1

我正在实现一个小监控应用程序,所以我在进程中连接 CreateWindowExA/W,所以我可以控制窗口的创建。我用来挂钩的方法是用汇编程序 JMP 指令将调用中的前 5 个字节替换为我的挂钩函数。(是的,我知道汇编程序,我以前多次使用相同的方法)。我在挂钩代码的开头使用 EnterCriticalSection 并使用 InterlockedExchange 来恢复被盗字节,也就是将我在 CreateWindowExA/W 开头写的 JMP 替换为真正的 5 个字节,这样我就可以正确调用该函数。根据我的经验,一切都必须没问题,但发生的情况是,当我刚刚用真实字节替换 JMP 时,其他一些线程/s 调用该函数,看起来字节也被替换了...... .

我知道我可以使用 IAT/EAT 表挂钩,但我想知道我当前的方法有什么问题......也许 InterlockedExchange 不起作用的问题是,从 dll 调用 CreateWindowExA/W(comctl32.dll,shell32.dll ...) 但不是主要的可执行模块。

我希望有人帮助我,如果你不明白我的解释,请询问,我会重新解释。

4

3 回答 3

2

如果您要挂钩 Windows 功能,IAT 挂钩会更好、更安全。但是,如果您坚持使用 detours,通常最好使用 windows 端的内置热补丁(这使得编写 detour 可以原子地编写,不需要同步)。

您的问题正如您所说,您的锁只会暂停您的执行线程,而不是那些由您控制的线程。要解决这个问题,您需要暂停所有这些线程(通过 PSAPI/toolhlp32),或者更有效地,向您绕道的函数添加一个检查,以检查被调用者地址是否位于您想要绕道的模块的地址空间中,这个可以使用 GetModuleHandle、WinNT 中的一些 PE 函数和_ReturnAddress内部函数来完成。

于 2012-05-18T12:12:01.003 回答
1

一旦您更改回字节,挂钩就会丢失,并且关键部分将无济于事,因为这是在 jmp 之后。

看看DXHooks中的http://dxhook.googlecode.com/svn/trunk/dxhook.cpp,因为我认为它可以满足您的需求

于 2012-05-18T13:00:33.387 回答
0

如果您可以控制对 CreateWindowEx 的每一次调用,那么您可以用关键部分包装它们。但是,如果你能做到这一点,那么你就不需要挂钩该函数。

剩下的就是在任何其他线程启动之前挂钩该函数。在您的应用程序开始时执行此操作,可能通过使用静态初始化。

另一个人想到了这个特殊的功能。在许多应用程序中,所有窗口都是在主线程中创建的。如果这对您来说是这样,那么您无需同步。

于 2012-05-18T12:11:32.710 回答