WEB开发网
开发学院软件开发VC 用自删除dll实现应用程序的安装/卸载代码 阅读

用自删除dll实现应用程序的安装/卸载代码

 2006-07-20 11:38:22 来源:WEB开发网   
核心提示: 要让 DLL 进行自删除需要一点诀窍,rundll32 调用 LoadModule 将 DLL 加载到它的地址空间,用自删除dll实现应用程序的安装/卸载代码(3),如果 DLL 函数可以返回的话,rundll32 将会退出,编译器会报如下两个 无法解析的外部符号( unresolved

要让 DLL 进行自删除需要一点诀窍。rundll32 调用 LoadModule 将 DLL 加载到它的地址空间。如果 DLL 函数可以返回的话,rundll32 将会退出,从而导致 DLL 被释放(不是被删除)。为了解决这个问题,我们可以执行下面的代码:

FreeLibrary(DLL module handle);
   DeleteFile(DLL filename);
   ExitProcess(0);   

MagicDel 函数是不能按这样的顺序进行直接调用的,因为 FreeLibary 会使代码页无效。为此, MagicDel 采用将等效的汇编指令压入堆栈,然后执行它们,后跟一个 ret 指令,最后调用 ExitProccess 以防止进程继续往下执行。我参考 Gary Nebbit 在 Windows 开发杂志(WDJ)“Tech Tips”栏目发表的文章编写了一个汇编代码块。如果你用 Visual Studio 以默认选项生成DLL,最终的二进制文件大约为 40K。由于我们打算将 DLL 作为可执行程序的资源,它的体积越小越好,为此,我们必须对它进行瘦身处理。思路是将无用的 C 运行时代码从DLL中删除掉,具体方法如下:

  1. 本文例子使用 Visual Studio.NET 2003 中文版编译生成 DLL,先设置项目的编译/链接选项:

    项目(P)| [项目名称] 属性(P)... | 链接器 | 输入 | 忽略所有默认库:是(/NODEFAULTLIB),此设置将 /NODEFAULTLIB 选项传给链接器以便过滤掉运行时代码。

  2. 由于 DLL 入口点(Entry Point)通常是由运行时库提供(默认为 DllMain),所以完成上述第一步设置之后,还必须显式地将 DLL入口点设置为 DllMain:

    项目(P)| [项目名称] 属性(P)... | 链接器 | 高级 | 入口点:DllMain。

    如果此时编译生成 DLL,编译器会报如下两个 无法解析的外部符号( unresolved externals ) 错误: error LNK2019: 无法解析的外部符号 ___security_cookie ,该符号在函数 _MagicDel@16 中被引用
    error LNK2019: 无法解析的外部符号 @__security_check_cookie@4 ,该符号在函数 _MagicDel@16 中被引用
    解决方法是进行下一步设置。

    上一页  1 2 3 4 5 6 7  下一页

Tags:删除 dll 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接