有关SetWindowsHookEx()和挂钩的问题

时间:2012-01-26 21:25:34

标签: windows winapi hook dll-injection setwindowshookex

这是一些背景信息。我正在通过AppInit_DLLs注册表项替换已在dll注入技术中使用的dll。它的目的是出现在每个进程中并设置挂钩到GDI32.dll以收集有关打印的信息。这是一种时髦的方式来获得我们想要的东西。 .dll本身已经超过10年了(用Visual Studio 97编写),我们想用比注入的dll更少侵入性的东西替换它。

SetWindowsHookEx()似乎正在寻找的东西。我一直遇到一些麻烦,但我也和同事讨论过这棵树是否值得咆哮。以下是我们无法确定的一些问题:

  1. 当我们从一个dll中挂起一个例程,例如来自GDI32.dll的StartDoc()时,每次任何其他进程使用该dll中的那个时,我们是否真的收到通知? 这是我们使用注入的.dll获得的功能,我们需要相同的功能。

  2. 当钩子被触发时,钩子处理程序是在发起实际调用的进程的进程空间中运行,还是在设置钩子的进程的进程空间中运行?我的意见是它必须在调用例程的进程的进程空间中运行。例如,如果一个程序从GDI32.dll调用StartDoc(),它将把钩子处理程序代码“注入”到它的空间并执行。否则,必须在调用进程和设置挂钩的进程之间自动建立一些进程间通信,我只是不认为是这种情况。此外,这种钩子处理例程在调用进程的进程空间中运行是必要的,因为它需要知道的事情之一是该调用进程的名称,并且我不确定如何获取该信息它实际上并没有在那个过程中运行。

  3. 如果钩子处理例程是使用.NET托管环境编写的,那么当它被连接到不使用.NET托管环境的进程时它是否会中断?我们真的很喜欢在这里离开C ++并使用C#,但是如果我们的钩子从一个未被管理的进程调用会发生什么?如前所述,我认为我们的钩子处理过程将在最初调用被钩住的例程的过程中运行。但如果这是真的,那么如果这个过程没有使用.NET运行时环境,那么我认为我们会遇到麻烦,但是传入的钩子处理代码是。

1 个答案:

答案 0 :(得分:3)

  1. 一般情况下,它是前者:它在进程的上下文中执行,其事件正在挂钩。

    成功调用SetWindowsHookEx后,操作系统会自动将钩子DLL(包含回调函数的DLL)注入满足指定钩子类型要求的所有目标进程的地址空间。 (当然,挂钩代码不一定是立即注入。)

    此一般规则的例外是低级键盘和鼠标挂钩(WH_LL_KEYBOARDWH_LL_MOUSE)。由于这些钩子类型注入客户端进程,因此在最初调用SetWindowsHookEx的同一线程中调用回调。

  2. 最后一点非常重要,请记住回答第三个问题。因为低级键盘和鼠标挂钩是唯一不需要DLL注入的两个全局挂钩,所以它们也是可以用托管.NET代码编写的唯一两种类型的挂钩。

    对于其他钩子类型,您在问题中表达的关注是完全正确的。您需要在C或C ++中编写这些钩子DLL。当然,应用程序部分的 rest 仍然可以用托管语言编写。唯一重要的是钩子DLL。

  3. 您可以考虑查看Microsoft DetoursEasyHook

相关问题