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做一个键盘记录器

android静态注册监听系统广播,如何只让本工程能够使用?

SetWindowsHookEx 问题的文档

SetWindowsHookEx 失败并出现错误 126

SetWindowsHookEx 注入失败

SetWindowsHookex Global 不是很全球化