== 怎样在程序删除自身那个 exe 文件啊 ==

zPerry 2004-01-13 12:07:28
也就是说,一个程序 delself.exe,运行它后能删除 delself.exe 文件
...全文
363 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
taianmonkey 2004-01-17
  • 打赏
  • 举报
回复
/////////////////////////////////////////////////////////////////////////
//98,2000下通过
//nt/2000下面的删除代码方法来自陆麟(lu0)的文章,再此表示感谢

#pragma optimize( "", off )
/*NOTE fun_AfterDelSelf MUST BE memory allocate by HeapAlloc or VirtualAlloc,and you should free it your self.
,can't use normal callback function(which data on diskdrive,and can't access it after we delete ourself
*/

int DeleteSelf(void * fun_AfterDelSelf)//
{
typedef int (WINAPI *PFClose)(LPVOID);
OSVERSIONINFO os_info;
os_info.dwOSVersionInfoSize=sizeof(os_info);
LPVOID pBuffer=NULL;
PFClose pClose;
PFClose pDelete;
char fn[4096];
HINSTANCE hins=GetModuleHandle(NULL);
GetModuleFileName(NULL,fn,4096);
if(!GetVersionEx(&os_info))
 return false;

switch(os_info.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
 __try{
  while(CloseHandle((HANDLE)4));
 }__except(1){
 }
 CloseHandle((HANDLE)4);
 pClose=PFClose(UnmapViewOfFile);
 break;
case VER_PLATFORM_WIN32_WINDOWS:
 pClose=PFClose(FreeLibrary);
 break;
default:
 return false;
}
pDelete=PFClose(DeleteFile);
pBuffer=VirtualAlloc(NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
__asm{
 call _delete_end
}
 __asm{
_test_close:
 push hins
 call [pClose]
 or eax,eax
 jz _test_close
 lea eax,fn
 push eax
 call [pDelete]
 mov eax,fun_AfterDelSelf
 or eax,eax
 jz _Exit_Process
 call eax
_Exit_Process:
 push 0
 push MEM_RELEASE
 push 0
 push pBuffer
 
 push ExitProcess
 push VirtualFree
 ret
}
_delete_end:
__asm{
 pop ebx
 push 128
 push ebx
 push [pBuffer]
 call memcpy
 jmp pBuffer
}
return 0;
}
#pragma optimize( "", on )
/////////////////////////////////////////////////////////////////////////
lzzqqq 2004-01-17
  • 打赏
  • 举报
回复
操,程序自杀啊,在Google上一搜一堆。。。。。
topwork 2004-01-17
  • 打赏
  • 举报
回复
to WnEunfn(看人间有情,问斯人不语)
这段代码在网上流传很久了,可是我还没有试验成功过,不知道您能否给与指教?
Viconia 2004-01-17
  • 打赏
  • 举报
回复
mark
zPerry 2004-01-17
  • 打赏
  • 举报
回复
Gary Nebbett 那个例子我以前看过,不过好像在 XP 下没成功。
其他的我试一下,成功立即给分。
zachary7833 2004-01-17
  • 打赏
  • 举报
回复
用过DOS的朋友应该还记得批处理文件吧,新建一个批处理文件a.bat,编辑其内容为:del %0,然后运行它,怎么样?a.bat把自己删除掉了!好,我们就用它来进行程序的“自杀”!
找一个EXE可执行文件,比如说abc.exe,新建一个批处理文件a.bat,编辑其内容为:
:pp
del abc.exe
if exist abc.exe goto pp
del %0
先运行abc.exe,再运行a.bat,然后将abc.exe退出,你会发现a.exe和a.bat都没有了!按照这个思路,我们可以在程序中根据文件名称写一个批处理,将上面的abc.exe换成自己的EXE文件名就可以了
WnEunfn 2004-01-17
  • 打赏
  • 举报
回复
进程退出前删除自身EXE

-----------------------------------------------------------------------
下面的代码由Gary Nebbett写的,在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. 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不被删除。)
picker 2004-01-17
  • 打赏
  • 举报
回复
thanks
suntao222 2004-01-17
  • 打赏
  • 举报
回复
study
akiy 2004-01-17
  • 打赏
  • 举报
回复
再不行看看这个
DeleteMe.CPP


Module name: DeleteMe.cpp

Written by: Jeffrey Richter

Description: Allows an EXEcutable file to delete itself

********************************************************************/


#include <Windows.h>

#include <stdlib.h>

#include <tchar.h>


/////////////////////////////////////////////////////////////////////


int WINAPI WinMain(HINSTANCE h, HINSTANCE b, LPSTR psz, int n) {


// Is this the Original EXE or the clone EXE?

// If the command-line 1 argument, this is the Original EXE

// If the command-line >1 argument, this is the clone EXE


if (__argc == 1) {


// Original EXE: Spawn clone EXE to delete this EXE

// Copy this EXEcutable image into the user's temp directory


TCHAR szPathOrig[_MAX_PATH], szPathClone[_MAX_PATH];

GetModuleFileName(NULL, szPathOrig, _MAX_PATH);

GetTempPath(_MAX_PATH, szPathClone);

GetTempFileName(szPathClone, __TEXT("Del"), 0, szPathClone);

CopyFile(szPathOrig, szPathClone, FALSE);


//***注意了***:

// Open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE

HANDLE hfile = CreateFile(szPathClone, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);


// Spawn the clone EXE passing it our EXE's process handle

// and the full path name to the Original EXE file.

TCHAR szCmdLine[512];

HANDLE hProcessOrig = OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());

wsprintf(szCmdLine, __TEXT("%s %d \"%s\""), szPathClone, hProcessOrig, szPathOrig);

STARTUPINFO si;

ZeroMemory(&si, sizeof(si));

si.cb = sizeof(si);

PROCESS_INFORMATION pi;

CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);

CloseHandle(hProcessOrig);

CloseHandle(hfile);


// This original process can now terminate.

} else {


// Clone EXE: When original EXE terminates, delete it

HANDLE hProcessOrig = (HANDLE) _ttoi(__targv[1]);

WaitForSingleObject(hProcessOrig, INFINITE);

CloseHandle(hProcessOrig);

DeleteFile(__targv[2]);

// Insert code here to remove the subdirectory too (if desired).


// The system will delete the clone EXE automatically

// because it was opened with FILE_FLAG_DELETE_ON_CLOSE

}

return(0);

}

 

看懂了吗?


这一段程序思路很简单:不是不能在运行时直接删除本身吗?好,那么程序先复制(CLONE)一个自己,用复制品起动另一个进程,然后自己结束运行,则原来的EXE文件不被系统保护.这时由新进程作为杀手删除原来的EXE文件,并且继续完成程序其他的功能。


新进程在运行结束后,复制品被自动删除。这又是值得介绍的一个把戏了,注意:

// Open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE

HANDLE hfile = CreateFile(szPathClone, 0, FILE_SHARE_READ, NULL,OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);

这里面的FILE_FLAG_DELETE_ON_CLOSE标志,这个标志是告诉操作系统,当和这个文件相关的所有句柄都被关闭之后(包括上面这个CREATEFILE创建的句炳),就把这个文件删除。几乎所有的临时文件在创建时,都指明了这个标志。

另外要注意的是:在复制品进程对原始程序操刀之前,应该等待原进程退出.在这里用的是进程同步技术.用

HANDLE hProcessOrig = OpenProcess(SYNCHRONIZE, TRUE,GetCurrentProcessId());

得到原进程句柄.SYNCHRONICE标志在NT下有效,作用是使OpenProcess得到的句柄可以做为同步对象.复制品进程用WaitForSingleObject函数进行同步,然后一个DeleteFile,以及进行其它销毁证据(Jeffrey说:比如删目录)的工作,打完收工!


程序是基于CONSOLE的,通过传入的参数确定是原始的进程还是复制品新进程,并且得到需要操作的目标文件的信息(主要是路径),复制品放在系统的TEMP目录(GetTempPath得到),你也可以随便找个你认为安全的地方(比如:WINDOWS\SYSTEM32等等)。

这里面没有甚么深的技术.再看其他的一些实现删除自己的例子,比如说在进程退出前,用fwrite等方法输出一个.BAT文件,在里面写几句DEL,然后WINEXEC一下这个BAT文件即可.玩儿过DOS的虫虫大多都会。今天又学一招,爽。
akiy 2004-01-17
  • 打赏
  • 举报
回复
有段汇编是干这个得
找了半天,没找到
你翻翻去年的贴子吧
ying_feng 2004-01-17
  • 打赏
  • 举报
回复
以前用vb试过,编一个批处理文件,里面有等待时间的命令。然后在程序关闭自己时调用批处理文件就可以了。
lostgdi731 2004-01-17
  • 打赏
  • 举报
回复
利用“第三者”的方法给于删除的操作。
lsaturn 2004-01-17
  • 打赏
  • 举报
回复
用MoveFile可以实现重新启动后删除
我想或许可以通过远程线程把代码写到另外的进程中去,然后等程序退出后再来删除这个程序!
马丁当 2004-01-16
  • 打赏
  • 举报
回复
记得以前讨论过,好象程序员杂志上也写过,但好象是不可以。
carbon107 2004-01-16
  • 打赏
  • 举报
回复
??
自杀

这个好像不合情理吧
zPerry 2004-01-14
  • 打赏
  • 举报
回复
Up

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧