不幸的是,MSDN对它不够清楚.我正在编写一个使用全局钩子的程序,我担心如果程序异常终止(崩溃,被用户杀死等)会发生什么.
当进程终止时,Windows是否自动解除进程安装的全局挂钩?
如果没有,是否可以在另一个进程中调用UnhookWindowsHookEx()来释放钩子?(我想在钩子线程中这样做,如果它检测到安装程序进程已经死了.)
如果答案是否定,那么在安装程序进程终止时保持全局挂钩处于活动状态并不危险?处理这种情况的标准方法是什么?
我在MSDN中读到UnhookWindowsHookEx()没有释放在其他进程中加载的dll,但它没有说明何时释放dll.CodeProject中的这篇文章似乎暗示当第一条消息到达钩子线程时,dll未被映射(在相应的进程中),所以它就在UnhookWindowsHookEx()调用之后.这是真的吗?
谢谢.
我有一个DLL我注入其他进程使用SetWindowsHookEx
.在DLL内部,我通过调用增加模块的引用计数器,GetModuleHandleEx
这样我可以控制何时卸载模块.
此时,这两个API调用的模块引用计数"应为"2.当调用进程关闭时,它会调用UnhookWindowsHookEx
,将引用计数减少到1. DLL有一个等待一些东西的线程,其中一个是调用进程的句柄SetWindowsHookEx
.当进程消失时,DLL会进行一些清理,终止所有线程,清理内存和句柄然后调用FreeLibraryAndExitThread
.这会减少计数器并卸载DLL.
这是我的问题.有一些进程,尤其是没有UI的进程,DLL永远不会被卸载.我很自信我清理了一切.而且我知道我的线程都没有运行.
首先,如果您有任何疑难解答提示以帮助发现原因,那将会有所帮助.否则,我正在考虑使用一些API NtQueryInformationProcess
来获取模块地址并确认模块句柄计数实际上为零,然后调用CreateRemoteThread
注入一个调用来LdrUnloadDll
从进程内卸载模块地址.你对这种方法有什么看法?有没有人有任何示例代码?我很难找到如何获得模块句柄计数.
当加载它们的系统范围的钩子被卸载时,如何从所有进程正确卸载 DLL?
从MSDN:
您可以使用 UnhookWindowsHookEx 释放全局钩子过程,但该函数不会释放包含钩子过程的 DLL。这是因为在桌面中每个应用程序的进程上下文中调用全局钩子过程,导致对所有这些进程的 LoadLibrary 函数的隐式调用。因为不能为另一个进程调用 FreeLibrary 函数,所以没有办法释放 DLL。在显式链接到 DLL 的所有进程都已终止或调用 FreeLibrary 并且调用挂钩过程的所有进程已在 DLL 外部恢复处理后,系统最终会释放 DLL。
所以我在寻找的是一种检测钩子何时解钩的方法,然后FreeLibrary
从所有被钩子的进程中调用。有没有其他方法可以在卸载钩子时立即卸载 DLL?