【问题标题】:Will global hooks work across x86 and x64全局挂钩是否可以跨 x86 和 x64 工作
【发布时间】:2014-05-18 02:08:53
【问题描述】:

我试图将所有内容嵌入到单个 COM dll 中。目前,我将 WH_GETMESSAGE 和 WH_CBT 挂钩如下:

BOOL TouchDetector::SetMessageHook(BOOL Install)
{
if (Install)
{
    return ((mHookMessage = ::SetWindowsHookEx(WH_GETMESSAGE, MessageHookProc, mDll, 0)) != NULL)
         && ((mHookWin = ::SetWindowsHookEx(WH_CBT, WinHookProc, mDll, 0)) != NULL);
}
else
{
    return UnhookWindowsHookEx(mHookMessage)
        && UnhookWindowsHookEx(mHookWin);
}
};

我也把共享变量是这样的:

#pragma data_seg(".shared")
TouchDetector*   pTouch = nullptr;
HHOOK            mHookMessage = NULL;
HHOOK            mHookWin = NULL;
#pragma data_seg()
#pragma comment(linker,"/section:.shared,rws")

通过附加到 explorer.exe,我可以看到挂钩正在工作,但不是全局的。 我也尝试了 SetWinEventHook,但结果相同:只对我创建的窗口或 explorer.exe 做出反应。

它自己的 COM dll 是 x64,因为资源管理器是 x64。会不会是这个问题?

我试图存档的是在前台窗口更改时更新我的​​应用程序的配置。我知道我可以简单地启动另一个线程来关注它。但我不喜欢这样,目前程序只能被动地响应用户输入或赢得回调。

【问题讨论】:

    标签: c++ winapi hook


    【解决方案1】:

    来自SetWindowsHookEx documentation

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

    要在 64 位 Windows 安装的桌面上挂钩所有应用程序,请安装一个 32 位全局挂钩和一个 64 位全局挂钩,每个挂钩都来自相应的进程,并确保在挂钩应用程序中不断发送消息到避免阻碍正常运作。

    全局挂钩是一种共享资源,安装一个挂钩会影响与调用线程位于同一桌面的所有应用程序。

    因此,您需要创建两个版本的 DLL,一个用于 32 位挂钩,另一个用于 64 位挂钩。如果您以后决定添加 WH_MOUSEWH_KEYBOARDWH_JOURNAL*WH_SHELL 全局挂钩,请小心:

    请注意,可以在安装挂钩的线程上调用 WH_MOUSE、WH_KEYBOARD、WH_JOURNAL*、WH_SHELL 和低级挂钩,而不是在处理挂钩的线程上调用。对于这些钩子,如果 32 位钩子在钩子链中位于 64 位钩子之前,则可能会同时调用 32 位和 64 位钩子。

    但是对于您的 WH_GETMESSAGEWH_CBT 挂钩,您应该可以使用同一个 DLL 的两个版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 2010-09-12
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多