【问题标题】:SetWindowsHookEx() doesn't return an error when hooking 64 bit processes from a 32 bit process?从 32 位进程挂钩 64 位进程时,SetWindowsHookEx() 不返回错误?
【发布时间】:2014-03-30 16:50:18
【问题描述】:

我的应用程序编译为 32 位,由于我在 64 位 Windows 7 上运行,我的目标 (notepad.exe) 是 64 位。当我在 notepad.exe 找到的第一个线程上调用 SetWindowsHookEx() 时,DLL 根本没有被注入,但没有返回错误。我知道它没有被注入,因为在DLL_PROCESS_ATTACH 上我显示带有消息Attached 的消息框,而对于DLL_PROCESS_DETACH 我在消息框中显示Detached 消息。这些消息仅在我调用 LoadLibrary() 时显示一次,在我的应用程序退出时显示另一次。

根据 MSDN 文档here

因为钩子在应用程序的上下文中运行,它们必须匹配 应用程序的“位数”。如果 32 位应用程序安装了 64 位 Windows 上的全局钩子,32 位钩子被注入到每个 32 位进程(通常的安全边界适用)。在 64 位 进程中,线程仍被标记为“已挂钩”。然而,因为一个 32位应用程序必须运行钩子代码,系统执行 在钩子应用程序的上下文中钩子;具体来说,在线程上 称为 SetWindowsHookEx。这意味着挂钩应用程序必须 继续泵送​​消息,否则可能会阻止正常运行 64 位进程。

这是否意味着它成功地挂钩了我自己的进程,而不是实际返回错误?

编辑:我的钩子是 WH_CBT 类型的。

【问题讨论】:

  • 这个问题主要取决于钩子的类型
  • 它没有义务返回错误,它肯定注入了一些进程。只是不是你想要的那个。这就是 64 位操作系统上的陷阱,您需要使用 64 位 DLL 启动程序的 64 位版本才能注入 64 位进程。

标签: c++ winapi dll hook


【解决方案1】:

您需要进一步阅读文档:

对于指定的钩子类型,线程钩子首先被调用,然后是全局的 钩子。请注意,WH_MOUSE、WH_KEYBOARD、WH_JOURNAL*、WH_SHELL、 并且可以在安装了 钩子而不是处理钩子的线程。对于这些钩子,它 可能会调用 32 位和 64 位挂钩,如果 在钩子链中,32 位钩子在 64 位钩子之前。

简而言之,如果你的 dll 被注入到目标进程中,这取决于钩子类型。如果您只想监视键盘和鼠标事件,则无需将自己注入其他进程。 Windows 将在您自己的进程中回调您的钩子。

我怀疑你的钩子类型是以下之一:

  • WH_MOUSE_LL
  • WH_KEYBOARD_LL

不会导致任何库注入目标进程。

【讨论】:

  • 只有 _LL 钩子不使用注入。
【解决方案2】:

该部分文档没有明确说明的是,当SetWindowsHookEx 无法将您的 32 位 DLL 注入 64 位进程时,它不会返回错误,而是使用线程的消息循环调用SetWindowsHookEx 来执行钩子程序,就像它与低级鼠标/键盘钩子(WH_MOUSE_LL/WH_KEYBOARD_LL)的工作方式一样。

【讨论】:

  • 这太奇怪了。我看到SetWindowsHookEx 成功(有点),同时尝试从 32 位线程挂钩 64 位线程:返回值不是 NULL,并且似乎是有效的HHOOK,因为UnhookWindowsHookEx 运行得很好。但是(对于WH_GETMESSAGE)我的钩子程序永远不会被调用。
猜你喜欢
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 2013-03-11
  • 1970-01-01
  • 2011-09-20
  • 2010-09-12
相关资源
最近更新 更多