2012年7月5日星期四

delete_myself.asm


;功能:实现删除自己。
;改编自网上的c/c++代码。
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include Shell32.inc
includelib Shell32.lib
includelib kernel32.lib

.code
psi STARTUPINFO <sizeof psi,0>
pi PROCESS_INFORMATION <0>
sa SECURITY_ATTRIBUTES <sizeof sa,0,1>
x dd 0
z dd 0
s dd 0
buffer db 261 dup (0)
name1 db "1.exe",0
name2 db "2.exe",0
name3 db "1.exe i",0
name4 db "net",0

start:
invoke GetCommandLineW
invoke CommandLineToArgvW,eax,addr x
mov eax,[eax]
mov z,eax

invoke lstrlenW,z
mov s,eax

invoke WideCharToMultiByte,0,0,z,s,addr buffer,sizeof buffer,0,0

mov eax,x
.if eax==1
  invoke CopyFile,addr buffer,addr name1,0
  invoke MoveFile,addr buffer,addr name2
  invoke CreateFile,addr name1,0,FILE_SHARE_READ,addr sa,OPEN_EXISTING,FILE_FLAG_DELETE_ON_CLOSE,0
  invoke CreateProcess,0,addr name3,0,0,1,0,0,0,addr psi,addr pi
.elseif 
  invoke DeleteFile,addr name2
  invoke CreateProcess,0,addr name4,0,0,1,DEBUG_ONLY_THIS_PROCESS,0,0,addr psi,addr pi
.endif

invoke ExitProcess,0
end start 
;made at 2011.05.02
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//一个c/c++代码如下:
//调试的时候不能删除。
#include <windows.h>

struct StackContext
{//栈回溯的实现。
  DWORD_PTR DeleteFileW;
  DWORD_PTR WaitForSingleObject_argv1;
  DWORD_PTR WaitForSingleObject_argv2;
  DWORD_PTR ExitProcess;
  DWORD_PTR DeleteFileW_argv1;
  DWORD_PTR shit;
  DWORD_PTR ExitProcess_argv1;
}stackctx;

BOOL DeleteMyself()
{
  WCHAR helper[MAX_PATH];
  ZeroMemory(helper, sizeof(helper));
  wcscpy(helper, L"explorer.exe");

  STARTUPINFOW si = {sizeof(STARTUPINFOW),0};
  PROCESS_INFORMATION pi;
  CreateProcess(NULL, helper, 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si, &pi);
  //以上是打开一个程序,并挂起。

  //填写结构
  CONTEXT ctx = {CONTEXT_FULL,0};
  GetThreadContext(pi.hThread, &ctx);
  ctx.Eip = (DWORD_PTR)GetProcAddress(GetModuleHandleW(L"Kernel32.dll"), "WaitForSingleObject");
  ctx.Esp = (DWORD_PTR)VirtualAllocEx(pi.hProcess, 0, 512*1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  ctx.Esp += 256*1024;

  //填写结构。
  stackctx.DeleteFileW = (DWORD_PTR)GetProcAddress(GetModuleHandleW(L"Kernel32.dll"), "DeleteFileW");
  stackctx.WaitForSingleObject_argv1 = (DWORD_PTR)OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());
  stackctx.WaitForSingleObject_argv2 = (DWORD_PTR)-1;
  stackctx.ExitProcess = (DWORD_PTR)GetProcAddress(GetModuleHandleW(L"Kernel32.dll"), "ExitProcess");
  WCHAR MyselfPath[MAX_PATH];
  int nPathLen = GetModuleFileNameW(NULL, MyselfPath, MAX_PATH);
  stackctx.DeleteFileW_argv1 = (DWORD_PTR)VirtualAllocEx(pi.hProcess, 0, (nPathLen+1)*sizeof(WCHAR), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  stackctx.shit = 0;
  stackctx.ExitProcess_argv1 = 0;

  //写入打开进程的内存地址。
  WriteProcessMemory(pi.hProcess, (LPVOID)stackctx.DeleteFileW_argv1, MyselfPath, (nPathLen+1)*sizeof(WCHAR), NULL);
  WriteProcessMemory(pi.hProcess, (LPVOID)(ctx.Esp), &stackctx, sizeof(stackctx), NULL);

  //运行打开线程的指定的内容。
  SetThreadContext(pi.hThread, &ctx);
  ResumeThread(pi.hThread);

  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  return TRUE;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  DeleteMyself();
  return 0;
}
//2011.12.09修改自网上的代码。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//又一办法:
#include <windows.h>
#include <shlobj.h>
#include <shellapi.h>

BOOL SelfDelete()
{
  TCHAR szModule [MAX_PATH], szComspec[MAX_PATH], szParams [MAX_PATH];

  GetModuleFileName(0,szModule,MAX_PATH) ;
  GetShortPathName(szModule,szModule,MAX_PATH);
  GetEnvironmentVariable("COMSPEC",szComspec,MAX_PATH);

  lstrcpy(szParams,"/c del ");
  lstrcat(szParams, szModule);
  lstrcat(szParams, " > nul");

  SHELLEXECUTEINFO sei;
  sei.cbSize       = sizeof(sei);
  sei.hwnd         = 0;
  sei.lpVerb       = "Open";
  sei.lpFile       = szComspec;
  sei.lpParameters = szParams;
  sei.lpDirectory  = 0;
  sei.nShow        = SW_HIDE;
  sei.fMask        = SEE_MASK_NOCLOSEPROCESS;

  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

  ShellExecuteEx(&sei);
  SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS);
  SetProcessPriorityBoost(sei.hProcess,TRUE);

  SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,szModule,0);
  return TRUE;

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow)
{
  SelfDelete();
  return 0;
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;此方法在xp下无效。
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;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//dll自删除的c/c++代码。
#include <windows.h>
#include <tchar.h>

HMODULE hDll;

extern "C" __declspec(dllexport) void DeleteMe()
{
   //在这里干其它想干的事,如删除其它exe文件

   //下面代码实现DLL自删除
   TCHAR* szDll = (TCHAR*)VirtualAlloc(NULL, MAX_PATH, MEM_COMMIT, PAGE_READWRITE);
   GetModuleFileName(hDll, szDll, MAX_PATH);

   __asm
   {
     push 0         ;参数1
     push 0
     push szDll       ;参数2
     push ExitProcess
     push hDll       ;参数3
     push DeleteFile
     push FreeLibrary
     ret           
   }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD   ul_reason_for_call, LPVOID lpReserved )
{
   switch (ul_reason_for_call)
   {
   case DLL_PROCESS_ATTACH:
     hDll = hModule;
     break;
   case DLL_PROCESS_DETACH:
     break;
   }
   return TRUE;
}
将代码编译为test.dll,然后rundll32 test.dll,DeleteMe运行,test.dll就自己删除了
那段__asm代码就是精华所在了
执行ret后,就返回到FreeLibrary处去执行,这时候ESP+4就是FreeLibrary的参数,也就是相当于调用了FreeLibrary(参数3),而参数3是DLL自身的模块句柄,所以相当于DLL自己把自己从rundll32.exe里给卸载了;
FreeLibrary执行完后会将参数3出栈,并返回到DeleteFile处去执行,这时相当于调用了DeleteFile(参数2),参数2就是DLL文件自身的路径啦,这个路径必须存放在用VirtualAlloc在rundll32.exe里分配的内存,因为这时DLL已经被卸载了;
同理最后调用的是ExitProcess(参数1),防止rundll32继续运行下去出错。
这样DLL就可以实现自删除啦,这有啥用捏?借助这个DLL,可以实现EXE的自删除,例如把这个DLL放到一个EXE里,当EXE需要自删除的时候,先释放出DLL,然后把EXE自身的路径告诉DLL,最后CreateProcess   rundll32 xxx.dll,DeleteMe,DeleteMe里先删除EXE,再自删除,就可以实现EXE的自删除啦。
注释:本文照抄自网络。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;一下代码在win 7上偶尔成功。.386  .model flat, stdcall  option casemap :none
include   windows.inc  include   kernel32.inc  includelib kernel32.lib  include   user32.inc  includelib user32.lib      .dataexplorer    db "Progman",0exp_class    db "Program Manager",0ken      db "Kernel32.dll",0LoadLib      db "LoadLibraryA",0delef    db "DeleteFileA",0  
.data?hInstance HINSTANCE ?rs_addr    dd ?system_dir    db 260 dup(?)explorer_hd    dword <>vm_hd    dword <>bw_file    dd ?open_proc_hd    dword <>  ken32    dword <>dwProcessID dd ?rt_hd dd ?   .codestart:invoke GetModuleHandle, 0mov    hInstance,eaxinvoke FindWindow,addr explorer,addr exp_class  invoke  GetWindowThreadProcessId,eax,offset dwProcessID  invoke OpenProcess,PROCESS_VM_WRITE or PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION,TRUE ,dwProcessIDmov   open_proc_hd,eax  invoke VirtualAllocEx,open_proc_hd,0,260,MEM_COMMIT,PAGE_EXECUTE_READWRITEmov vm_hd,eaxinvoke LoadLibrary,addr kenmov  ken32,eaxinvoke GetModuleFileName,hInstance,addr system_dir,MAX_PATHinvoke WriteProcessMemory,open_proc_hd,vm_hd,addr system_dir,250,rt_hdinvoke GetProcAddress,ken32,addr delefinvoke CreateRemoteThread,open_proc_hd,NULL,0,eax,vm_hd,0,NULLinvoke ExitProcess,NULLend start 

没有评论:

发表评论