在Windows上放置不安全的DLL清理代码的安全位置?

时间:2017-07-19 10:07:03

标签: windows visual-c++ dll loadlibrary dllmain

我们遇到的情况是,FreeLibrary / (unknown client dll or exe) links dynamically or statically to -> -> DLL_1, loads dynamically -> DLL_x DllMain电话放入我们的最佳解决方案。

当然,你must not do that

  

从DllMain调用FreeLibrary是不安全的。

用例是我们遇到这样的情况:

LoadLibrary

DLL_1应该透明地加载DLL_x。它的客户端代码,它应该动态加载DLL_x。现在,可以懒惰地加载,因此DLL_PROCESS_ATTACH调用不需要驻留在DLL_1的DLL_1/Uninitialize部分。

但是一旦客户端完成了DLL_1,当从进程中卸载DLL_1之前/之后,它也应该卸载(== FreeLibrary)DLL_x。

如果没有必须由客户调用的明确DllMain函数,有没有办法做到这一点?

我会注意到:

  • <system.diagnostics> <sharedListeners> <add name="AzureDriveTraceListener" type="Microsoft.WindowsAzure.WebSites.Diagnostics.AzureDriveTraceListener, Microsoft.WindowsAzure.WebSites.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </sharedListeners> <sources> <source name="TraceSourceLogging" switchName="TestSwitch" switchType="System.Diagnostics.SourceSwitch"> <listeners> <add name="AzureDriveTraceListener"/> </listeners> </source> </sources> <switches> <add name="TestSwitch" value="Verbose" /> </switches> </system.diagnostics> ,因此也不能使用任何C ++全局静态析构函数。
  • 在kernel32 / ntdll或者共享的MS CRT中是否还有其他回调机制可以实现这一点?
  • 还有其他模式可以使这个用例工作吗?

1 个答案:

答案 0 :(得分:1)

正确的方法是DLL_1中的显式Uninitialize函数。

但是,如果你不能这样做,你可以通过启动一个帮助程序线程为你卸载来解决这个问题。如果要安全地播放它,请在加载DLL_x的同时启动该线程并让它等待事件对象。 (但是,对于记录,从DllMain发起一个帖子通常被认为是安全的,只要你尊重它在DllMain退出之前就不会启动的事实。)

显然,帮助程序线程的代码不能在DLL_1中。如果你可以修改DLL_x,你可以把它放在那里。如果没有,您将需要一个帮助DLL。在任何一种情况下,包含帮助程序线程代码的DLL都可以使用FreeLibraryAndExitThread函数安全地自行卸载。