【发布时间】:2012-03-09 05:24:24
【问题描述】:
我对挂钩很感兴趣,我决定看看我是否可以挂钩一些功能。我对使用 detours 之类的库不感兴趣,因为我想拥有自己做这件事的经验。通过我在互联网上找到的一些资源,我能够创建下面的代码。这是基本的,但它工作正常。但是,当挂钩由多个线程调用的函数时,它被证明是极其不稳定的。如果几乎同时拨打两个电话,它就会崩溃。经过一些研究,我认为我需要创建一个蹦床功能。在寻找了几个小时之后,除了对蹦床的一般描述之外,我找不到任何其他东西。我找不到任何关于编写蹦床函数的具体内容,或者它们是如何工作的。如果有人可以帮助我写一篇文章,发布一些资源,或者至少通过推荐一些文章、网站、书籍等为我指明正确的方向。我将不胜感激。
下面是我写的代码。这真的很基础,但我希望其他人可以从中学习。
test.cpp
#include "stdafx.h"
Hook hook;
typedef int (WINAPI *tMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
DWORD hMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
hook.removeHook();
tMessageBox oMessageBox = (tMessageBox)hook.funcPtr;
int ret =oMessageBox(hWnd, lpText, "Hooked!", uType);
hook.applyHook(&hMessageBox);
return ret;
}
void hookMessageBox()
{
printf("Hooking MessageBox...\n");
if(hook.findFunc("User32.dll", "MessageBoxA"))
{
if(hook.applyHook(&hMessageBox))
{
printf("hook applied! \n\n");
} else printf("hook could not be applied\n");
}
}
hook.cpp
#include "stdafx.h"
bool Hook::findFunc(char* libName, char* funcName)
{
Hook::funcPtr = (void*)GetProcAddress(GetModuleHandleA(libName), funcName);
return (Hook::funcPtr != NULL);
}
bool Hook::removeHook()
{
DWORD dwProtect;
if(VirtualProtect(Hook::funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect))
{
WriteProcessMemory(GetCurrentProcess(), (LPVOID)Hook::funcPtr, Hook::origData, 6, 0);
VirtualProtect(Hook::funcPtr, 6, dwProtect, NULL);
return true;
} else return false;
}
bool Hook::reapplyHook()
{
DWORD dwProtect;
if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect))
{
WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::hookData, 6, 0);
VirtualProtect(funcPtr, 6, dwProtect, NULL);
return true;
} else return false;
}
bool Hook::applyHook(void* hook)
{
return setHookAtAddress(Hook::funcPtr, hook);
}
bool Hook::setHookAtAddress(void* funcPtr, void* hook)
{
Hook::funcPtr = funcPtr;
BYTE jmp[6] = { 0xE9, //jmp
0x00, 0x00, 0x00, 0x00, //address
0xC3 //retn
};
DWORD dwProtect;
if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect)) // make memory writable
{
ReadProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::origData, 6, 0); // save old data
DWORD offset = ((DWORD)hook - (DWORD)funcPtr - 5); //((to)-(from)-5)
memcpy(&jmp[1], &offset, 4); // write address into jmp
memcpy(Hook::hookData, jmp, 6); // save hook data
WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, jmp, 6, 0); // write jmp
VirtualProtect(funcPtr, 6, dwProtect, NULL); // reprotect
return true;
} else return false;
}
【问题讨论】:
-
我打算发布一个指向 GD 的链接,但我刚刚注意到你也是那里的成员。您是否尝试过使用他们的搜索功能?它提出了大量的例子:)
-
你可以查看 EasyHook 的代码,我相信它是开源的。周围还有很多其他的例子。如果您打算在已部署的应用程序中使用它,我建议您使用已经可以处理钩子/蹦床、线程和一些有趣的东西上的递归的库(如 EasyHook)。
-
@Tom Knapen 在发布之前,我搜索了 GD、MPGH 和其他一些网站。在 GD 上搜索“蹦床”会返回一些稍微相关的帖子,但不是我要找的。span>
-
你的代码对初学者很有用,谢谢
标签: c++ winapi hook tramp trampolines