用自删除dll实现应用程序的安装/卸载代码
2006-07-20 11:38:22 来源:WEB开发网核心提示: 项目(P)| [项目名称] 属性(P)... | C/C++ | 代码生成 | 缓冲区安全检查:否,该设置不会将 /GS 标志传给编译器,用自删除dll实现应用程序的安装/卸载代码(4),从而摆脱 unresolved externals 错误,好了,此外还有一种可选方法是将 DLL 二进
该设置不会将 /GS 标志传给编译器,从而摆脱 unresolved externals 错误。
好了,现在编译生成 DLL,最终的 DLL 大小为 3K,实际的文件大小只有 2.5K。
实现能自删除的可执行程序
这里所用的主要思路是将一个能自删除的 DLL 作为资源保存在拟实现自删除的可执行程序中,然后在需要时重新创建它,同时,启动一个 rundll32.exe 进程实现删除行为。
下面是用于将DLL存储为资源的头文件和资源文件。资源类型值只要大于 256 都可以,这是为用户定义类型预留的。此外还有一种可选方法是将 DLL 二进制文件以字节数组的形式直接存储在源中:
在资源中包含一个文件
// SelfDelete.h
#define RC_BINARYTYPE 256
#define ID_MAGICDEL_DLL 100
// SelfDelete.rc
#include "SelfDelete.h"
ID_MAGICDEL_DLL RC_BINARYTYPE MagicDel.dll
下面是可执行程序关键代码:
#include <windows.h>
#include "SelfDelete.h"
void WriteResourceToFile(HINSTANCE hInstance,
int idResource,
char const *filename)
{
// 存取二进制资源
HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(idResource),
MAKEINTRESOURCE(RC_BINARYTYPE));
HGLOBAL hgRes = LoadResource(hInstance, hResInfo);
void *pvRes = LockResource(hgRes);
DWORD cbRes = SizeofResource(hInstance, hResInfo);
// 将二进制资源写到文件
HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
DWORD cbWritten;
WriteFile(hFile, pvRes, cbRes, &cbWritten, 0);
CloseHandle(hFile);
}
void SelfDelete(HINSTANCE hInstance)
{
WriteResourceToFile(hInstance, ID_MAGICDEL_DLL, "magicdel.dll");
// 生成命令行
// 1. 查找 rundll32.exe
char commandLine[MAX_PATH * 3];
GetWindowsDirectory(commandLine, sizeof(commandLine));
lstrcat(commandLine, "\\rundll32.exe");
if (GetFileAttributes(commandLine) == INVALID_FILE_ATTRIBUTES)
{
GetSystemDirectory(commandLine, sizeof(commandLine));
lstrcat(commandLine, "\\rundll32.exe");
}
// 2. 添加 rundll32.exe 参数
lstrcat(commandLine, " magicdel.dll,_MagicDel@16 ");
// 3. 添加本文件名
char thisName[MAX_PATH];
GetModuleFileName(hInstance, thisName, sizeof(thisName));
lstrcat(commandLine, thisName);
// 执行命令行
PROCESS_INFORMATION procInfo;
STARTUPINFO startInfo;
memset(&startInfo, 0, sizeof(startInfo));
startInfo.dwFlags = STARTF_FORCEOFFFEEDBACK;
CreateProcess(0, commandLine, 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0,
&startInfo, &procInfo);
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
SelfDelete(hInstance);
}
WriteResourceToFile 的功能是存取二进制资源,以便能在磁盘中重建 DLL。Windows 资源 API 提供了一个指向原始数据的指针。
更多精彩
赞助商链接