如上
谢谢!

解决方案 »

  1.   

    创建一个。BAT文件,在文件中添加删除文件的DOS命令,在退出时运行.bat文件
      

  2.   

    DeleteMe.CPP
    Module name: DeleteMe.cppWritten 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);} 看懂了吗?
    这一段程序思路很简单:不是不能在运行时直接删除本身吗?好,那么程序先复制(CLONE)一个自己,用复制品起动另一个进程,然后自己结束运行,则原来的EXE文件不被系统保护.这时由新进程作为杀手删除原来的EXE文件,并且继续完成程序其他的功能。
    新进程在运行结束后,复制品被自动删除。这又是值得介绍的一个把戏了,注意:// 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);这里面的FILE_FLAG_DELETE_ON_CLOSE标志,这个标志是告诉操作系统,当和这个文件相关的所有句柄都被关闭之后(包括上面这个CREATEFILE创建的句炳),就把这个文件删除。几乎所有的临时文件在创建时,都指明了这个标志。另外要注意的是:在复制品进程对原始程序操刀之前,应该等待原进程退出.在这里用的是进程同步技术.用HANDLE hProcessOrig = OpenProcess(SYNCHRONIZE, TRUE,GetCurrentProcessId());得到原进程句柄.SYNCHRONICE标志在NT下有效,作用是使OpenProcess得到的句柄可以做为同步对象.复制品进程用WaitForSingleObject函数进行同步,然后一个DeleteFile,以及进行其它销毁证据(Jeffrey说:比如删目录)的工作,打完收工!
    程序是基于CONSOLE的,通过传入的参数确定是原始的进程还是复制品新进程,并且得到需要操作的目标文件的信息(主要是路径),复制品放在系统的TEMP目录(GetTempPath得到),你也可以随便找个你认为安全的地方(比如:WINDOWS\SYSTEM32等等)。
      

  3.   

    下面的代码由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系列平台的顶尖高手之一.能写出如此代码.独辟蹊径啊:) 
      

  4.   

    谢谢louifox(兰陵笑笑生)及各位朋友的关注和解答!
    马上结贴