SetWindowsHookEx() 只注册一个本地钩子,同时注入DLL
Posted
技术标签:
【中文标题】SetWindowsHookEx() 只注册一个本地钩子,同时注入DLL【英文标题】:SetWindowsHookEx() only registering a local hook, while DLL is injected 【发布时间】:2013-06-23 14:09:37 【问题描述】:我在非托管 C++ DLL 中有以下代码。 ToasterHook() 函数由 C# 应用程序使用 P/Invoke 调用,并且 WndProc 被覆盖以捕获任何 WM_COPYDATA 消息。 Process Explorer 说我的 DLL 已被注入到其他进程中,但是当我的表单加载时,我只收到 WM_COPYDATA 一次。
#pragma data_seg (".SHARED")
HHOOK g_HookHandle = 0;
HINSTANCE DllHandle;
HOOKPROC hkprcSysMsg;
#pragma data_seg()
extern "C" __declspec(dllexport) int ToasterHook()
if(g_HookHandle != 0) return 0;
DllHandle = LoadLibrary(L"toasterHookDll.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(DllHandle, "_ToasterInterProcFilter@12");
g_HookHandle = SetWindowsHookEx(WH_SHELL, hkprcSysMsg, DllHandle, 0);
return 0;
extern "C" __declspec(dllexport)
LRESULT CALLBACK ToasterInterProcFilter(int code, WPARAM wParam, LPARAM lParam)
if(code == HSHELL_WINDOWCREATED)
HWND g_ToasterReceiver = FindWindow(NULL, L"toaster");
SendNotifyMessage(g_ToasterReceiver, WM_COPYDATA, wParam, lParam);
return CallNextHookEx(g_HookHandle, code, wParam, lParam);
extern "C" __declspec(dllexport) void ToasterUnHook()
if(g_HookHandle == 0) return;
UnhookWindowsHookEx(g_HookHandle);
我在这里做错了什么?为 HOOKPROC 指定 GetProcAddress(DllHandle, "_ToasterInterProcFilter@12")
或 ToasterInterProcFilter
本身的结果似乎有效。
【问题讨论】:
你做错了什么被省略了all错误检查。所以没有办法找出它为什么不起作用。您可能不会在 SetWindowsHookEx() 调用中检查错误,因为点太多而无法进行调用,但值得注意的是它似乎没有使用 DLL 句柄。添加 UAC 并需要同时拥有 32 位和 64 位版本的代码以使其更难以诊断。 其实我去掉了错误检查代码,方便阅读。在 LoadLibrary、GetProcAddress 和 SetWindowsHookEx 之后,我检查句柄并返回 GetLastError() 如果它是 NULL,它不是。另外,我的意思是指定 GetProcAddress 的结果或回调函数本身似乎都不起作用。我希望这能澄清事情。该代码被编译为 32 位 DLL,并且似乎被注入到 32 位进程中。唯一的问题是回调只在当前线程上触发,这表明 HOOKPROC 有问题,但似乎不是。 抱歉,我想知道,为什么我的问题被否决了? 【参考方案1】:发送WM_COPYDATA
消息时,lParam
值必须指向COPYDATASTRUCT
结构。该数据结构包含诸如指向要复制的数据的指针和数据的大小等信息。 Windows 会自动处理此数据的封送处理,以便接收消息的应用程序可以访问它。
您的代码当前正在传递lParam
,伴随着HSHELL_WINDOWCREATED
。 Windows 可能会将其指向的数据解释为 COPYDATASTRUCT
结构,但在大多数情况下它会失败。
【讨论】:
谢谢!!我使用 RegisterWindowMessage 而不是 WM_COPYDATA 来注册一条唯一的消息并且它有效!以上是关于SetWindowsHookEx() 只注册一个本地钩子,同时注入DLL的主要内容,如果未能解决你的问题,请参考以下文章
手把手教你用SetWindowsHookEx做一个键盘记录器