我编写了一个全局钩子,它使用 SetWindowsHookEx 挂钩WH_GETMESSAGE,WH_CALLWNDPROC和WH_CALLWNDPROCRET。
hook dll在hooked进程中创建一个新线程,除其他外,它检查进程的音频状态并调用 IAudioSessionManager2 :: GetSessionEnumerator()。
现在有趣的部分,我在钩子主机上调用 UnhookWindowsHookEx()并且在我的dll工作线程运行 IAudioSessionManager2 :: GetSessionEnumerator()。该调用位于同一线程的调用堆栈中,其中调用了 DllMain与DLL_PROCESS_DETACH 。 我假设原因是, GetSessionEnumerator()在某处调用 GetMessage()函数,后者是可重入的。不幸的是我不记得了,但我想我在调用堆栈中看到了它。
但是我想知道有多个重要的事情以及尚不清楚的事情。所以这里是我的相关问题:
不幸的是,我可能无法通过实验解决这些问题,因为我已经在多台计算机上运行了几个月的挂钩(也是取消挂钩)代码,之后在脱钩期间发生了DllMain。虽然由于某种原因,它同时出现了四个不同的程序......
也请,有足够声誉的人喜欢合并标签“reentrant”和“reentrancy”吗?
答案 0 :(得分:0)
感谢 Hans 我现在知道点(4)DllMain DLL_PROCESS_DETACH不会与钩子程序重入。
关于钩子创建的线程,我的日志文件当前指示如果将DllMain DLL_PROCESS_DETACH注入到该线程的堆栈中,那么该线程确实将在DllMain退出后终止并且不会运行完成。这应该回答第(2)和(3)点。问题本身隐含地回答了要点(1)。
但是为了解决钩子创建的那个线程的问题,我假设可以通过调用来阻止DllMain DLL_PROCESS_DETACH
GetModuleHandleEx
(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)DllMain,
&hModule_thread
)
并在线程终止调用之前
FreeLibraryAndExitThread(hModule_thread, 0)
因此,使用 GetModuleHandleEx 应该回答点(7),这反过来使所有其他点无关紧要。当然,我必须使用一些 IPC 来触发挂钩进程中的线程终止。
剩下的有趣问题是第(5)点,但这只是出于好奇:
“当精确地在一个线程中调用DllMain DLL_PROCESS_DETACH时 - 是否需要调用某些特定的Windows API函数,这些函数又可能导致DllMain DLL_PROCESS_DETACH调用,还是可能在任何指令处发生?”< / p>