删除问题:如何删除exe自己? 新建一个application,在窗体的onclick事件中只有一句:DeleteFile(application.ExeName);怎么不能删除exe自己啊? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1.利用批处理文件2.利用Win.ini文件,重启删除3.进程复制,复制它到系统临时目录里(C:\Windows\temp\),利用复制进程删除原可执行文件,之后自身被操作系统删除4.用 UnmapViewOfFile 解除 exe 文件在内存中的映象,接着通过堆栈传递当前程序的路径名缓冲区指针给 DeleteFile() ,实现了程序的自删除 可以先生成一个.bat文件,文件中不段删除自己。 // 应用程序自我删除的实现// 版权所有(C) 2001, 云横秦岭#include "windows.h"void main(){ HINSTANCE hModule = GetModuleHandle(0); // 获取映像基址 CHAR buf[MAX_PATH]; // 保存文件完整路径 GetModuleFileName(hModule, buf, sizeof(buf)); // 获取文件完整路径 // 获取完成自我删除以及返回操作系统所需的APIs地址 HINSTANCE hKernel = GetModuleHandle("KERNEL32"); DWORD pExitProcess = (DWORD) GetProcAddress(hKernel, "ExitProcess"); DWORD pDeleteFile = (DWORD) GetProcAddress(hKernel, "DeleteFileA"); DWORD pUnmapViewOfFile = (DWORD) UnmapViewOfFile; CloseHandle(HANDLE(4)); // 关闭文件映像对象句柄 __asm { lea eax, buf // 设置待删文件完整路径 push 0 // 设置 ExitProcess 的入口参数 push 0 // ExitProcess 的返回地址 push eax // 设置 DeleteFile 的入口参数 push pExitProcess // DeleteFile 的返回地址 push hModule // 设置UnmapViewOfFile 的入口参数 push pDeleteFile // UnmapViewOfFile 的返回地址 push pUnmapViewOfFile // 接下来 ret 的返回地址 ret }} 進入MS-DOS: 鍵入:edit delete.bat 回車del 你文件名的路徑\文件名.exe回車cls保存退出在你的程序中調用這個批處理文件uses shellapi.........shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail); 不好意思,忘了寫退出dos進入MS-DOS: 鍵入:edit delete.bat 回車del 你文件名的路徑\文件名.exe回車exitcls保存退出在你的程序中調用這個批處理文件uses shellapi.........shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail); 不好意思,忘了寫退出dos進入MS-DOS: 鍵入:edit delete.bat 回車del 你文件名的路徑\文件名.exe回車clsexit保存退出在你的程序中調用這個批處理文件uses shellapi.........shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail); program Project1; uses Windows; procedure DeleteSelf;var hModule: THandle; buff: array[0..255] of Char; hKernel32: THandle; pExitProcess, pDeleteFileA, pUnmapViewOfFile: Pointer;begin hModule := GetModuleHandle(nil); GetModuleFileName(hModule, buff, sizeof(buff)); CloseHandle(THandle(4)); hKernel32 := GetModuleHandle('KERNEL32'); pExitProcess := GetProcAddress(hKernel32, 'ExitProcess'); pDeleteFileA := GetProcAddress(hKernel32, 'DeleteFileA'); pUnmapViewOfFile := GetProcAddress(hKernel32, 'UnmapViewOfFile'); asm LEA EAX, buff PUSH 0 PUSH 0 PUSH EAX PUSH pExitProcess PUSH hModule PUSH pDeleteFileA PUSH pUnmapViewOfFile RET end;end;begin DeleteSelf;end. westfly(西翔) 好像不好使这个绝对没有问题我用得好好的,98/2000/XP都OKprocedure DeleteSelf;var BatchFile: TextFile; BatchFileName: string; ProcessInfo: TProcessInformation; StartUpInfo: TStartupInfo;begin BatchFileName := ChangeFileExt(Paramstr(0),'.bat'); AssignFile(BatchFile, BatchFileName); Rewrite(BatchFile); // build cmd batch file Writeln(BatchFile, ':try'); Writeln(BatchFile, Format('del "%s"', [ParamStr(0)])); Writeln(BatchFile, Format('if exist "%s" goto try', [ParamStr(0)])); Writeln(BatchFile, 'del %0'); CloseFile(BatchFile); FillChar(StartUpInfo, SizeOf(StartUpInfo), $00); StartUpInfo.dwFlags := STARTF_USESHOWWINDOW; StartUpInfo.wShowWindow := SW_HIDE; // create hidden process if CreateProcess(nil, PChar(BatchFileName), nil, nil,False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo,ProcessInfo) then begin CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); end;end; 云横秦岭是个盗版专家,版权到底该是谁的?下面的代码由Gary Nebbett写就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFERENCE的作者.乃NT系统一等一的高手.下面就分析一些他的这段代码. 这段代码在PROCESS没有结束前就将启动PROCESS的EXE文件删除了. int main(int argc, char *argv[]) { HMODULE module = GetModuleHandle(0); CHAR buf[MAX_PATH]; GetModuleFileName(module, buf, sizeof buf); CloseHandle(HANDLE(4)); __asm { lea eax, buf push 0 push 0 push eax push ExitProcess push module push DeleteFile push UnmapViewOfFile ret } return 0; } 现在,我们先看一下堆栈中的东西 偏移 内容 24 0 20 0 16 offset buf 12 address of ExitProcess 8 module 4 address of DeleteFile 0 address of UnmapViewOfFile 调用RET返回到了UnmapViewOfFile,也就是栈里的偏移0所指的地方.当进入UnmapViewOfFile的流程时,栈里见到的是返回地址DeleteFile和HMODUL module.也就是说调用完毕后返回到了DeleteFile的入口地址.当返回到DeleteFile时,看到了ExitProcess的地址,也就是返回地址.和参数EAX,而EAX则是buffer.buffer存的是EXE的文件名.由GetModuleFileName(module, buf, sizeof buf)返回得到.执行了DeleteFile后,就返回到了ExitProcess的函数入口.并且参数为0而返回地址也是0.0是个非法地址.如果返回到地址0则会出错.而调用ExitProcess则应该不会返回. 这段代码的精妙之处在于: 1.如果有文件的HANDLE打开,文件删除就会失败,所以,CloseHandle(HANDLE(4));是十分巧妙的一手.HANDLE4是OS的硬编码,对应于EXE的IMAGE.在缺省情况下,OS假定没有任何调用会关闭IMAGE SECTION的HANDLE,而现在,该HANDLE被关闭了.删除文件就解除了文件对应的一个句柄. 2.由于UnmapViewOfFile解除了另外一个对应IMAGE的HANDLE,而且解除了IMAGE在内存的映射.所以,后面的任何代码都不可以引用IMAGE映射地址内的任何代码.否则就OS会报错.而现在的代码在UnmapViewOfFile后则刚好没有引用到任何IMAGE内的代码. 3.在ExitProcess之前,EXE文件就被删除了.也就是说,进程尚在,而主线程所在的EXE文件已经没了.(WINNT/9X都保护这些被映射到内存的WIN32 IMAGE不被删除.) Gary Nebbett果然是WIN系列平台的顶尖高手之一.能写出如此代码.独辟蹊径啊:) westfly(西翔) 也绝对没问题你把procedure DeleteSelf;复制下来,随便在那里调用 关于数据传输问题!!!大家帮忙建议下 要离开一阵子,关于结贴的事 如何在用ado对不同服务器的表进行关联查询 请问如何在.........Help me !~~ 我没分了,关于比较日期大小的问题。 求助:毕业设计问题,各位高手帮帮忙!!!!!!!!!!!没分可给了,抱歉呀,急的。。 to 7415004(7415004):'在一个贴子里你回复不能超过30次!!'看这里 key violation?? 哪位大侠能把Socket的阻塞和非阻塞用低手能听懂的通俗语言解释一下?? 这里有人编过ERP吗? 组件遍历,怎么遍历!急!!!! 困惑我的三大问题,分不够可以再加
2.利用Win.ini文件,重启删除
3.进程复制,复制它到系统临时目录里(C:\Windows\temp\),利用复制进程删除原可执行文件,之后自身被操作系统删除
4.用 UnmapViewOfFile 解除 exe 文件在内存中的映象,接着通过堆栈传递当前程序的路径名缓冲区指针给 DeleteFile() ,实现了程序的自删除
// 版权所有(C) 2001, 云横秦岭#include "windows.h"void main()
{
HINSTANCE hModule = GetModuleHandle(0); // 获取映像基址
CHAR buf[MAX_PATH]; // 保存文件完整路径
GetModuleFileName(hModule, buf, sizeof(buf)); // 获取文件完整路径
// 获取完成自我删除以及返回操作系统所需的APIs地址
HINSTANCE hKernel = GetModuleHandle("KERNEL32");
DWORD pExitProcess = (DWORD) GetProcAddress(hKernel, "ExitProcess");
DWORD pDeleteFile = (DWORD) GetProcAddress(hKernel, "DeleteFileA");
DWORD pUnmapViewOfFile = (DWORD) UnmapViewOfFile;
CloseHandle(HANDLE(4)); // 关闭文件映像对象句柄 __asm
{
lea eax, buf // 设置待删文件完整路径
push 0 // 设置 ExitProcess 的入口参数
push 0 // ExitProcess 的返回地址
push eax // 设置 DeleteFile 的入口参数
push pExitProcess // DeleteFile 的返回地址
push hModule // 设置UnmapViewOfFile 的入口参数
push pDeleteFile // UnmapViewOfFile 的返回地址
push pUnmapViewOfFile // 接下来 ret 的返回地址
ret
}
}
edit delete.bat 回車
del 你文件名的路徑\文件名.exe回車
cls
保存退出
在你的程序中調用這個批處理文件
uses shellapi
.........
shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail);
進入MS-DOS: 鍵入:
edit delete.bat 回車
del 你文件名的路徑\文件名.exe回車
exit
cls
保存退出
在你的程序中調用這個批處理文件
uses shellapi
.........
shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail);
進入MS-DOS: 鍵入:
edit delete.bat 回車
del 你文件名的路徑\文件名.exe回車
cls
exit
保存退出
在你的程序中調用這個批處理文件
uses shellapi
.........
shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail);
var
hModule: THandle;
buff: array[0..255] of Char;
hKernel32: THandle;
pExitProcess, pDeleteFileA, pUnmapViewOfFile: Pointer;
begin
hModule := GetModuleHandle(nil);
GetModuleFileName(hModule, buff, sizeof(buff));
CloseHandle(THandle(4));
hKernel32 := GetModuleHandle('KERNEL32');
pExitProcess := GetProcAddress(hKernel32, 'ExitProcess');
pDeleteFileA := GetProcAddress(hKernel32, 'DeleteFileA');
pUnmapViewOfFile := GetProcAddress(hKernel32, 'UnmapViewOfFile');
asm
LEA EAX, buff
PUSH 0
PUSH 0
PUSH EAX
PUSH pExitProcess
PUSH hModule
PUSH pDeleteFileA
PUSH pUnmapViewOfFile
RET
end;
end;begin
DeleteSelf;
end.
这个绝对没有问题
我用得好好的,98/2000/XP都OK
procedure DeleteSelf;
var
BatchFile: TextFile;
BatchFileName: string;
ProcessInfo: TProcessInformation;
StartUpInfo: TStartupInfo;
begin
BatchFileName := ChangeFileExt(Paramstr(0),'.bat');
AssignFile(BatchFile, BatchFileName);
Rewrite(BatchFile);
// build cmd batch file
Writeln(BatchFile, ':try');
Writeln(BatchFile, Format('del "%s"', [ParamStr(0)]));
Writeln(BatchFile, Format('if exist "%s" goto try', [ParamStr(0)]));
Writeln(BatchFile, 'del %0');
CloseFile(BatchFile);
FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);
StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
StartUpInfo.wShowWindow := SW_HIDE;
// create hidden process
if CreateProcess(nil, PChar(BatchFileName), nil, nil,False, IDLE_PRIORITY_CLASS,
nil, nil, StartUpInfo,ProcessInfo) then
begin
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;
end;
这段代码在PROCESS没有结束前就将启动PROCESS的EXE文件删除了.
int main(int argc, char *argv[])
{
HMODULE module = GetModuleHandle(0);
CHAR buf[MAX_PATH];
GetModuleFileName(module, buf, sizeof buf);
CloseHandle(HANDLE(4));
__asm {
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push UnmapViewOfFile
ret
}
return 0;
}
现在,我们先看一下堆栈中的东西 偏移 内容
24 0
20 0
16 offset buf
12 address of ExitProcess
8 module
4 address of DeleteFile
0 address of UnmapViewOfFile 调用RET返回到了UnmapViewOfFile,也就是栈里的偏移0所指的地方.当进入UnmapViewOfFile的流程时,栈里见到的是返回地址DeleteFile和HMODUL module.也就是说调用完毕后返回到了DeleteFile的入口地址.当返回到DeleteFile时,看到了ExitProcess的地址,也就是返回地址.和参数EAX,而EAX则是buffer.buffer存的是EXE的文件名.由GetModuleFileName(module, buf, sizeof buf)返回得到.执行了DeleteFile后,就返回到了ExitProcess的函数入口.并且参数为0而返回地址也是0.0是个非法地址.如果返回到地址0则会出错.而调用ExitProcess则应该不会返回.
这段代码的精妙之处在于:
1.如果有文件的HANDLE打开,文件删除就会失败,所以,CloseHandle(HANDLE(4));是十分巧妙的一手.HANDLE4是OS的硬编码,对应于EXE的IMAGE.在缺省情况下,OS假定没有任何调用会关闭IMAGE SECTION的HANDLE,而现在,该HANDLE被关闭了.删除文件就解除了文件对应的一个句柄.
2.由于UnmapViewOfFile解除了另外一个对应IMAGE的HANDLE,而且解除了IMAGE在内存的映射.所以,后面的任何代码都不可以引用IMAGE映射地址内的任何代码.否则就OS会报错.而现在的代码在UnmapViewOfFile后则刚好没有引用到任何IMAGE内的代码.
3.在ExitProcess之前,EXE文件就被删除了.也就是说,进程尚在,而主线程所在的EXE文件已经没了.(WINNT/9X都保护这些被映射到内存的WIN32 IMAGE不被删除.) Gary Nebbett果然是WIN系列平台的顶尖高手之一.能写出如此代码.独辟蹊径啊:)
你把procedure DeleteSelf;
复制下来,随便在那里调用