怎么样在程序内部,删除本身?有人说用批处理,但批处理要删除时会出现无法仿问,有没有更好的方法???

解决方案 »

  1.   

    下面的代码由Gary Nebbett写就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFE
    RENCE的作者.乃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所指的地方.当进入UnmapViewOf
    File的流程时,栈里见到的是返回地址DeleteFile和HMODUL module.也就是说调用完毕后
    返回到了DeleteFile的入口地址.当返回到DeleteFile时,看到了ExitProcess的地址,也
    就是返回地址.和参数EAX,而EAX则是buffer.buffer存的是EXE的文件名.由GetModuleFi
    leName(module, buf, sizeof buf)返回得到.执行了DeleteFile后,就返回到了ExitPro
    cess的函数入口.并且参数为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不被删除.)
      

  2.   

    bat.bat 我的批处理如下:
    del c:\a.exe
    copy c:\b.exe c:\a.exe然后在程序a.exe的InitInstance()开始处用ShellExecute()执行这个批处理,结果是这样:有时候可以del,有时候会出现无法访问,但第二个语句可以成功执行。
    如果去掉第一个语句,只执行copy那句,就无法成功执行,怎么回事??
      

  3.   

    这个我试过了,绝对可以,要在WinMain函数中进行。    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
        }
      

  4.   

    deleteme.cpp
    module name: deleteme.cpp
    written by: jeffrey richterdescription: 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_closehandle 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 ithandle 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);}
      

  5.   

    Gary Nebbett的方法只能在WINNT/2K/XP下使用, 不适用于Win9x.
      

  6.   

    程序自我更新问题,在程序内部通过判断,发现有新版本的EXE,不想通过额外的程序,有没有办法实现自我更新??? 也就先删掉自己,再把新版本拷进去
      

  7.   

    哈哈,在Win2000下,下面的代码随便放那里都可以!!!!
    98下好像完全不行。
        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
        }