用于 64 位操作系统的系统范围挂钩
Posted
技术标签:
【中文标题】用于 64 位操作系统的系统范围挂钩【英文标题】:system-wide hook for 64-bit operating systems 【发布时间】:2011-02-28 07:15:18 【问题描述】:我想在 64 位操作系统上执行系统范围的挂钩(使用 SetWindowHook)。
我知道 64 位进程 (= proc64) 只能加载 64 位 dll (= dll64),而 32 位进程 (= proc32) 只能加载 32 位 dll (= dll32)。
目前我计划调用 SetWindowHook 两次,一次使用 dll32,一次使用 dll64,预计 proc64s 将加载 dll64,proc32s 将加载 dll32(而 proc64s 的 dll32 和 proc32s 的 dll64 将失败)。
这是正确的做法,还是有“更正确”的做法?
谢谢! :-)
【问题讨论】:
【参考方案1】:您所描述的方法是正确的并记录在案。
来自http://msdn.microsoft.com/en-us/library/ms644990(v=vs.85).aspx:
SetWindowsHookEx
可以用来注入 一个DLL到另一个进程。一个 32 位 DLL 不能注入到 64 位 进程,并且不能使用 64 位 DLL 注入32位进程。如果 应用程序需要使用钩子 在其他过程中,需要 一个 32 位应用程序调用 SetWindowsHookEx 注入 32 位 DLL 转换为 32 位进程,以及 64 位应用程序调用 SetWindowsHookEx 注入 64 位 DLL 转换为 64 位进程。 32 位 和 64 位 DLL 必须有不同的 名字。
请注意最后一条语句,即 32 位和 64 位 DLL 的名称必须不同。
【讨论】:
【参考方案2】:您可能需要查看EasyHook 来省去一大堆麻烦。
【讨论】:
我不想使用 easyhook 来完成这项任务,因为 SetWindowHook 足以完成这项工作......【参考方案3】:您应该在代码中测试机器以查看字长是 32 位还是 64 位。 64 位机器将通过扩展字长来处理 32 位指令集,但是传递 64 位指令集的 32 位机器......可能会导致非常糟糕的事情。
在C标准库的limits.h头文件中——INT_MAX会给你最大尺寸,测试看看
bool is32 = true;
if ( INT_MAX == 2^63 − 1 )
is32 = false;
一旦你有了你的标志,你就会知道要包含哪个文件,并且你可以使用你的标志来包含它。
【讨论】:
如果 INT_MAX 是无符号的,你需要测试它是否等于 2^64 - 1,不记得是否。 既然有单独的 32 位和 64 位版本的 DLL,为什么还要这样做? 这样您的程序就不会尝试在 32 位机器上使用 64 位 dll。在大多数情况下,32 位机器会将 64 位指令切成两半并处理它们,这相当于在 c 中创建指针,而不是将其清空或初始化并在其上运行进程......你不知道会发生什么发生。 首先,这个问题明确说明了存在 64 位操作系统的事实。其次,有更多相关的方法可以在编译时查看平台是否为 AMD64。第三个也是最后一个 - 32 位 DLL 不会从 64 位进程加载,就像 64 位 DLL 不会从 32 位进程加载一样。所以没有机会得到你描述的组合。以上是关于用于 64 位操作系统的系统范围挂钩的主要内容,如果未能解决你的问题,请参考以下文章