首页 > 代码库 > 程序实现自我删除的七种方法

程序实现自我删除的七种方法

//第一种

利用CREATEFILE函数的FILE_FLAG_DELETE_ON_CLOSE,标志位实现

#include <windows.h>
#include <tchar.h>

int CommitSuicide(char *szCmdLine)
{
	HANDLE hTemp;
	char szPath[MAX_PATH];
	char szTemp[MAX_PATH];

	static BYTE buf[1024];
	
	STARTUPINFO			si;
	PROCESS_INFORMATION pi;
	UINT ret;

	GetTempPath(MAX_PATH, szTemp);
	lstrcat(szTemp, "suicide.exe");

	GetModuleFileName(0, szPath, MAX_PATH);
	
	CopyFile(szPath, szTemp, FALSE);

	hTemp = CreateFile(szTemp, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, 0,
		OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);

	ZeroMemory(&si, sizeof(STARTUPINFO));
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);

	lstrcat(szTemp, " ");
	lstrcat(szTemp, szCmdLine);

	ret = CreateProcess(0, szTemp, 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi);

	Sleep(100);
	CloseHandle(hTemp);

	return 0;
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
	char szPath[MAX_PATH];

	if(szCmdLine[0] == '\0')
	{
		HMODULE hModule = GetModuleHandle(0);

		GetModuleFileName(hModule, szPath, MAX_PATH);

		CommitSuicide(szPath);
		
		return 0;
	}

	else
	{

		Sleep(200);

		DeleteFile(szCmdLine);

		return 0;
	}
}	


第二种

//利用UnmapViewOfFile系列函数逆向删除自身,一般仅限于低版本系统。

#include <windows.h>
#include <tchar.h>

int main(int argc, char *argv[])
{
    TCHAR	buf[MAX_PATH];
	HMODULE module;
	
	module = GetModuleHandle(0);
	GetModuleFileName(module, buf, MAX_PATH);
    CloseHandle((HANDLE)4);
	
    __asm 
	{
        lea     eax, buf
		push    0
		push    0					
		push    eax
		push    ExitProcess
		push    module
		push    DeleteFile
		push    UnmapViewOfFile
		ret
    }
	
    return 0;
}


第三种

//同第二种进行改进

#include <windows.h>

void DeleteMyself()
{
    char    buf[MAX_PATH];
    HMODULE module;
    
    module = GetModuleHandle(0);
    GetModuleFileName(module, buf, MAX_PATH);

    if(0x80000000 & GetVersion())
    {
        __asm 
        {
          lea     eax, buf
          push    0
          push    0
          push    eax
          push    ExitProcess
          push    module
          push    DeleteFile
          push    FreeLibrary
          ret
        }
    }

    else    
    {
        CloseHandle((HANDLE)4);

        __asm 
        {
          lea     eax, buf
          push    0
          push    0
          push    eax
          push    ExitProcess
          push    module
          push    DeleteFile
          push    UnmapViewOfFile
          ret
        }
    }
}

int main(int argc, char *argv[])
{
   DeleteMyself();
   return 0;
} 


第四种

//以临时文件打开创建进程

#include <windows.h>
#include <tchar.h>

#pragma comment (linker, "/NODEFAULTLIB")

#ifndef _DEBUG
#pragma comment(linker,"/merge:.rdata=http://www.mamicode.com/.data")>

第五种

//利用系统环境变量实现

#include <windows.h>

BOOL SelfDelete()
{
  TCHAR szFile[MAX_PATH], szCmd[MAX_PATH];

  if((GetModuleFileName(0,szFile,MAX_PATH)!=0) &&
     (GetShortPathName(szFile,szFile,MAX_PATH)!=0))
  {
    lstrcpy(szCmd,"/c del ");
    lstrcat(szCmd,szFile);
    lstrcat(szCmd," >> NUL");

    if((GetEnvironmentVariable("ComSpec",szFile,MAX_PATH)!=0) &&
       ((INT)ShellExecute(0,0,szFile,szCmd,0,SW_HIDE)>32))
       return TRUE;
  }
  return FALSE;
}

int main()
{
	SelfDelete();
	return 0;
}



第六种

//注入别的进程代替实现

#include <windows.h>
#include <tchar.h>

#pragma pack(push, 1)

#define CODESIZE 0x200

typedef struct _SELFDEL
{
	struct _SELFDEL *Arg0;			

	BYTE	opCodes[CODESIZE];		

	HANDLE	hParent;				

	FARPROC	fnWaitForSingleObject;
	FARPROC	fnCloseHandle;
	FARPROC	fnDeleteFile;
	FARPROC	fnSleep;
	FARPROC	fnExitProcess;
	FARPROC fnRemoveDirectory;
	FARPROC fnGetLastError;

	BOOL	fRemDir;

	TCHAR	szFileName[MAX_PATH];	

} SELFDEL;

#pragma pack(pop)

#ifdef _DEBUG
#define FUNC_ADDR(func) (PVOID)(*(DWORD *)((BYTE *)func + 1) + (DWORD)((BYTE *)func + 5))
#else
#define FUNC_ADDR(func) func
#endif


static void remote_thread(SELFDEL *remote)
{

	remote->fnWaitForSingleObject(remote->hParent, INFINITE);
	remote->fnCloseHandle(remote->hParent);


	while(!remote->fnDeleteFile(remote->szFileName))
	{
		
		remote->fnSleep(1000);
	}
	remote->fnExitProcess(0);
}

	
BOOL SelfDelete(BOOL fRemoveDirectory)
{
	STARTUPINFO			si = { sizeof(si) };
	PROCESS_INFORMATION pi;

	CONTEXT				context;
	DWORD				oldProt;
	SELFDEL				local;
	DWORD				entrypoint;

	TCHAR				szExe[MAX_PATH] = _T("explorer.exe");


	if(CreateProcess(0, szExe, 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi))
	{
		local.fnWaitForSingleObject		= (FARPROC)WaitForSingleObject;
		local.fnCloseHandle				= (FARPROC)CloseHandle;
		local.fnDeleteFile				= (FARPROC)DeleteFile;
		local.fnSleep					= (FARPROC)Sleep;
		local.fnExitProcess				= (FARPROC)ExitProcess;
		local.fnRemoveDirectory			= (FARPROC)RemoveDirectory;
		local.fnGetLastError			= (FARPROC)GetLastError;

		local.fRemDir					= fRemoveDirectory;

		DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), 
			pi.hProcess, &local.hParent, 0, FALSE, 0);

		GetModuleFileName(0, local.szFileName, MAX_PATH);


		memcpy(local.opCodes, FUNC_ADDR(remote_thread), CODESIZE);

		context.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
		GetThreadContext(pi.hThread, &context);

	
		entrypoint = (context.Esp - sizeof(SELFDEL)) & ~0x1F;
		
	
		local.Arg0 = (SELFDEL *)entrypoint;

		context.Esp = entrypoint - 4;	
		context.Eip = entrypoint + 4;	

		
		VirtualProtectEx(pi.hProcess,   (PVOID)entrypoint, sizeof(local), PAGE_EXECUTE_READWRITE, &oldProt);
		WriteProcessMemory(pi.hProcess, (PVOID)entrypoint, &local, sizeof(local), 0);

		FlushInstructionCache(pi.hProcess, (PVOID)entrypoint, sizeof(local));

		SetThreadContext(pi.hThread, &context);

	
		ResumeThread(pi.hThread);
		CloseHandle(pi.hThread);
		CloseHandle(pi.hProcess);

		return TRUE;
	}

	return FALSE;
}


int main(void)
{
	SelfDelete(TRUE);
	return 0;
}


第七种

//同第六种进行改进

#include <windows.h>
#include <tchar.h>

#define EXPLORER_PID 1444

typedef UINT  (WINAPI * WAIT_PROC)(HANDLE, DWORD);	
typedef BOOL  (WINAPI * CLOSE_PROC)(HANDLE);		
typedef BOOL  (WINAPI * DELETE_PROC)(LPCTSTR);		
typedef VOID  (WINAPI * EXIT_PROC)(DWORD);			

typedef struct
{
	WAIT_PROC	fnWaitForSingleObject;
	CLOSE_PROC	fnCloseHandle;
	DELETE_PROC	fnDeleteFile;
	EXIT_PROC	fnExitProcess;

	HANDLE		hProcess;
	TCHAR		szFileName[MAX_PATH];

} INJECT;

#pragma optimize("gsy", off)
#pragma check_stack(off)		

DWORD WINAPI RemoteThread(INJECT *remote)
{
	remote->fnWaitForSingleObject(remote->hProcess, INFINITE);
	remote->fnCloseHandle(remote->hProcess);
	remote->fnDeleteFile(remote->szFileName);
	remote->fnExitProcess(0);

	return 0;
}

#pragma check_stack

HANDLE GetRemoteProcess()
{
	STARTUPINFO			si = { sizeof(si) };
	PROCESS_INFORMATION pi;

	
	if(CreateProcess(0, "explorer.exe", 0, 0, FALSE, CREATE_SUSPENDED|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS,                         0, 0, &si, &pi))
	{
		CloseHandle(pi.hThread);
		return pi.hProcess;
	}
	else
	{
		return 0;
	}
}

PVOID GetFunctionAddr(PVOID func)
{
#ifdef _DEBUG


	DWORD *offset = (BYTE *)func + 1;
	return (PVOID)(*offset + (BYTE *)func + 5);

#else

	return func;

#endif
}

BOOL SelfDelete()
{
	INJECT local, *remote;
	BYTE   *code;
	HMODULE hKernel32;
	HANDLE  hRemoteProcess;
	HANDLE  hCurProc;

	DWORD	dwThreadId;
	HANDLE	hThread = 0;

	char ach[80];

	hRemoteProcess = GetRemoteProcess();

	if(hRemoteProcess == 0)
		return FALSE;
	

	code = VirtualAllocEx(hRemoteProcess, 0, sizeof(INJECT) + 128, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);

	if(code == 0)
	{
		CloseHandle(hRemoteProcess);
		return FALSE;
	}

	hKernel32 = GetModuleHandle(_T("kernel32.dll"));

	remote = (INJECT *)(code + 128);

	local.fnWaitForSingleObject  = (WAIT_PROC)GetProcAddress(hKernel32,  "WaitForSingleObject");
	local.fnCloseHandle		     = (CLOSE_PROC)GetProcAddress(hKernel32, "CloseHandle");
	local.fnExitProcess			 = (EXIT_PROC)GetProcAddress(hKernel32, "ExitProcess");

#ifdef UNICODE
	local.fnDeleteFile			  = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileW");
#else
	local.fnDeleteFile			  = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileA");
#endif


	hCurProc = GetCurrentProcess();
	DuplicateHandle(hCurProc, hCurProc, hRemoteProcess, &local.hProcess, 0, FALSE, DUPLICATE_SAME_ACCESS);

	GetModuleFileName(NULL, local.szFileName, MAX_PATH);


	WriteProcessMemory(hRemoteProcess, code,    GetFunctionAddr(RemoteThread), 128, 0);
	WriteProcessMemory(hRemoteProcess, remote, &local, sizeof(local), 0);

	wsprintf(ach, "%x %x\n", code, remote);
	OutputDebugString(ach);


	hThread = CreateRemoteThread(hRemoteProcess, 0, 0, code, remote, 0, &dwThreadId);

	if(hThread != 0)
	{
		CloseHandle(hThread);
	}
	
	return TRUE;
}

int main(void)
{
	SelfDelete();

	return 0;
}