//第一种
利用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=.data") #pragma comment(linker,"/merge:.text=.data") #pragma comment(linker,"/merge:.reloc=.data") #pragma comment(linker,"/FILEALIGN:0x200") #endif // _DEBUG TCHAR szAppName[] = _T("delthis"); TCHAR szUsage[] = _T("Usage:\r\n\r\nselfdel [options]\r\n\r\nOptions:\r\n-u (Uninstall)\r\n-pid Pid\r\n-exe Path"); TCHAR szError1[] = _T("Failed to open process [%u]"); TCHAR szDeleting[] = _T("Deleting:\r\n\r\n%s"); int _tatoi(TCHAR *num) { int n = 0; TCHAR *nptr = num; while(*nptr && IsCharAlphaNumeric(*nptr) && !IsCharAlpha(*nptr)) n = 10 * n + (*nptr++ - '0'); return n; } void MyZeroMem(void *mem, DWORD bytes) { BYTE *bptr = (BYTE *)mem; while(bytes--) *bptr++ = 0; } void CommitSuicide(void) { HANDLE hTemp; char szPath[MAX_PATH]; char szTemp[MAX_PATH]; char szBig [MAX_PATH*2 + 100]; STARTUPINFO si; PROCESS_INFORMATION pi; UINT ret; GetTempPath(MAX_PATH, szTemp); lstrcat(szTemp, "selfdel.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); MyZeroMem(&si, sizeof(STARTUPINFO)); MyZeroMem(&pi, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); wsprintf(szBig, "\"%s\" -pid %u -exe \"%s\"", szTemp, GetCurrentProcessId(), szPath); ret = CreateProcess(0, szBig, 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi); Sleep(100); CloseHandle(hTemp); } // void DeleteExe(DWORD dwPid, TCHAR *szPath) { HANDLE hProcess; TCHAR szErr[MAX_PATH+32]; hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, dwPid); if(hProcess == 0) { wsprintf(szErr, szError1, dwPid); MessageBox(0, szErr, szAppName, MB_OK|MB_ICONINFORMATION); return; } WaitForSingleObject(hProcess, INFINITE); CloseHandle(hProcess); DeleteFile(szPath); } TCHAR * GetNextArg(TCHAR *szPtr, TCHAR *szOut) { TCHAR *pOut = szOut; TCHAR ch = *szPtr++; if(ch == '\0') return 0; while(ch == ' ' || ch == '\t') { ch = *szPtr++; } if(ch == '\"') { ch = *szPtr++; while(ch && ch != '\"') { *szOut++ = ch; ch = *szPtr++; } *szOut = '\0'; return szPtr; } while(ch && ch != ' ' && ch != '\t') { *szOut++ = ch; ch = *szPtr++; } *szOut = '\0'; return szPtr; } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd) { DWORD dwProcessId; TCHAR *ptr; TCHAR buf[MAX_PATH]; ptr = lpCmdLine; ptr = GetNextArg(ptr, buf); if(lstrcmpi(buf, "-u") == 0) { CommitSuicide(); ExitProcess(0); return 0; } if(lstrcmpi(buf, "-pid") == 0) { ptr = GetNextArg(ptr, buf); dwProcessId = _tatoi(buf); ptr = GetNextArg(ptr, buf); if(lstrcmpi(buf, "-exe") == 0) { //exe-path specified - get the path ptr = GetNextArg(ptr, buf); DeleteExe(dwProcessId, buf); return 0; } else { return 1; } } else { return 1; } return 0; } int WINAPI WinMainCRTStartup() { UINT ret; TCHAR *pszCmdLine; TCHAR temp[MAX_PATH]; HINSTANCE hInst = GetModuleHandle(0); pszCmdLine = GetCommandLine(); pszCmdLine = GetNextArg(pszCmdLine, temp); ret = WinMain(hInst, 0, pszCmdLine, SW_SHOWNORMAL); if(ret != 0) { MessageBox(0, szUsage, szAppName, MB_OK|MB_ICONINFORMATION); } ExitProcess(ret); return 0; }
第五种
//利用系统环境变量实现
#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; }
原文地址:http://blog.csdn.net/microzone/article/details/38556529