在入口函数Hook的分析
2009-02-10 11:20
162 查看
// DemoKing2.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <windows.h> // 保存原始的5个字节代码,注意一定要保证完整 BYTE orig_code[5] = {0x90, 0x90, 0x90, 0x90, 0x90}; BYTE save_code[10] = {0x90, 0x90, 0x90, 0x90, 0x90}; // JMP 0xXXXXXXXX BYTE hook_code[5] = { 0xe9, 0, 0, 0, 0 }; BYTE jmp_orig_code[5] = { 0xe9, 0, 0, 0, 0}; int func(int a,char *str); int fake_func(int a,char *str); void hook_func(); int jmp_back(int a,char *str); int main(int argc, char **argv) { int ret; hook_func(); ret = func(110,"pklang"); return ret; } int func(int a,char *str) { printf("I'm func(),I'm called! a:%d,str:%s/r/n",a,str); return 0; } void hook_func() { DWORD dwOldProtect; #ifdef _DEBUG //Debug 模式时是用jmp跳转表,所以要算出真正的函数地址 #define PATCH 6 DWORD fake_funcAddr= (DWORD)fake_func+*(PDWORD)((DWORD)fake_func+1)+5; DWORD funcAddr= (DWORD)func+*(PDWORD)((DWORD)func+1)+5; DWORD jmp_backAddr= (DWORD)jmp_back+*(PDWORD)((DWORD)jmp_back+1)+5; #else #define PATCH 8 DWORD fake_funcAddr= (DWORD)fake_func; DWORD funcAddr= (DWORD)func; DWORD jmp_backAddr= (DWORD)jmp_back; #endif *((PDWORD)(hook_code+1) ) = (DWORD)fake_funcAddr - (DWORD)funcAddr - 5; //save old code //要看看入口地址前五个字节是否完整为汇编指令的,如果不是要补成完整指令 //比如fun函数在debug模式开头为 // 004010A0 >/> /55 push ebp //1个字节 // 004010A1 |. 8BEC mov ebp, esp //2个字节 // 004010A3 |. 83EC 40 sub esp, 40 //3个字节 // 004010A6 |. 53 push ebx //所以加起来至少要6个字节 // 004010A7 |. 56 push esi //而Release模式fun开头汇编为 // 00401020 /$ 8B4424 08 mov eax, dword ptr [esp+8] //4个字节 // 00401024 |. 8B4C24 04 mov ecx, dword ptr [esp+4] //4个字节 // 00401028 |. 50 push eax //所以加起来至少要8个字节 // 00401029 |. 51 push ecx memcpy(save_code,(LPVOID)funcAddr,PATCH); // 修改原始入口 VirtualProtect((LPVOID)funcAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect); memcpy((BYTE *)funcAddr, hook_code, 5); VirtualProtect((LPVOID)funcAddr, 5, dwOldProtect, &dwOldProtect); //设置原函数地址 *( (PDWORD)(jmp_orig_code+1) ) = (ULONG)funcAddr - (ULONG)jmp_backAddr -5; VirtualProtect((LPVOID)jmp_backAddr, 15, PAGE_EXECUTE_READWRITE, &dwOldProtect); memcpy((BYTE *)jmp_backAddr, save_code, PATCH); memcpy((BYTE *)((DWORD)jmp_backAddr+PATCH), jmp_orig_code, 5); VirtualProtect((LPVOID)jmp_backAddr, 15, dwOldProtect, &dwOldProtect); } //4011ba __declspec(naked) int jmp_back(int a,char *str) { __asm { _emit 0x90 _emit 0x90 _emit 0x90 _emit 0x90 _emit 0x90 _emit 0x90 _emit 0x90 _emit 0x90 _emit 0x90 _emit 0x90 } } int fake_func(int a,char *str) { int ret; printf("I'm fake_func(),I'm called! a:%d,str:%s/r/n",a,str); ret = jmp_back(a,str); return ret; }
相关文章推荐
- ReactJS分析之入口函数render
- netfilter源码分析(1)- IP报文的接收到hook函数的调用
- EventBus源码分析(一):入口函数提纲挈领(2.4版本)
- 4.1 ipu_common.c分析---入口函数及probe函数分析
- 原创:Twemproxy源码分析之一 入口函数及启动过程
- Linux netfilter 学习笔记 之六 ip层netfilter的filter表的创建及其hook函数分析
- ReactJS分析之入口函数render
- Linux netfilter 学习笔记 之二 ip 层netfilter的hook 注册以及执行hook函数的概要分析
- 小e开发板用户代码入口user_init函数分析
- Twemproxy源码分析之一 入口函数及启动过程
- Linux netfilter 学习笔记 之二 ip 层netfilter的hook 注册以及执行hook函数的概要分析
- ReactJS分析之入口函数render
- c c++ 函数入口和出口的hook(gcc 编译选项),然后打印出函数调用关系的方法
- android init入口函数分析
- Linux内核分析 - 网络:netif_receive_skb平台报文入口函数详解
- linux启动分析---C程序入口函数start_kernel
- Linux netfilter 学习笔记 之六 ip层netfilter的filter表的创建及其hook函数分析
- [LWIP学习]--tcpip_input,tcpip_inpkt,tcpip_thread函数分析(协议栈入口)
- hook函数实例分析--sys_seteuid调用
- discuz 插件核心函数hookscript分析.