Sich selbst zerstörende Exe
-
Hi,
Wie der Titel schon andeutet suche ich nach einer Möglichkeit die eigene Exe Datei zu löschen, während der Prozess ausgeführt wird. Ich habe schon die Möglichkeiten in "Windows Programmierung für Experten" durchgerabeitet, aber davon bin ich nicht so sehr begeistert. Auch eine DLL in einen anderen Prozess zu injizieren und so die Datei zu löschen, sobald der eigentliche Prozess beendet ist, erscheint mir nicht sehr schön. Könnt ihr mir sagen, was genau die Datei blockiert während ein Prozess aktiv ist? Ich dachte es könnte funktionieren, wenn man aus einer DLL heraus die Exe Datei aus dem Speicher herausmapped mit
UnmapViewOfFile((LPVOID)GetModuleHandle(0));
, was auch funktioniert, aber löschbar wird die Exe Datei damit leider trotzdem noch nicht!
-
Es gab mal irgendeinen Frickel-Assembler-Code, der zumindest unter Windows 2000 die Exe löschen konnte. Warum nicht einfach eine separate Exe-Datei in den User-Temp-Ordner "entpacken" (wie auch immer, als Ressource halten oder so) und starten, sich beenden und der Temp-Prozess löscht deine Exe-Datei sobald dein Prozess komplett hinüber ist?
-
Ein bißchen Suchfunktion schadet nicht
Z.B.: "Wie kann sich ein Programm selbst löschen?"
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39360-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.htmlMartin
-
Ah danke macher! Und kannst du mir noch sagen was dieser code macht:
#include <windows.h> 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; }
-
ps. und er funktionier auch gar nicht!
-
Probiers mal so
http://www.bytesandmore.de/rad/index.htm?http://www.bytesandmore.de/rad/cpp/snipp/sc06006.php
-
Oder auch
bool DestroyMe() { // For the full duration of "timeout", the deletion-program tries to delete our (this) exe-file. // This is needed since it may take a second or so for Windows to mark our exe as "not-in-use" and // our program may need a little time to exit. static const short timeout = 2000; static unsigned char exe_data[1024] = { 77, 90, 144, 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 14, 31, 186, 14, 0, 180, 9, 205, 33, 184, 1, 76, 205, 33, 84, 104, 105, 115, 32, 112, 114, 111, 103, 114, 97, 109, 32, 99, 97, 110, 110, 111, 116, 32, 98, 101, 32, 114, 117, 110, 32, 105, 110, 32, 68, 79, 83, 32, 109, 111, 100, 101, 46, 13, 13, 10, 36, 0, 0, 0, 0, 0, 0, 0, 145, 171, 72, 222, 213, 202, 38, 141, 213, 202, 38, 141, 213, 202, 38, 141, 22, 197, 123, 141, 214, 202, 38, 141, 213, 202, 39, 141, 208, 202, 38, 141, 242, 12, 72, 141, 212, 202, 38, 141, 242, 12, 94, 141, 212, 202, 38, 141, 82, 105, 99, 104, 213, 202, 38, 141, 0, 0, 0, 0, 0, 0, 0, 0, 80, 69, 0, 0, 76, 1, 1, 0, 79, 117, 197, 72, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 3, 1, 11, 1, 8, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 16, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 0, 64, 0, 0, 16, 0, 0, 0, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 4, 0, 0, 16, 0, 0, 16, 0, 0, 0, 0, 16, 0, 0, 16, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 16, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 116, 101, 120, 116, 0, 0, 0, 62, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 16, 0, 0, 0, 17, 0, 0, 14, 17, 0, 0, 30, 17, 0, 0, 232, 16, 0, 0, 0, 0, 0, 0, 86, 255, 21, 12, 16, 64, 0, 139, 240, 133, 246, 117, 2, 94, 195, 138, 6, 60, 34, 117, 38, 70, 138, 6, 132, 192, 116, 17, 60, 34, 116, 7, 70, 138, 6, 132, 192, 117, 245, 128, 62, 0, 116, 1, 70, 128, 62, 32, 116, 250, 235, 19, 60, 32, 116, 9, 70, 138, 6, 132, 192, 117, 245, 235, 1, 70, 128, 62, 32, 116, 250, 83, 139, 29, 8, 16, 64, 0, 87, 255, 211, 139, 248, 129, 199, LOBYTE(timeout), HIBYTE(timeout), 0, 0, 235, 33, 86, 255, 21, 4, 16, 64, 0, 133, 192, 117, 34, 255, 21, 0, 16, 64, 0, 131, 248, 5, 117, 17, 104, 250, 0, 0, 0, 255, 21, 16, 16, 64, 0, 255, 211, 59, 199, 114, 217, 51, 192, 95, 91, 94, 195, 51, 192, 64, 235, 247, 204, 204, 204, 208, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 17, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 16, 0, 0, 0, 17, 0, 0, 14, 17, 0, 0, 30, 17, 0, 0, 232, 16, 0, 0, 0, 0, 0, 0, 86, 3, 83, 108, 101, 101, 112, 0, 113, 1, 71, 101, 116, 76, 97, 115, 116, 69, 114, 114, 111, 114, 0, 0, 131, 0, 68, 101, 108, 101, 116, 101, 70, 105, 108, 101, 65, 0, 223, 1, 71, 101, 116, 84, 105, 99, 107, 67, 111, 117, 110, 116, 0, 0, 16, 1, 71, 101, 116, 67, 111, 109, 109, 97, 110, 100, 76, 105, 110, 101, 65, 0, 75, 69, 82, 78, 69, 76, 51, 50, 46, 100, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Get temp-directory TCHAR temp_path[MAX_PATH*2+2] = { 0 }; if ( ! GetTempPath( MAX_PATH+1, temp_path ) ) return false; // Cut off trailing backslash if ( lstrlen(temp_path ) ) temp_path[lstrlen(temp_path)] = '\0'; // Let windows create a unique temp-file-name TCHAR temp_file_name[MAX_PATH+2] = { 0 }; if ( ! GetTempFileName( temp_path, TEXT("aaa"), 0, temp_file_name ) ) return false; lstrcat( temp_file_name, TEXT(".exe") ); // Create exe-file std::ofstream o( temp_file_name, std::ios_base::binary ); o.write( reinterpret_cast<char*>(&exe_data[0]), sizeof(exe_data) ); o.close(); // Get the path from our application TCHAR this_path[MAX_PATH+2]; GetModuleFileName( NULL, this_path, MAX_PATH+1 ); // Execute the deletion-program return reinterpret_cast<int>(ShellExecute( NULL, TEXT("open"), temp_file_name, this_path, NULL, SW_HIDE )) > 32; }
Ich hatte einfach mal ein wenig rumprobiert. Der Datensatz ist der Inhalt einer Exe-Datei zu diesem Programm (dazu verkleinert):
#include <windows.h> int __cdecl WinMainCRTStartup() { static const DWORD DEL_TIMEOUT = 2500; static const DWORD DEL_ERROR = ERROR_ACCESS_DENIED; const char* cmdline = GetCommandLine(); if ( ! cmdline ) return 0; if ( *cmdline == '\"' ) { cmdline++; while ( *cmdline && *cmdline!='\"' ) cmdline++; if ( *cmdline ) cmdline++; while ( *cmdline == ' ' ) cmdline++; } else { while ( *cmdline && *cmdline!=' ' ) cmdline++; while ( *cmdline == ' ' ) cmdline++; } const DWORD start = GetTickCount(); const DWORD end = start + DEL_TIMEOUT; while ( GetTickCount() < end ) { if ( DeleteFile( cmdline ) ) return 1; if ( GetLastError() != DEL_ERROR ) break; Sleep( 250 ); } return 0; }
Das ergab ne Exe-Datei von 1024 Byte, die ich mit
std::ifstream f( "C:/Users/it-kassel/Documents/Visual Studio 2005/Projects/TTTTest/release/TTTTest.exe", std::ios_base::binary ); unsigned char buf[1024]; f.read( (char*)buf, 1024 ); std::ofstream out( "C:/asm.txt" ); out << "static const unsigned char file[1024] = { "; for ( int i=0; i<1024; i++ ) { out << static_cast<int>(buf[i]) << ", "; }
zu 'nem Array konvertiert hab, hab ja keine Lust die Bytes alle einzeln aus'm Ressourcen-Editor abzutippen
Ich wollt's mal hier vorstellen, weil es relativ portabel und vergleichsweise sein sollte, ähnlich der Batch-Datei.