支持,学习了。。。→_→
<code class="lang-cpp">typedef struct APIHOOK *LPAPIHOOK; LPAPIHOOK APIHook_CreateHook(HANDLE hProc, FARPROC oldFunc, void* newFunc); void APIHook_DestoryHook(LPAPIHOOK hook); void APIHook_TurnOnHook(LPAPIHOOK hook); void APIHook_TurnOffHook(LPAPIHOOK hook); typedef struct APIHOOK { #ifdef _AMD64_ BYTE OldCode[12]; BYTE NewCode[12]; #else BYTE OldCode[5]; BYTE NewCode[5]; #endif FARPROC oldProc; HANDLE hP; bool status; }APIHOOK; void APIHook_TurnOnHook(LPAPIHOOK hook) { if (hook == NULL) return; DWORD dwTemp = 0; DWORD dwOldProtect; #ifdef _AMD64_ VirtualProtectEx(hook->hP, hook->oldProc, 12, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hook->hP, hook->oldProc, hook->NewCode, 12, 0); VirtualProtectEx(hook->hP, hook->oldProc, 12, dwOldProtect, &dwTemp); #else VirtualProtectEx(hook->hP, hook->oldProc, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hook->hP, hook->oldProc, hook->NewCode, 5, 0); VirtualProtectEx(hook->hP, hook->oldProc, 5, dwOldProtect, &dwTemp); #endif hook->status = true; } void APIHook_TurnOffHook(LPAPIHOOK hook) { if (hook == NULL) return; DWORD dwTemp = 0; DWORD dwOldProtect; #ifdef _AMD64_ VirtualProtectEx(hook->hP, hook->oldProc, 12, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hook->hP, hook->oldProc, hook->OldCode, 12, 0); VirtualProtectEx(hook->hP, hook->oldProc, 12, dwOldProtect, &dwTemp); #else VirtualProtectEx(hook->hP, hook->oldProc, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hook->hP, hook->oldProc, hook->OldCode, 5, 0); VirtualProtectEx(hook->hP, hook->oldProc, 5, dwOldProtect, &dwTemp); #endif hook->status = false; } LPAPIHOOK APIHook_CreateHook(HANDLE hProc, FARPROC oldFunc, void* newFunc) { LPAPIHOOK ret = (LPAPIHOOK)malloc(sizeof(APIHOOK)); ret->hP = hProc; ret->oldProc = oldFunc; if (ret->oldProc == NULL) { return NULL; } #ifdef _AMD64_ memcpy_s(ret->OldCode, 12, (BYTE*)(ret->oldProc), 12); ret->NewCode[0] = 0x48; ret->NewCode[1] = 0xB8; ULONG64 addr = (ULONG64)newFunc; memcpy_s(ret->NewCode + 2, 8, &addr, 8); ret->NewCode[10] = 0x50; ret->NewCode[11] = 0xC3; #else memcpy_s(ret->OldCode, 5, (BYTE*)(ret->oldProc), 5); ret->NewCode[0] = 0xe9; //jmp ULONG32 aNew = (ULONG32)newFunc - (ULONG32)(void*)(ret->oldProc) - 5; memcpy_s(ret->NewCode + 1, 4, &aNew, 4); #endif ret->status = false; return ret; } void APIHook_DestoryHook(LPAPIHOOK hook) { if (hook == NULL) return; if (hook->status) APIHook_TurnOffHook(hook); free(hook); }</code>
<code class="lang-cpp">BOOL WINAPI MyTrackPopupMenuEx(HMENU hMenu, UINT uFlags, int x, int y, HWND hwnd, LPTPMPARAMS lptpm) { APIHook_TurnOffHook(apiHook_TPM); //Do something here BOOL ret = TrackPopupMenuEx(hMenu, uFlags, x, y, hwnd, lptpm); //Do something here APIHook_TurnOnHook(apiHook_TPM); return ret; } LPAPIHOOK apiHook_TPM; //Create a api hook HMODULE hmod = LoadLibrary(TEXT("User32.dll")); apiHook_TPM = APIHook_CreateHook(OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()), GetProcAddress(hmod, "TrackPopupMenuEx"), MyTrackPopupMenuEx); APIHook_TurnOnHook(apiHook_TPM); //Dont forget APIHook_DestoryHook(apiHook_TPM);</code>
引用 phpskycn:IAT hook比较难哎 似乎还对汇编要求高 咱x86汇编基本就是狒狒
其实R3下API Hook有很多种实现方法,inline hook只是一种,比较方便粗暴,但是需要进行代码注入不是特别安全(如果hook的时候某个线程正好执行到这里就可能发生无法意料的情况),而写入jmp指令是无法实现原子操作的。
iat ...
引用 金星凌日:发现一个奇怪情况 大部分函数比如MessageBoxW GetMenuItemInfo等能被正确Hook但是CreateWindowExW这玩意就不能正确hook 在自己的CreateWindowExW中调用原来的函数始终得不到正确的结果 GetLastError返回0x57 似乎是参数不正确的意思orz
我记得x86(32位)下大多数WindowsAPI开头都是相当于空指令的mov edi,edi,因而如果只改写这两个字节,自己调用时就不必恢复,只需将函数指针增加两个字节调用。
引用 金坷居士:IAT对汇编的要求比inline hook低,主要得了解PE+结构。
IAT hook比较难哎 似乎还对汇编要求高 咱x86汇编基本就是狒狒
引用 金坷居士:在什么版本的系统下出现了这样的问题?我在版本较低的32位Windows下测试,可以Hook。
发现一个奇怪情况 大部分函数比如MessageBoxW GetMenuItemInfo等能被正确Hook但是CreateWindowExW这玩意就不能正确hook 在自己的CreateWindowExW中调用原来的函数始终得不到正确的结果 ...
引用 phpskycn:是参数填错了orz 小错误
IAT对汇编的要求比inline hook低,主要得了解PE+结构。
Hook失败的时候需要检查堆栈,看看参数之类的是否正确,调试器里面单步跟一下,并对比正常情况
引用 金星凌日:搞定了2333
在什么版本的系统下出现了这样的问题?我在版本较低的32位Windows下测试,可以Hook。
引用 金星凌日 : 我记得x86(32位)下大多数WindowsAPI开头都是相当于空指令的mov edi,edi,因而如果只改写这两个字节,自己调用时就不必恢复,只需将函数指针增加两个字节调用。
两个字节怎么hook。。。
引用 acmilan : > 引用 金星凌日 : 我记得x86(32位)下大多数WindowsAPI开头都是相当于空指令的mov edi,edi,因而如果只改写这两个字节,自己调用时就不必恢复,只需将函数指针增加两个字节调用。……
jmp short
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。