Etwas an eine Exe-Datei anhängen



  • Hallo Com,

    vielleicht hat jemand(der das hier liest) ja schon meine erste Frage(http://www.c-plusplus.net/forum/320626) gelesen.
    Eigentlich wollte ich diese Frage dort Posten, aber der Titel "Assembler - Eine Verständnissfrage" wäre denke verwirrend und ich hätte
    dann wahrscheinlich keine Antwort gekriegt.

    Ich wollte fragen, wie ich eine Funktion oder ähnliches ans Ende einer Exe anhängen kann. Ich möchte weniger wissen, womit ich das mache(HexEditor und co. weis ich).

    Kurz etwas, um meine Frage zu verdeutlichen:

    Zitat von rkhb aus meiner ersten Frage

    Das 004060E0 des Call-Aufrufs gehört zu einer Tabelle, in die Windows bei Programmstart die Sprungadressen zu den Betriebssystemaufrufen hineinschreibt.

    Genau da ist mein Problem. Wenn ich zum Beispiel ein zweites kleines Programm schreibe, es dann im HexE. öffne und kopiere,
    kann ich das dann doch nicht einfach in den HexCode des ersten Programms einfügen. Die Adressen der Funktionen des ersten & zweiten
    Programmes wären dann doch voll durcheinander und würden sich vielleicht sogar überschneiden, oder nicht.
    Ich finde keine Lösung zu diesem Problem, von daher frage ich hier. Kann man nicht vielleicht die Adressen des zweiten Programms manuell verändern?
    Oder sind diese in der Exe fest integriert und nicht veränderbar?

    Falls das obige nicht so verstäntlich ist, hier noch mal kurz zusammengefasst:
    Ich habe eine Exe, die nur folgendes macht:

    ...
    MessageBox(NULL, "Das ist der Text", "Titel", 0);
    ...
    

    Die zweite Exe macht folgendes:

    ...
    TextOut(hDC, 10, 10, "Zweiter Text", 13);
    ...
    

    Wie kann ich jetzt die zweite(oder Teile davon) in die erste einbauen?

    PS: Ich bin kein Skriptkiddi, der sich an irgendeinen Mist versucht. Ich lerne gerade Assembler und auch den Umgang mit dem HexEditor.
    Ich möchte die verschiedenen Möglichkeiten austesten, unter anderem, weil sie echt Spaß machen!



  • Kann mir denn keiner weiterhelfen?



  • Doch klar kann man dir weiterhelfen. Aber glaub mir du lernst tausendmal mehr wenn du dir das selber erarbeitest.

    Zuerst solltest du dich mit den grundlegenden Assemblerbefehlen vertraut machen, und zwar so dass du sie wirklich verstehst.
    Dann kannst du dir mal den Debugger wie z.B. OllyDbg hernehmen und dein Programm analysieren. Mit einem Debugger geht das VIEL besser als mit einem Disassembler. Und einen zusätzlichen Hexeditor kannst du dir sparen, ein guter Debugger reicht.

    Die Addressem für z.B. die MessageBox werden vom Loader des Betriebsystems in eine Tabelle der Exe eingetragen: Die Import Address Table (IAT). Der Call geht normalerweise einfach auf eine Addresse in der IAT, dort steht dann ein unbedingter Sprung der dann auf die MessageBox Funktion umleitet.

    D.h. wenn die einen zweiten MessageBox Aufruf einfügen willst musst du schauen an welcher Addresse in der IAT für die MessageBox steht.
    Einfach gesagt dann einfach die ensprechenden Parameter auf den Stack pushen, call auf die entsprechende Addresse und fertig.

    Allerdings kann sich diese Addresse bei einem Neustart des Programms ändern.
    Und du musst erst einmal den zusätzlichen call in den Code bringen. Dazu musst du wohl oder übel existierenden code überschreiben, das musst du so machen dass es das eigentliche programm nicht beschädigt 😉
    z.B. Code ans Ende anhängen, irgendwo im Programm Code rauskopieren, mit einen unbedingen Sprung ersetzen und ans ende deines Codes dann den alten Code einfügen..
    Achja und du wirst dich schwer tun zusätzliche Strings ins Datensegment zu bekommen, deshalb musst du Tricks anwenden die man z.B. in Shellcode verwendet.

    Wie du siehst ist das alles nicht so einfach wie du glaubst 😉



  • Doch klar kann man dir weiterhelfen. Aber glaub mir du lernst tausendmal mehr wenn du dir das selber erarbeitest.

    Das stimmt!

    Zuerst solltest du dich mit den grundlegenden Assemblerbefehlen vertraut machen, und zwar so dass du sie wirklich verstehst.

    Hab ich auch vor, doch auch wenn ich sie verstehe, beantwortet das nicht die Frage, wie man nachher code einbauen kann, ohne anderen zu ersetzen.
    Ich denke folgendes(bitte sag mir, ob das so richtig ist):

    Soweit ich das jetzt verstanden habe(OllyDbg), ist eine Exe in verschiedene Sektionen aufgeteilt(.data, .text...). Kann man dann nicht am Ende der Exe ein Call-Aufruf
    einbauen, der dann entsprechend der angegebenen Adresse in die entsprechende Sektion springt und sich die Funktion holt? Dann ist noch das
    Problem, das man dem Programm ja mitteilen muss, wann es zum eingebauten Call-Aufruf springen und den Code abarbeiten soll. Also geht es anscheinend nicht,
    ohne das man im Code etwas ersetzt? Das muss doch irgendwie hinzukriegen sein.

    Sag bescheid, falls ich einen Denkfehler habe.

    Die Addressem für z.B. die MessageBox werden vom Loader des Betriebsystems in eine Tabelle der Exe eingetragen: Die Import Address Table (IAT). Der Call geht
    normalerweise einfach auf eine Addresse in der IAT, dort steht dann ein unbedingter Sprung der dann auf die MessageBox Funktion umleitet.

    D.h. wenn die einen zweiten MessageBox Aufruf einfügen willst musst du schauen an welcher Addresse in der IAT für die MessageBox steht.
    Einfach gesagt dann einfach die ensprechenden Parameter auf den Stack pushen, call auf die entsprechende Addresse und fertig.

    Ja, aber was ist, wenn man eine Funktion einbauen will, die das Programm nicht benutzt? Kann man diese dann irgendwie zur Liste hinzufügen?

    Wie du siehst ist das alles nicht so einfach wie du glaubst 😉

    Geglaubt hab ich es nicht 😃



  • Geglaubt hab ich es nicht 😃

    Gut das ist ja schonmal was 😃

    Kann man dann nicht am Ende der Exe ein Call-Aufruf
    einbauen, der dann entsprechend der angegebenen Adresse in die entsprechende Sektion springt und sich die Funktion holt?

    Normal ist das alles andere als Linear. Im Header der Exe steht wo der Einstiegspunkt ist. Und das Ende der Main Funktion ist auch irgendwo mittendrin. Also hinten etwas anhängen kannst du vergessen. Allerdings gibts im Textsegment meistens ungenutze Teile, oder du reservierst neuen Speicher.

    Kann man diese dann irgendwie zur Liste hinzufügen

    Das wäre eine Möglichkeit, die IAT der PE neuschreiben. Geht allerdings nicht zur Runtime.
    Aber du kannst "LoadLIbraryA" und "GetProcAddress" zur dynamischen Auflösung verwenden. Falls diese auch nicht importiert werden wird schwierig. Entweder die Addresse hardcoden (spätestens nach nem Neustart ändert sie sich), oder sie irgendwie dynamisch finden. Und damit wären wir wieder bei Shellcode, da braucht man sowas.
    Würde aber hier zuweit führen, schau erstmal dass du es soweit verstehst 😉



  • Normal ist das alles andere als Linear

    Das ist mir bewusst.

    Im Header der Exe steht wo der Einstiegspunkt ist. Und das Ende der Main Funktion ist auch irgendwo mittendrin. Also hinten etwas anhängen kannst du vergessen.
    

    Ich meinte eigentlich sowas wie beim HexEditor, wo man am Ende beliebig viele Null-Bytes anhängen kann. Diese kann man ja dann sozusagen frei Coden. Mit "am Ende" meinte ich nicht das "Ende" des Programms, sondern des Codes.
    Das Programm(Assembler-Code) springt ja von Befehl zu Befehl(Call-Aufrufe und co.).
    Da könnte man doch teoretisch eine bestimmte stelle im Code so ändern, dass die Abarbeitung des Programms an der gewünschten Stelle(hinzugefügter Code am "ende") fortgesetzt wird.



  • Klar kannst du etwas "am Ende des Codes" anhängen. Allerdings gilt es erstmal das Ende des Codes zu lokalisieren.
    Dann kannst du die Exe neuschreiben, sämtliche Offsets anpassen usw.
    Hier die PE-Spezifikation, viel Spass beim durcharbeiten 😃



  • Ist jetzt zwar schon paar Tage her, aber ich habe noch ne Frage. Ich habe jetzt schon etwas mehr von Assembler gelernt und habe mich in OllyDbg eingearbeitet.

    DarkShadow44 schrieb
    ...Allerdings gibts im Textsegment meistens ungenutze Teile...

    Ja, diese habe ich auch für meine "Tests" benutzt, mit erfolg. Doch jetzt will ich mich mit dem Einfügen neuer Funktionen beschäftigen. Du hast dazu
    ja schon was geschrieben.

    DarkShadow44 schrieb

    Ich schrieb
    Kann man diese dann zur Liste hinzufügen

    Das wäre eine Möglichkeit, die IAT der PE neuschreiben. Geht allerdings nicht zur Runtime.
    Aber du kannst "LoadLIbraryA" und "GetProcAddress" zur dynamischen Auflösung verwenden. Falls diese auch nicht importiert werden wird schwierig.
    Entweder die Addresse hardcoden (spätestens nach nem Neustart ändert sie sich), oder sie irgendwie dynamisch finden.
    Und damit wären wir wieder bei Shellcode, da braucht man sowas.

    Zur IAT, wie könnte ich sie denn neu schreiben? Allerdings, wenn ich z.b. nur eine Funktion hinzufügen will, wäre es bestimmt nicht sinnvoll,
    die ganze IAT neu zu schreiben, oder?
    Kannst du mir auch noch ein bischen was zu "LoadLIbraryA" und "GetProcAddress" sagen? Geht das damit, könnte ich damit einfach die entsprechende Funktion
    aufrufen?

    Entweder die Addresse hardcoden (spätestens nach nem Neustart ändert sie sich), oder sie irgendwie dynamisch finden.

    Könntest du mir sagen, wie genau du es mit hardcoden meinst?



  • Ah sorry, hab übersehen dass du geantwortest hast. 😮

    Nein für eine Funktion finde ich das nicht sinnvoll. Falls du das machen willst, wie gesagt lies dir die PE_Specs durch. Dort steht wie eine Exe aufgebaut ist, auch wo und wie die IAT zu finden ist. Alternativ hier eine Erklärung der IAT.
    Du musst wie gesagt nur bedenken betreffende Offsets anzupassen wenn du etwas einfügst.

    HMODULE libray=LoadLibraryA("User32.dll");
    FARPROC addressMessageBoxA = GetProcAddress(library, "MessageBoxA");
    

    Das ganze natürlich in Assembler. Und statt "LoadLibraryA" musst du ein call auf die entsprechende Stelle (LoadLibraryA) in der IAT machen.

    Hardcoden ist z.B. "call 0x45454545" wenn die Addresse von MessageBoxA an Stelle 0x45454545 liegt.

    Das hättest du aber auch selber finden können 😃


Anmelden zum Antworten