fstream.write schreibt nicht alles



  • Hallo,

    seit einigen Stunden quäle ich mich jetzt mit einem Problem rum bei dem ich überhaupt nicht weiter komme.

    Ich möchte gerne eine EXE-Datei patchen so dass sie als erstes von mir bestimmten Code ausführt um eine DLL zu laden. Hier mal der Code:

    #include <iostream>
    #include <fstream>
    
    int main()
    {
    	std::fstream game;
    
    	constexpr unsigned int offset_entry = 0x00282985;
    	constexpr char call_codecave[] = { 0xE8, 0x06, 0xCE, 0xDA, 0xFF }; // call game.42F790
    
    	constexpr unsigned int offset_string = 0x002D412C;
    	constexpr char dll_name[] = { 0x64, 0x75, 0x6D, 0x6D, 0x79, 0x2E, 0x64, 0x6C, 0x6C, 0x00 }; // asci "dummy.dll\0"
    
        constexpr unsigned int offset_codecave = 0x0002F790;
    	constexpr char codecave[] = { 0x68, 0x2C, 0x41, 0x6D, 0x00, 0xFF, 0x15, 0x44, 0xC1, 0x6C, 0x00, 0xE8, 0x05, 0xD1, 0x25, 0x00, 0xC3, 0x90, 0x90, 0x90,  // 20 bytes
    						0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // 45 bytes bis hier
    		                0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; // 67 bytes gesamt
    	/* 
    		push game.6D412C 
    		call dword ptr ds:[<&LoadLibraryA>]
    		call game.68C8A5
    		ret
    
    		...viele nops weil eine bereits existierende Funktion komplett überschrieben werden soll
    	*/
    
    	game.open("Game.exe", std::fstream::in | std::fstream::out | std::fstream::binary);
    
    	if (!game.is_open())
    	{
    		std::cerr << "could not open Game.exe\n";
    		return 1;
    	}
    
    	// überschreibe den ersten call im Ziel mit einem call zu unserem Code
    	game.seekg(offset_entry);
    	game.write(call_codecave, sizeof(call_codecave)); // sizeof(call_codecave) == 5
    
    	// überschreibe einen String im Ziel der nicht benötigt wird mit dem Namen unserer dll
    	game.seekg(offset_string);
    	game.write(dll_name, sizeof(dll_name)); // sizeof(dll_name) == 10
    
    	// schreibe den Code der die dummy.dll läd und die Kontrolle wieder an das Ziel übergibt
    	game.seekg(offset_codecave);
    	game.write(codecave, sizeof(codecave)); // sizeof(codecave) == 67 aber es werden nur 43 bytes geschrieben
    
    	// fertig
    	game.close();
    
        return 0;
    }
    

    Und es funktioniert sogar...irgendwie.

    Aber beim letzten Schreibzugriff in Zeile 45 wo meine "Codecave" geschrieben werden soll, werden statt der erwarteten 67 Bytes immer nur 43 geschrieben.
    Kann mir jemand sagen woran das liegt?

    Vielen Dank voraus!



  • Auch wenn es mit C++ nicht direkt was zu tun hat, hier mal ein kleines Update damit ihr auch was zum Lachen habt:

    Selbstverständlich lag der Fehler bei mir was ich auch schon befürchtet hatte als ich das Thema erstellte.

    Um es kurz zu fassen: ich muss nicht 67 Bytes schreiben sondern 0x67 Bytes 😕
    Achja 67 Dezimal == 43 Hexadezimal.

    Schönen Abend noch


Anmelden zum Antworten