procedure DeleteMe;
var
  p1,p2,p3,p4:pointer;
  hm:hmodule;
  buf:array[0..Max_path] of char;
begin
  hm:=GetModuleHandle(0);
  GetModuleFileName(hm,buf,sizeof(buf));
  CloseHandle(4);
  p1:=@ExitProcess;
  p2:=@DeleteFile;
  p3:=@UnMapViewOfFile;
  asm
    lea  eax,buf;
    push 0;
    push 0;
    push eax;
    push p1;
    push hm;
    push p2;
    push p3;
    ret;
  end;
end;

解决方案 »

  1.   

    到Borland的论坛去问了问,确实跟laoduan说得一样,要 自己GetProcAddress。代码如下: 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. 现在有一点比较古怪,那就是必须把代码放在一个Procedure里, 直接放在begin ... end.中间是不行的。也许是全局变量不能使用 的缘故,但为什么不能使用,还是不是很清楚。 还有,不GetProcAddress,直接如下写: PUSH OFFSET UnmapViewOfFile trace的结果是执行进入了KERNEL32.UnmapViewOfFile的,只是在 函数内RET $4出就出错了,跳到了一个莫名其妙的地方。为什么会 这样?难道是Delphi的编译器的问题吗? 另外,Borland论坛上RE的代码不是上面的,不过效果跟我写的一样 。但是FreeLibrary(p)跟UnmapViewOfFile(hModule)效果一样吗? 代码如下: program Project1; uses windows; procedure DeleteSelf; var module : HMODULE; buf : array [ 0 .. MAX_PATH - 1 ] of char; p : ULONG; hKrnl32 : HMODULE; pExitProcess, pDeleteFile, pFreeLibrary : pointer; begin module := GetModuleHandle ( nil ); GetModuleFileName ( module, buf, sizeof ( buf ) ); CloseHandle ( THandle ( 4 ) ); p := ULONG ( module ) + 1; //上面这一句什么意思? 
    hKrnl32 := GetModuleHandle ( 'kernel32' ); pExitProcess := GetProcAddress ( hKrnl32, 'ExitProcess' ); pDeleteFile := GetProcAddress ( hKrnl32, 'DeleteFileA' ); pFreeLibrary := GetProcAddress ( hKrnl32, 'FreeLibrary' ); asm lea eax, buf push 0 push 0 push eax push pExitProcess push p push pDeleteFile push pFreeLibrary ret end; end; 
      

  2.   

    procedure TForm1.OnClose;
    var tfTmp:TextFile;
    begin
      ...
      //当然是满足一定条件后才执行一下代码
      Assignfile(tfTmp,'delself.bat');
      Rewrite(tfTmp);
      Writeln(tfTmp,'@echo off');
      Writeln(tfTmp,':loop');
      Writeln(tfTmp,'del '''+Application.ExeName+'''');
      Writeln(tfTmp,'If Exist'+Application.ExeName+'Goto loop');
      Writeln(tfTmp,'del delself.bat');
      Closefile(tfTmp); 
      Winexec('delself.bat', SW_HIDE);
      Close;
    end; 
    http://www.tommstudio.com/newclub30/d_displayjqxw.asp
      

  3.   

    原理:在应用程序刚要退出之前创建一个Delself.bat文件,让它先删除应用程序,然后删除自身。在Form的OnClose事件中加入下列代码: AssignFile(F, ′delself.bat′);Rewrite(F);{F为TextFile类型} WriteLn(F,′del ′+ExtractFileName(Application.ExeName)); WriteLn(F,′del %0′);CloseFile(F); WinExec(′delself.bat′,SW—HIDE); http://www.tommstudio.com/newclub30/d_displayjqxw.asp
      

  4.   

    ----我们经常遇到这样的软件,运行之后就消失的无影无踪,
    特别是一些 黑客的木马工具。如果我们能掌握这个技术,即使
    不做黑客工具,也可以在程序加密、软件卸载等方面发挥作
    用。那么他们是怎样实现的呢? ----以delphi为例,在form关闭的时候执行以下函数closeme即可: procedure TForm1.closeme;
    var f:textfile;
    begin
    assignfile(f,'.\delme.bat');
    rewrite(f);
    writeln(f,'@echo off');
    writeln(f,':loop');
    writeln(f,'del "'+application.ExeName+'"');
    writeln(f,'if exist .\file.exe goto loop');
    writeln(f,'del .\delme.bat');
    closefile(f);
    winexec('.\delme.bat', SW_HIDE);
    close;
    end;
    http://www.tommstudio.com/newclub30/d_displayjqxw.asp
      

  5.   

    让应用程序自身删除  
         原理:在应用程序刚要退出之前创建一个Delself.bat文件,让它先删除应用程序,然后删除自身。在Form的OnClose事件中加入下列代码: AssignFile(F,'delself.bat');Rewrite(F);{F为TextFile类型} WriteLn(F,'del'+ExtractFileName(Application.ExeName)); WriteLn(F,'del %0');CloseFile(F); WinExec('delself.bat',SWHIDE);
      

  6.   

    不要使用汇编,nt等不支持某些指令的。
    可以和我联系。
    [email protected]