Wie finden Sie die main-Funktion ist der Einstiegspunkt der elf-executable-Datei, ohne jede symbolische Informationen?
Entwickelte ich ein kleines cpp-Programm auf der Plattform von Ubuntu-Linux 11.10.
Jetzt möchte ich mittels reverse-Engineering es. Ich bin Anfänger. Ich solche tools verwenden: GDB 7.0, hte-editor, hexeditor.
Für das erste mal habe ich es ziemlich einfach. Mit Hilfe von symbolischen Informationen, die ich gegründet die Adresse der main-Funktion und gemacht alles, was ich brauchte.
Dann habe ich gestreift (--strip-all
) ausführbare elf-Datei und ich habe einige Probleme.
Ich weiß, dass main
Funktion startet von 0x8960 in diesem Programm.
Aber ich habe keine Ahnung, wie sollte ich diesen Punkt zu finden, ohne dieses wissen.
Ich habe versucht, meine debug das Programm Schritt für Schritt mit gdb aber es geht in __libc_start_main
dann in die ld-linux.so.3
(also, er findet und lädt die shared libraries benötigt ein Programm). Ich gedebuggt es etwa 10 Minuten. Natürlich, kann in 20 Minuten kann ich erreichen, die wichtigste Funktion ist der Einstiegspunkt, aber es scheint, dass die einfache Möglichkeit hat, zu existieren.
Was sollte ich tun, um zu finden, die main
- Funktion ist der Einstiegspunkt, ohne jegliche symbolische info?
Könnten Sie mir raten, ein paar gute Bücher/Webseiten/other_sources von reverse-engineering von elf-Dateien mit Hilfe von gdb?
Jede Hilfe würde geschätzt werden.
- (ld-linux.so ist nicht der kernel, es ist der dynamische linker im user-space.)
- Mat, Ok, ich bin nicht dagegen, aber die Frage ist die gleiche.
- Ich denke, glibc auf x86 schiebt
main()
's Adresse vor dem Aufruf__libc_start_main
auf_start
. Zumindest ist es nicht lange her. - Ja, Sie haben Recht! Habe ich auch schon gefunden es gestern so. 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Auffinden
main()
in eine abgespeckte Linux-ELF-binary ist einfach. Kein symbol-Informationen erforderlich ist.Den Prototyp für
__libc_start_main
istDen runtime-Speicher-Adresse von
main()
ist das entsprechende argument wird dem ersten parameter,int (*main) (int, char**, char**)
. Dies bedeutet, dass die Letzte Speicheradresse gespeichert, die auf dem Laufzeit-stack vor dem Aufruf__libc_start_main
ist die Speicher-Adresse vonmain()
, da Argumente drückte auf den Laufzeit-stack in umgekehrter Reihenfolge zu Ihrer entsprechenden Parameter in der Funktionsdefinition.Kann man geben
main()
imgdb
in 4 Schritten:__libc_start_main
heißt_libc_start_main
continue
bis der break-Punkt fürmain()
geschlagenDer Prozess ist der gleiche für sowohl 32-bit und 64-bit-ELF-Binärdateien.
Eingabe
main()
an einem Beispiel, abgespeckte 32-bit-ELF-Binärdatei namens "test_32":Eingabe
main()
in einem Beispiel stripped 64-bit-ELF-Binärdatei namens "test_64":Eine detaillierte Behandlung der Programm-Initialisierung und-was geschieht, bevor
main()
heißt und wie manmain()
gefunden werden kann gefunden werden in Patrick Horgan ' s tutorial "Linux-x86-Programm Startenoder - Wie zum Teufel kommen wir zu main()?"
Soweit ich weiß, sobald ein Programm entfernt wurde, gibt es keinen einfachen Weg, um suchen Sie die Funktion, die das symbol
main
sonst hätte verwiesen.Dem Wert des symbols
main
ist nicht erforderlich für die Programm-start-up: im ELF-format, der start des Programms angegeben ist, die durch diee_entry
Feld der ELF-executable-headers. Dieses Feld normalerweise auf die C-Bibliothek von code für die Initialisierung, und nicht direkt anmain
.Während die C-Bibliothek von code für die Initialisierung nennt
main()
nachdem es eingerichtet hat, die C run-time-Umgebung, dies ist eine normale Funktion aufrufen, wird vollständig aufgelöst, zur link-Zeit.In einigen Fällen, Umsetzung-spezifische Heuristiken (d.h., die spezifischen Kenntnisse der Interna von der C-runtime) kann verwendet werden, um zu bestimmen, die Lage des
main
in eine abgespeckte ausführbare Datei. Allerdings bin ich mir nicht bewusst, eine portable Möglichkeit, dies zu tun.Wenn Sie haben eine sehr abgespeckte version, oder sogar ein binary gepackt wird, wie mit UPX, können Sie den gdb auf die harte Weise:
Und dann können Sie brechen es in GDB, wie:
und dann sehen Sie den Eintrag Anleitung:
Ich hoffe, es hilft