全局 WH_CBT 挂钩 DLL 仅加载到某些进程中

Posted

技术标签:

【中文标题】全局 WH_CBT 挂钩 DLL 仅加载到某些进程中【英文标题】:Global WH_CBT hook DLL is loaded into some processes only 【发布时间】:2010-03-21 16:36:58 【问题描述】:

主程序调用wi.dll中的SetHook函数安装全局WH_CBT hook。

bool WI_API SetHook()

    if (!g_hHook)
    
        g_hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC) CBTProc, g_hInstDll, 0);
    

    return g_hHook != NULL;

我假设安装全局钩子后,wi.dll 应该被加载到每个进程的地址空间中。但是 wi.dll 仅加载到某些进程中。例如,如果我启动 Skype、MS Word,我可以看到 wi.dll 也被加载到这些进程中(使用 Process Explorer),但是如果我运行 Firefox、uTorrent、Adobe Reader,那么 wi.dll 不会加载到这些进程中.

我用的是W7 64位,主程序和wi.dll都是32位的,这里提到的所有程序都是32位的程序。

你知道为什么会这样吗?

提前致谢。

【问题讨论】:

【参考方案1】:

来自 MSDN:

SetWindowsHookEx 可用于将 DLL 注入另一个进程。 32位DLL不能注入64位进程,64位DLL不能注入32位进程。如果应用程序需要在其他进程中使用钩子,则需要 32 位应用程序调用 SetWindowsHookEx 将 32 位 DLL 注入 32 位进程,64 位应用程序调用 SetWindowsHookEx 将 64 位DLL 转换为 64 位进程。 32 位和 64 位 DLL 必须具有不同的名称。

因此,您应该创建 32 位应用程序以从 32 位 dll 调用 SetWindowsHookEx,然后将消息重定向到您的主应用程序,并让您的 x64 主应用程序从 64 位 dll 调用 SetWindowsHookEx 以接收来自x64 进程也是如此。

【讨论】:

【参考方案2】:

钩链机制不是万无一失的,它依赖于参与其中的每个人都遵守规则。如果一个应用程序安装了它自己的每线程WH_CBT 钩子并且没有在它的钩子过程中调用CallNextHookEx,那么早期的钩子将不会被调用。请参阅 CallNextHookEx 的 MSDN 文档。

【讨论】:

以上是关于全局 WH_CBT 挂钩 DLL 仅加载到某些进程中的主要内容,如果未能解决你的问题,请参考以下文章

Dllmain的作用

用于 64 位操作系统的系统范围挂钩

C++ 函数挂钩

跨进程加载的 DLL - 如何使某些操作“类似于单例”

如何查找加载到进程中的DLL及其位置等

Hook exe