0x01主要是针对内部函数的hook
这里有需要注意的地方
内部含糊的地址
HOOK的位置
保存现场: pushfd pushad
原本硬编码的恢复
extern "C" _declspec(naked)void HookProc() { //保存现场 _asm { pushad pushfd } //获取寄存器 _asm { mov reg.Eax,eax mov reg.Ecx,ecx mov reg.Ebx,ebx mov reg.Edx,edx mov reg.Esp,esp mov reg.Ebp,ebp mov reg.Esi,esi mov reg.Edi,edi mov EAX,DWORD PTR SS:[esp+0x28] mov dwParaX,EAX mov EAX,DWORD PTR SS:[esp+0x2C] mov dwParaY,EAX } //当前寄存器的内容 OutputDebugStringF("Eax:%d,Ebx:%d,Ecx,%d,Edx:%d",reg.Eax,reg.Ebx,reg.Ecx,reg.Edx); OutputDebugStringF("esp:%d,ebp:%d,esi,%d,edi:%d",reg.Esp,reg.Ebp,reg.Esi,reg.Edi); //参数内容 OutputDebugStringF("X:%d.Y:%d",dwParaX,dwParaY); //恢复现场 _asm { popfd popad } //执行覆盖代码 _asm { push ebp mov ebp,esp sub esp,40h } //跳回去 _asm { jmp g_dwRetAddr } }
裸函数的运用
0x02 跳转地址的注意事项
//备份硬编码 g_pCodePatch = new BYTE[bytes]; memcpy(g_pCodePatch,(void*)dwHookAddr,bytes); //填充90 dwJumpCode = dwProcAddr - dwHookAddr - 5; memset((void*)dwHookAddr,0x90,bytes); // jmp 0x0000 *(PBYTE)dwHookAddr = 0xE9; *(PDWORD)((PBYTE)dwHookAddr + 1) = dwJumpCode;
0x03 上面贴的是核心代码
详细代码如下
// 20180203_01.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "DebugTool.h" DWORD g_dwHookAddr; //Hook开始的地方 DWORD g_dwRetAddr; //Hook结束的地方 DWORD g_dwLength; //Hook字节数 PBYTE g_pCodePatch; //存储Hook原来的硬编码 DWORD g_dwHookFlag; //HOOK状态, 1 Hook成功, 0 HOOK 失败 typedef struct _REGISTER { DWORD Eax; DWORD Ecx; DWORD Edx; DWORD Ebx; DWORD Esp; DWORD Ebp; DWORD Esi; DWORD Edi; }Register; DWORD dwParaX; DWORD dwParaY; Register reg= {0}; TCHAR szBuffer[100] = {0}; extern "C" _declspec(naked)void HookProc() { //保存现场 _asm { pushad pushfd } //获取寄存器 _asm { mov reg.Eax,eax mov reg.Ecx,ecx mov reg.Ebx,ebx mov reg.Edx,edx mov reg.Esp,esp mov reg.Ebp,ebp mov reg.Esi,esi mov reg.Edi,edi mov EAX,DWORD PTR SS:[esp+0x28] mov dwParaX,EAX mov EAX,DWORD PTR SS:[esp+0x2C] mov dwParaY,EAX } //当前寄存器的内容 OutputDebugStringF("Eax:%d,Ebx:%d,Ecx,%d,Edx:%d",reg.Eax,reg.Ebx,reg.Ecx,reg.Edx); OutputDebugStringF("esp:%d,ebp:%d,esi,%d,edi:%d",reg.Esp,reg.Ebp,reg.Esi,reg.Edi); //参数内容 OutputDebugStringF("X:%d.Y:%d",dwParaX,dwParaY); //恢复现场 _asm { popfd popad } //执行覆盖代码 _asm { push ebp mov ebp,esp sub esp,40h } //跳回去 _asm { jmp g_dwRetAddr } } DWORD Plus(DWORD x,DWORD y) { return x+y; } BOOL SetInlineHook(DWORD dwHookAddr,DWORD dwProcAddr,int bytes) { BOOL bRet = FALSE; DWORD dwOldProtect = 0; DWORD dwJumpCode = 0; if(dwHookAddr == NULL || dwProcAddr==NULL) { OutputDebugStringF("Function Address Error!"); return bRet; } if(bytes<5) { OutputDebugStringF("字节长度不够,操作失败!"); return bRet; } bRet = VirtualProtectEx(::GetCurrentProcess(),(LPVOID)dwHookAddr,(DWORD)bytes,PAGE_EXECUTE_READWRITE,&dwOldProtect); if(!bRet) { OutputDebugStringF("内存空间申请权限失败"); return bRet; } //备份硬编码 g_pCodePatch = new BYTE[bytes]; memcpy(g_pCodePatch,(void*)dwHookAddr,bytes); //填充90 dwJumpCode = dwProcAddr - dwHookAddr - 5; memset((void*)dwHookAddr,0x90,bytes); // jmp 0x0000 *(PBYTE)dwHookAddr = 0xE9; *(PDWORD)((PBYTE)dwHookAddr + 1) = dwJumpCode; //修改HOOK状态 g_dwHookFlag = 1; g_dwHookAddr = dwHookAddr; g_dwLength = (DWORD)bytes; g_dwRetAddr = dwHookAddr + g_dwLength; return TRUE; } BOOL UnInlineHook() { BOOL bRet = FALSE; DWORD dwOldProtect; if(!g_dwHookFlag) { OutputDebugStringF("no hook inline"); return bRet; } bRet = VirtualProtectEx(::GetCurrentProcess(),(LPVOID)g_dwHookAddr,(DWORD)g_dwLength,PAGE_EXECUTE_READWRITE,&dwOldProtect); if(!bRet) { OutputDebugStringF("内存空间申请权限失败"); return bRet; } //恢复硬编码 memcpy((PDWORD)g_dwHookAddr,g_pCodePatch,g_dwLength); //修改HOOK状态 delete[] g_pCodePatch; g_dwHookFlag = 0; g_dwHookAddr = 0; g_dwLength = 0; g_dwRetAddr = 0; g_pCodePatch= NULL; return TRUE; } VOID TestInlineHook(DWORD dwHookAddr,DWORD dwProcAddr,int bytes) { SetInlineHook(dwHookAddr,dwProcAddr,bytes); Plus(11,55); //卸载HOOK UnInlineHook(); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { DWORD TestFuncAddr = 0x004012A0; Plus(1,2); OutputDebugStringF("HookProc: %08X",HookProc); OutputDebugStringF("TestFuncAddr: %08X",TestFuncAddr); //安装HOOK TestInlineHook(TestFuncAddr,(DWORD)HookProc,6); return 0; }
0x04 工程下载
直接分享代码吧,
记住不同机器上 Plus的地址不一样, 自己先测试吧!!
0则评论给“测试InlineHook”