// 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; }