Rol*_*kas 14
据我所知,它可以完成,并且有时可以完成(例如在CreateRemoteThread和其他方法注入dll的情况下).所以,
FreeLibraryAndExitThread(hModule, 0)
Run Code Online (Sandbox Code Playgroud)
会做到这一点.
另一方面,打电话
FreeLibrary(hModule)
Run Code Online (Sandbox Code Playgroud)
这里不做 - 来自MSDN:"如果他们分别调用FreeLibrary和ExitThread,就会出现竞争条件.在调用ExitThread之前可以卸载库." 作为一个评论,除了从线程函数返回之外,ExitThread还会进行一些簿记.
所有这些假设您的Dll通过从加载的Dll内部调用LoadLibrary来获取hModule本身,或者更确切地说,通过从加载的Dll内部调用以下函数:
GetModuleHandleEx
(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)DllMain,
&hModule
)
Run Code Online (Sandbox Code Playgroud)
这会增加Dll的引用计数,因此您知道如果稍后使用该句柄释放库,并且如果实际卸载了库,那么您最后一次引用它.
如果您在DLL_PROCESS_ATTACH期间跳过递增Dll的引用计数并仅从DllMain的参数获取hModule,那么您不应该调用FreeLibraryAndExitThread,因为加载Dll的代码仍在使用它,并且此模块句柄实际上不是您管理的.
小智 5
dll完成工作后使用此命令:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, &__ImageBase, 0, NULL);
// terminate if dll run in a separate thread ExitThread(0);
// or just return out the dll
Run Code Online (Sandbox Code Playgroud)
__ImageBase是您的dll的PE标头结构:
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
Run Code Online (Sandbox Code Playgroud)
我认为这不会起作用。从外部使用句柄调用 FreeLibrary(LoadLibrary 将从 DLL 外部的区域调用),因为代码在不再有效的内存位置中运行。
即使这是可能的,但它听起来像是一个糟糕的设计。也许你想制作一些更新程序或类似的东西。多解释一下您期望的结果是什么。从 DLL 内部卸载 DLL 并不是正确的方法。