让 DLL 卸载自身

原文链接:http://www.titilima.cn/show-547-1.html

今天的问题是:有没有可能让一个 DLL 自己卸载自己?

这个问题可以分成两个部分:

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

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

#include <Windows.h> HMODULE g_hDll = NULL; DWORD WINAPI UnloadProc(PVOID param) { MessageBox(NULL, TEXT("Press ok to unload me."), TEXT("MsgBox in dll"), MB_OK); FreeLibrary(g_hDll); // oops! return 0; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, PVOID lpvReserved) { if (DLL_PROCESS_ATTACH == fdwReason) { g_hDll = (HMODULE)hinstDLL; HANDLE hThread = CreateThread(NULL, 0, UnloadProc, NULL, 0, NULL); CloseHandle(hThread); } return TRUE; }

简单说明一下:在 DllMain 初始化的时候保存 DLL 的实例句柄(即模块句柄)供 FreeLibrary 调用,然后开启一个线程,在适当的时机调用 FreeLibrary 销毁 DLL。

但是,如果实际运行起来的话,我们会遇到一个很实际的问题:在 FreeLibrary 之后,该 DLL 的地址空间就不再可用了,但这时 EIP 指针仍然会指向 FreeLibrary 的下面一句,于是程序崩溃。

所幸,Win32 提供了另外的一个 API——FreeLibraryAndExitThread,这个函数能够在销毁 DLL 之后直接调用 ExitThread,这样一来 EIP 指针就不会指向非法的地址了。因此,我们只需要把 FreeLibrary 的一句替换为:

FreeLibraryAndExitThread(g_hDll, 0);
这样就可以了。

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值