Win32 Hooks DLL注入针对“任何CPU”构建的应用程序

时间:2012-01-27 09:41:06

标签: hook dll-injection setwindowshookex

我正在开发一个捕获所有用户交互的项目。 MSDN告诉(this

  

SetWindowsHookEx可用于将DLL注入另一个进程。一个   32位DLL无法注入64位进程和64位DLL   无法注入32位进程。如果申请需要   在其他进程中使用钩子,它需要一个32位   应用程序调用SetWindowsHookEx将32位DLL注入32位   进程和一个64位应用程序调用SetWindowsHookEx来注入一个   将64位DLL转换为64位进程。

我的问题是,如果应用程序是针对Any CPU构建的,会发生什么。我是否需要从针对SetWindowsHookEx构建的DLL中调用Any CPU

我已经写了HookLogger_32.exe加载HookFunctions_32.dll(包括x86)和HookLogger_64.exe加载HookFunctions_64.dll(都是x64)全局设置WH_CBTWH_MOUSE(不是特定的线程)。

HookLogger_32.exe,HookLogger_64.exe,HookFunctions_32.dll和HookFunctions_64.dll是用C ++编写的。

当我点击针对Any CPU构建的.NET应用程序时,会注入这些DLL(通过SetWindowHookEx)。 Windows操作系统挂起&我必须强行重启我的机器。

当针对x86或x64构建相同的.NET应用程序时,当我在HookLoggers(32位和64位)启动后单击应用程序时,一切正常。

此未定义行为的任​​何原因。

我正在使用的平台是一台64位计算机。

4 个答案:

答案 0 :(得分:3)

您需要从具有相应bitnse的DLL中注入 - 即“任何CPU”在运行时变为32位或64位...并且您的DLL必须与运行时位相匹配!

在您的情况下有用的东西被称为“并排组装”(同一组件的两个版本,一个32和另一个64位)......我认为您会发现这些有用:

在这里,您可以找到一个包含大量有用信息的精彩演练 - 它描述了.NET DLL wrapping C++/CLI DLL referencing a native DLL

<强>更新

要使挂钩变得非常简单和健壮,请参阅this well-tested and free library - 除其他外,它适用于AnyCPU!

答案 1 :(得分:0)

我猜您的主要问题是您正在尝试将.NET程序集注入本机进程,这肯定无法正常工作。我甚至不确定SetWindowsHookEx是否支持在CLR进程中注入.NET程序集。您的问题的解决方案是:

  1. 使用本机编译器(如C ++ / Delphi / VB等)为x86和x64平台重写/重新编译您的dll。
  2. 确保您的dll仅依赖于系统库。例如,它不应该依赖于任何不附带Windows的DLL,因为您可能会崩溃目标进程。您可以使用“Dependency Walker”工具来识别依赖关系。
  3. 如MSDN中所述,您应该为要支持的每个cpu使用可执行的注入器。在本例中为x86和x64。
  4. 或者您可以使用更好的注入/挂钩库,例如madCodeHook或Detours。通过这种方式,您将克服问题#3,而不是提及他们提供的数十个专业人员。

答案 2 :(得分:0)

根据您对问题的描述,我猜是...... 您的任何CPU编译程序正在加载x86存根,它会触发您的32位挂钩,然后x86存根检查并看到该环境具有64位支持并启动64位CLR版本。

在这种情况下,你的32位钩子dll正在获取WH_SHELL消息,并试图注入已经结束的进程(x86存根)或者它将32位钩子注入64位CLR进程。因此,你的“非常模糊,需要详细说明”系统崩溃。

如果你想详细说明你的代码实际上在做什么,那么将给出更多的帮助(以及更少的概括和'只是使用程序A')。您是否实际将代码注入到进程中,或者您是否使用进程的dwThreadId调用SetWindowsHookEx。

答案 3 :(得分:0)

在32位计算机上,任何CPU应用程序都会采用比特,这一点非常明显。

64位计算机获得两个独立的.NET Framework安装:每个位数一个。以Any CPU作为目标编译的.NET应用程序通常在64位安装上运行,但如果由另一个直接针对x86的应用程序引用,它也可以在32位安装上运行。因此,如果您知道应用程序的运行方式,您只能确定自己获得了什么:作为一个独立的流程,或通过参考。

我不会做任何假设。不要假设该过程在64位计算机上是64位的:它可能是32位的。正确检查它以查看它运行的模式。然后,相应地从32位或64位注入。

你必须使用与目标进程相同的位数的原因是,由于技术原因我不会得到,这样的钩子不能跨越所谓的SysWOW障碍。 SysWOW允许32位应用程序在64位计算机上运行,​​16位应用程序在32位计算机上运行,​​等等。当您在SysWOW的不同侧面运行的应用程序之间进行通信时,您正在“越过障碍” - 也就是说,一个在SysWOW(32位)内运行,另一个不在(64位)。简而言之,一个过程必须完全在SysWOW之内或之外。因此,您不能将32位代码添加到64位进程,反之亦然。