打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
让 DLL 卸载自身



今天的问题是:有没有可能让一个 DLL 自己卸载自己?
这个问题可以分成两个部分:

  1. 卸载一个 DLL。
  2. 卸载 DLL 的代码应该是放在 DLL 之中的。

当然,如果不考虑后果的话,这个代码并不难写,如下:

C++代码
  1. #include <Windows.h>   
  2.   
  3. HMODULE g_hDll = NULL;   
  4.   
  5. DWORD WINAPI UnloadProc(PVOID param)   
  6. {   
  7.     MessageBox(NULL, TEXT("Press ok to unload me."),   
  8.         TEXT("MsgBox in dll"), MB_OK);   
  9.     FreeLibrary(g_hDll);   
  10.     // oops!   
  11.     return 0;   
  12. }   
  13.   
  14. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, PVOID lpvReserved)   
  15. {   
  16.     if (DLL_PROCESS_ATTACH == fdwReason)   
  17.     {   
  18.         g_hDll = (HMODULE)hinstDLL;   
  19.         HANDLE hThread = CreateThread(NULL, 0, UnloadProc, NULL, 0, NULL);   
  20.         CloseHandle(hThread);   
  21.     }   
  22.     return TRUE;   
  23. }  

简单说明一下:在 DllMain 初始化的时候保存 DLL 的实例句柄(即模块句柄)供 FreeLibrary 调用,然后开启一个线程,在适当的时机调用 FreeLibrary 销毁 DLL。
但是,如果实际运行起来的话,我们会遇到一个很实际的问题:在 FreeLibrary 之后,该 DLL 的地址空间就不再可用了,但这时 EIP 指针仍然会指向 FreeLibrary 的下面一句,于是程序崩溃。
所幸,Win32 提供了另外的一个 API——FreeLibraryAndExitThread,这个函数能够在销毁 DLL 之后直接调用 ExitThread,这样一来 EIP 指针就不会指向非法的地址了。因此,我们只需要把 FreeLibrary 的一句替换为:

C++代码
  1. FreeLibraryAndExitThread(g_hDll, 0);  

这样就可以了。

实际测试一下,在 DLL 被加载后,July 的模块视图显示了这个被加载的 DLL。

在内存视图中检查模块句柄指向的内容,证明该 DLL 的确被加载了。

FreeLibraryAndExitThread 调用后,再查看该模块句柄指向的内存,该地址已不再可用,销毁成功。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
FreeLibraryAndExitThread DLL中线程的安全退出
Dll 动态调用
C++与Fortran混合语言编程中动态连接库的调用
[Win32] DLL注入技术
LIB和DLL的区别与使用
VC2008如何生成及使用DLL(完整版)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服