Quote:Original post by Dizzy_exe
3. Inject yourself into another process and delete your program form there (complicated and dangerous)
The following works on NT based os (e.g. xp etc.) Not my code, found via quick google. Batch file would still be easier and less hassle
#include <windows.h>typedef UINT (WINAPI *WAIT_PROC)(HANDLE, DWORD); // WaitForSingleObjecttypedef BOOL (WINAPI *CLOSE_PROC)(HANDLE); // CloseHandletypedef BOOL (WINAPI *DELETE_PROC)(LPCTSTR); // DeleteFiletypedef VOID (WINAPI *EXIT_PROC)(DWORD); // ExitProcesstypedef DWORD (WINAPI *REMOTETHREAD)(LPVOID); // Our remote codetypedef struct{ WAIT_PROC fnWaitForSingleObject; CLOSE_PROC fnCloseHandle; DELETE_PROC fnDeleteFile; EXIT_PROC fnExitProcess; HANDLE hProcess; TCHAR szFileName[MAX_PATH];} INJECT;#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_stackPVOID GetFunctionAddr(PVOID func){ #ifdef _DEBUG // get address of function from the JMP <relative> instruction DWORD *offset = (BYTE *)func + 1; return (PVOID)(*offset + (BYTE *)func + 5); #else return func; #endif}BOOL SelfDelete(){ // Get process handle of the currently running as explorer HANDLE hRemoteProcess = NULL; 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, π)){ CloseHandle(pi.hThread); hRemoteProcess = pi.hProcess; } if(hRemoteProcess == NULL) return FALSE; // Allocate memory in remote process BYTE *code = (BYTE *)VirtualAllocEx(hRemoteProcess, 0, sizeof(INJECT) + 128, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(code == NULL){ CloseHandle(hRemoteProcess); return FALSE; }; // Setup remote structure INJECT *remote = (INJECT *)(code + 128); HMODULE hKernel32 = GetModuleHandle("kernel32.dll"); INJECT local; local.fnWaitForSingleObject = (WAIT_PROC)GetProcAddress(hKernel32, "WaitForSingleObject"); local.fnCloseHandle = (CLOSE_PROC)GetProcAddress(hKernel32, "CloseHandle"); local.fnExitProcess = (EXIT_PROC)GetProcAddress(hKernel32, "ExitProcess"); local.fnDeleteFile = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileA"); // Duplicate our own process handle for remote process to wait on HANDLE hCurProc = GetCurrentProcess(); DuplicateHandle(hCurProc, hCurProc, hRemoteProcess, &local.hProcess, 0, FALSE, DUPLICATE_SAME_ACCESS); // Find name of current executable GetModuleFileName(NULL, local.szFileName, MAX_PATH); // Write in code to execute, and the remote structure WriteProcessMemory(hRemoteProcess, code, GetFunctionAddr(RemoteThread), 128, 0); WriteProcessMemory(hRemoteProcess, remote, &local, sizeof(local), 0); // Execute the code in remote process DWORD dwThreadId = 0; HANDLE hThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (REMOTETHREAD)code, remote, 0, &dwThreadId); if(hThread != 0) CloseHandle(hThread); return TRUE;}