Winapi DllMain DLL\u进程\u分离和GetMessage函数重入

Winapi DllMain DLL\u进程\u分离和GetMessage函数重入,winapi,setwindowshookex,reentrancy,getmessage,dllmain,Winapi,Setwindowshookex,Reentrancy,Getmessage,Dllmain,我已经编写了一个全局钩子,它使用WH_GETMESSAGE、WH_CALLWNDPROC和WH_CALLWNDPROCRET钩子。 钩子dll在钩子进程中创建一个新线程,该线程检查进程的音频状态,并调用IAAudioSessionManager2::GetSessionNumerator() 有趣的是,我从钩子主机调用了unhookwindowshookx(),在我的dll的工作线程运行调用IAudioSessionManager2::getsessionnumerator()期间。该调用位于同

我已经编写了一个全局钩子,它使用WH_GETMESSAGE、WH_CALLWNDPROC和WH_CALLWNDPROCRET钩子。
钩子dll在钩子进程中创建一个新线程,该线程检查进程的音频状态,并调用IAAudioSessionManager2::GetSessionNumerator()

有趣的是,我从钩子主机调用了unhookwindowshookx(),在我的dll的工作线程运行调用IAudioSessionManager2::getsessionnumerator()期间。该调用位于同一线程的调用堆栈中,调用了dllmainwithdll\u PROCESS\u DETACH。 我假设原因是,getSessionNumerator()在某处调用了GetMessage()函数,后者是可重入的。不幸的是,我记不清了,但我想我在调用堆栈中看到了这一点

但我对许多重要的事情感到好奇,还有一些事情尚不清楚。下面是我的相关问题:

  • DllMain with DLL_PROCESS_DETACH是否可以随时调用,即使在运行当前正在卸载的DLL函数的线程中也是如此
  • 当DllMain DLL\u PROCESS\u DETACH退出时,堆栈上的函数会发生什么情况?调用堆栈上的函数中的代码最终会执行吗
  • 如果这些功能不退出怎么办?什么时候卸载dll
  • 在调用WH_GETMESSAGE、WH_CALLWNDPROC和WH_CALLWNDPROCRET钩子的过程中,是否可以类似地调用DllMain DLL_PROCESS_DETACH?我知道并通过实验证实,有时(虽然不是经常)这些函数是可重入的,因此可以在前一个调用仍在同一堆栈中运行时注入对这些函数的调用,但我不知道是否也可以以类似的方式注入对DllMain的调用
  • 当DllMain可以在线程中调用时,是否需要调用某些特定的Windows API函数,这些函数可能会导致DllMain DLL_进程_分离调用,或者在任何指令中都会发生这种情况
  • 如果DllMain DLL\u PROCESS\u DETACH调用可以随时“注入”,并且调用堆栈上的函数不再执行,那么我如何确切地知道调用堆栈上的函数在哪里中断?因此,我可以在DllMain内部释放一些由函数在堆栈上分配的句柄或资源
  • 有没有办法暂时阻止/推迟对DllMain DLL\u进程\u分离的调用?如果调用/中断发生在同一堆栈中,锁显然没有帮助
  • 不幸的是,我可能无法通过实验来解决这些问题,因为我已经在多台计算机上运行了我的挂接(以及取消挂接)代码数月了,而在取消挂接过程中,DllMain出现了这种情况。尽管出于某种原因,它同时出现在四个不同的程序中



    另外,有足够声誉的人愿意合并标记“可重入”和“可重入”吗?

    多亏了Hans我现在知道关于第(4)点,DllMain DLL_进程_分离将不会与钩子过程重入

    关于钩子创建的线程,我的日志文件当前表明,如果将DllMain DLL_PROCESS_DETACH注入到该线程的堆栈中,那么该线程确实会在DllMain退出后终止,并且不会运行到完成。这应该回答第(2)点和第(3)点。问题本身隐含地回答了第(1)点

    但是为了解决钩子创建的线程的问题,我假设可以通过调用

    GetModuleHandleEx
    (
        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
        (LPCTSTR)DllMain,
        &hModule_thread
    )
    
    在线程终止调用之前

    FreeLibraryAndExitThread(hModule_thread, 0)
    
    因此,使用GetModuleHandleEx应回答第(7)点,这反过来又使所有其他点变得无关紧要。当然,我必须使用一些IPC来触发挂钩进程中的线程终止

    剩下的有趣问题是第(5)点,但这只是出于好奇:

    “当DllMain DLL\u PROCESS\u DETACH可以在线程中调用时,是否需要调用某些特定的Windows API函数,这些函数反过来可能导致DllMain DLL\u PROCESS\u DETACH调用,或者它可能发生在任何指令上?”

    您肯定是在最大限度地提高痛苦的可能性。Windows只与钩子调用互锁解除钩子,它知道关于您启动的线程的bean。当您调用一个COM方法时,当调用需要被封送到另一个单元并在COM模式循环中等待时,您得到的重入性是臭名昭著的。所以,是的,不要指望Windows能帮你摆脱麻烦。谢谢!据我所知,这用“否”回答了第(4)点,这让我松了一口气:)也许你也用“在COM调用期间可以在非钩子回调堆栈中调用DllMain,但不能在随机指令中调用”回答了第(5)点?请确认后一个问题。Downwoters,请发表意见,还有什么可以改进的?关于最后一个开放式问题编号(5),我假设
    GetMessage
    可以调用
    FreeLibraryAndExitThread
    ,以获取某些消息,并触发
    DllMain