线程安全挂钩功能

时间:2012-05-18 11:45:01

标签: c++ windows winapi assembly hook

我正在实现很少的监控应用程序,所以我正在挂钩CreateWindowExA / W进程,所以我可以控制Windows创建。 我用来挂钩的方法是将带有汇编程序JMP指令的调用的前5个字节替换为我的钩子函数。 (是的,我知道汇编程序,我以前多次使用相同的方法)。 我在钩子代码的开头使用EnterCriticalSection,我使用InterlockedExchange来恢复被盗的字节,也就是用真正的5个字节替换我在CreateWindowExA / W开头写的JMP,这样我就可以正确地调用函数了。根据我的经验,一切都很好,但是发生的事情是,当我刚刚用真实字节替换JMP时,其他一些线程调用该函数,看起来字节也替换为它们......

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

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

3 个答案:

答案 0 :(得分:2)

如果您正在挂钩Windows功能,IAT挂钩会更好更安全。但是,如果你坚持使用弯路,它通常更好地使用内置于窗户侧面的热修补(这使得绕道路可以原子地写入,不需要同步)。

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

答案 1 :(得分:1)

一旦你改回字节,挂钩就会丢失,一个关键部分也无济于事,因为这是在jmp之后。

http://dxhook.googlecode.com/svn/trunk/dxhook.cpp中查看DXHooks因为我认为它会做你需要的事情

答案 2 :(得分:0)

如果您可以控制对CreateWindowEx的每次调用,那么您可以使用临界区来包装它们。但是,如果你可以这样做,那么你就不需要挂钩这个功能了。

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

关于这个特殊功能的另一个想法。在许多应用程序中,所有窗口都在主线程中创建。如果是这样,那么你就不需要同步了。