支持,学习了。。。→_→
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);
}
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);
引用 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
200字以内,仅用于支线交流,主线讨论请采用回复功能。