Ich habe eine Binärdatei auf meinem System installiert und möchte die Demontage einer bestimmten Funktion untersuchen. Bevorzugt verwenden objdump
, aber auch andere Lösungen wären akzeptabel.
Aus diesen Fragen habe ich gelernt, dass ich möglicherweise einen Teil des Codes zerlegen kann, wenn ich nur die Grenzadressen kenne. Aus dieser Antwort habe ich gelernt, wie ich meine geteilten Debug-Symbole wieder in eine einzige Datei umwandle.
Aber selbst wenn ich mit dieser einzelnen Datei arbeite und sogar den gesamten Code zerlege (dh ohne Start- oder Stoppadresse, aber mit einfachen -d
Parametern objdump
), sehe ich dieses Symbol immer noch nirgendwo. Dies ist insofern sinnvoll, als die betreffende Funktion statisch ist und daher nicht exportiert wird. Trotzdem valgrind
wird der Funktionsname gemeldet, so dass er irgendwo gespeichert werden muss.
Wenn ich mir die Details der Debug-Abschnitte ansehe, finde ich diesen Namen im .debug_str
Abschnitt erwähnt, aber ich kenne kein Tool, das dies in einen Adressbereich verwandeln kann.
static
, wird sie möglicherweise vom Compiler in ihre Aufrufseiten eingefügt. Dies kann bedeuten , dass es nicht wirklich jede Funktion zu zerlegen sein kann, per se . Wenn Sie Symbole für andere Funktionen erkennen können, jedoch nicht für die gesuchte Funktion, ist dies ein starker Hinweis darauf, dass die Funktion eingebunden wurde. Valgrind verweist möglicherweise weiterhin auf die ursprüngliche vorinline-Funktion, da in den Debugging-Informationen der ELF-Datei gespeichert wird, woher jeder einzelne Befehl stammt, selbst wenn die Befehle an einen anderen Ort verschoben werden.addr2line
akzeptiert PCs / IPs vonstdin
und druckt die entsprechenden Quellcodezeilen aus. In ähnlicher Weiseobjdump -l
wird der objdump mit Quellzeilen gemischt; Für hochoptimierten Code mit starkem Inlining sind die Ergebnisse beider Programme jedoch nicht immer besonders hilfreich.Antworten:
Ich würde vorschlagen, gdb als einfachsten Ansatz zu verwenden. Sie können es sogar als Einzeiler tun, wie:
quelle
-ex 'command'
ist nicht inman gdb
!? Ist aber in der Tat in GDB-Dokumenten aufgeführt . Auch für andere/bin/ls
könnten Dinge wie entfernt werden. Wenn dieser genaue Befehl also nichts anzeigt, versuchen Sie es mit einem anderen Objekt! Kann auch Datei / Objekt als Bareword-Argument angeben. zBgdb -batch -ex 'disassemble main' /bin/ls
gdb /bin/ls -batch -ex 'disassemble main'
funktioniert auchcolumn -ts$'\t'
die GDB-Ausgabe filtern, sind die Rohbytes und Quellenspalten gut ausgerichtet. Auch-ex 'set disassembly-flavor intel'
vor anderen-ex
s wird in Inteler Montage Syntax führen.disassemble fn
mit der Methode angerufen . Es scheint jedoch, dass, wenn die Binärdatei mehrere Funktionen mit demselben Namen enthält, nur eine zerlegt wird. Ist es möglich, alle zu zerlegen, oder sollte ich sie anhand der Rohadresse zerlegen?gdb
disassemble/rs
, um auch Quell- und Rohbytes anzuzeigenMit diesem Format kommt es der
objdump -S
Ausgabe sehr nahe :Haupt c
Kompilieren und zerlegen
Demontage:
Getestet unter Ubuntu 16.04, GDB 7.11.1.
objdump + awk Workarounds
Drucken Sie den Absatz wie folgt aus: /unix/82944/how-to-grep-for-text-in-a-file-and-display-the-paragraph-that-has-the -Text
z.B:
gibt nur:
Bei der Verwendung
-S
gibt es meines Erachtens keinen ausfallsicheren Weg, da die Codekommentare eine mögliche Reihenfolge enthalten könnten ... Aber das Folgende funktioniert fast immer:angepasst von: So wählen Sie Linien zwischen zwei Markierungsmustern aus, die bei awk / sed mehrfach auftreten können
Antworten auf die Mailingliste
Auf der Mailingliste befindet sich ein Thread von 2010, der besagt, dass dies nicht möglich ist: https://sourceware.org/ml/binutils/2010-04/msg00445.html
Neben der
gdb
von Tom vorgeschlagenen Problemumgehung kommentieren sie auch eine andere (schlechtere) Problemumgehung beim Kompilieren, mit-ffunction-section
der eine Funktion pro Abschnitt erstellt und dann der Abschnitt ausgegeben wird.Nicolas Clifton gab ihm ein WONTFIX https://sourceware.org/ml/binutils/2015-07/msg00004.html , wahrscheinlich weil die GDB- Problemumgehung diesen Anwendungsfall abdeckt.
quelle
Zerlegen Sie eine einzelne Funktion mit Objdump
Ich habe zwei Lösungen:
1. Kommandozeilenbasiert
Diese Methode funktioniert perfekt und zusätzlich eine einfache. Ich benutze objdump mit dem Flag -d und leite es durch awk . Die zerlegte Ausgabe sieht aus wie
Zunächst beginne ich mit der Beschreibung der objdump-Ausgabe. Ein Abschnitt oder eine Funktion wird durch eine leere Zeile getrennt. Wenn Sie also den FS (Field Separator) in Newline und den RS (Record Separator) in Double Newline ändern, können Sie leicht nach Ihrer empfohlenen Funktion suchen, da diese einfach im $ 1-Feld zu finden ist!
Natürlich können Sie main durch jede andere Funktion ersetzen, die Sie drucken möchten.
2. Bash Script
Ich habe ein kleines Bash-Skript für dieses Problem geschrieben. Fügen Sie es ein, kopieren Sie es und speichern Sie es als zB Dasm- Datei.
Ändern Sie den x-access und rufen Sie ihn auf mit zB:
Dies ist viel schneller als das Aufrufen von gdb mit einem Skript. Neben der Art und Weise mit objdump wird nicht die Bibliotheken in den Speicher geladen werden und ist daher sicherer!
Vitaly Fadeev hat eine automatische Vervollständigung für dieses Skript programmiert, was wirklich eine nette Funktion ist und das Tippen beschleunigt.
Das Skript finden Sie hier .
quelle
objdump
odergdb
ist schneller. Für eine riesige Binärdatei (Firefox 'libxul.so)objdump
dauert es ewig, ich habe sie nach einer Stunde abgebrochen, während siegdb
weniger als eine Minute dauert.So vereinfachen Sie die Verwendung von awk zum Parsen der Ausgabe von objdump im Vergleich zu anderen Antworten:
quelle
Dies funktioniert genau wie die GDB-Lösung (da sie die Offsets gegen Null verschiebt), nur dass sie nicht verzögert ist (erledigt die Arbeit auf meinem PC in ca. 5 ms, während die GDB-Lösung ca. 150 ms dauert):
objdump_func:
quelle
awk
tut), die einzige Funktion in der Objektdatei ist, das heißt, selbst wenn die Funktion beispielsweise bei0x2d
der zweiten awk beginnt, wird sie in Richtung verschoben0x00
(durch Subtrahieren)0x2d
von der Adresse jeder Anweisung), was nützlich ist, da der Assembler-Code häufig Verweise auf den Start der Funktion enthält und wenn die Funktion bei 0 beginnt, müssen Sie die Subtraktionen nicht in Ihrem Kopf durchführen. Der awk-Code könnte besser sein, macht aber zumindest den Job und ist ziemlich effizient.-ffunction-sections
eine einfachere Möglichkeit zu sein, um sicherzustellen, dass jede Funktion bei 0 beginnt.Wenn Sie über sehr aktuelle Binutils (2.32+) verfügen, ist dies sehr einfach.
Wenn Sie
--disassemble=SYMBOL
an objdump übergeben, wird nur die angegebene Funktion zerlegt. Die Startadresse und die Endadresse müssen nicht übergeben werden.LLVM objdump hat auch eine ähnliche Option (
--disassemble-symbols
).quelle
Bash-Abschluss für
./dasm
Vollständige Symbolnamen für diese Lösung (D lang-Version):
dasm test
und dann drücken TabTab, erhalten Sie eine Liste aller Funktionen.dasm test m
und anschließendes Drücken werden TabTab alle Funktionen angezeigt, die mit m beginnen. Wenn nur eine Funktion vorhanden ist, wird diese automatisch vervollständigt.Datei
/etc/bash_completion.d/dasm
:quelle