Objdump

Aus C und Assembler mit Raspberry

objdump ist ein mächtiges Werkzeug aus der GNU-Binutils-Suite, das verwendet wird, um verschiedene Informationen über Objektdateien, ausführbare Dateien und Bibliotheken anzuzeigen. Es ermöglicht dir, maschinenlesbare Dateien wie Objektdateien, ausführbare Dateien und Bibliotheken in eine für Menschen verständlichere Form zu konvertieren. Mit `objdump` kannst du u.a. Disassemblierungen vornehmen, Symbole auflisten und den Inhalt von Speichersegmenten anzeigen.

Hauptfunktionen von `objdump`

Disassemblierung von Maschinencode:

  • `objdump` kann den Maschinencode einer ausführbaren Datei oder einer Objektdatei in Assemblersprache zurückübersetzen. Dies ist nützlich, wenn du den generierten Code überprüfen möchtest.
  • Die grundlegende Verwendung zum Disassemblieren sieht so aus:
objdump -d meinprogramm
Der Befehl zeigt den Assemblercode der Datei an, einschließlich der Maschinenadressen und der entsprechenden Opcodes.

Anzeigen von Header-Informationen:

  • `objdump` kann die Header einer Datei ausgeben, z.B. den ELF (Executable and Linkable Format)-Header, der die Struktur und das Layout der ausführbaren Datei oder Objektdatei beschreibt.
  • Mit dem Befehl:
objdump -h meinprogramm
wird eine Liste der verschiedenen Abschnitte (Sections) der Datei angezeigt. Dies enthält Informationen über den Speicherort jedes Abschnitts und dessen Größe.

Liste der Symbole:

  • Du kannst eine Liste aller Symbole anzeigen, die in einer Objektdatei oder ausführbaren Datei definiert oder referenziert werden. Dies ist hilfreich, um zu sehen, welche Funktionen oder Variablen verwendet werden.
  • Symbole werden mit dem Befehl aufgelistet:
objdump -t meinprogramm
Dadurch wird eine Symboltabelle mit den Symbolnamen, ihren Typen (z.B. Funktionen, Variablen) und Adressen ausgegeben.

Anzeigen der Relokationen:

  • Relokationseinträge geben an, welche Speicheradressen zur Laufzeit angepasst werden müssen, wenn die Objektdatei mit anderen Dateien verknüpft wird. Du kannst die Relokationseinträge wie folgt anzeigen:
objdump -r meinprogramm

Anzeigen von Debugging-Informationen:

  • Wenn eine Datei mit Debugging-Informationen kompiliert wurde (z.B. mit `-g`), kannst du mit `objdump` diese Informationen anzeigen lassen:
objdump --debugging meinprogramm
Das ist nützlich, um mehr Details zu sehen, die beim Debugging hilfreich sind, wie Variablen und Quellcode-Zeileninformationen.

Anzeigen von dynamischen Symbolen und Bibliotheken:

  • `objdump` kann auch dynamische Symbole (z.B. Symbole aus Shared Libraries) und Abhängigkeiten von dynamischen Bibliotheken anzeigen:
objdump -T meinprogramm
Hierdurch wird die Liste der dynamischen Symbole angezeigt, die während der Laufzeit aufgelöst werden müssen.
  • Du kannst auch die dynamischen Bibliotheksabhängigkeiten mit dem Befehl `-p` anzeigen:
objdump -p meinprogramm

Wichtige Optionen von `objdump`

Hier sind einige der am häufigsten verwendeten Optionen von `objdump`:

  • -d, --disassemble: Disassembliert den Code und zeigt den Assemblercode an.
  • -h, --section-headers: Listet alle Abschnitte der Datei auf und zeigt Informationen zu deren Größe und Speicherort.
  • -S, --source: Zeigt den disassemblierten Code zusammen mit dem Quellcode an (falls verfügbar).
  • -t, --syms: Zeigt die Symboltabelle an.
  • -T, --dynamic-syms: Zeigt dynamische Symbole (d.h. Symbole, die zur Laufzeit aufgelöst werden) an.
  • -r, --reloc: Zeigt die Relokationseinträge an, die für das Verknüpfen notwendig sind.
  • -p, --private-headers: Zeigt private Header-Informationen an (z.B. dynamische Bibliotheksabhängigkeiten).
  • -g, --debugging: Zeigt Debugging-Informationen an, wenn sie verfügbar sind.
  • -x, --all-headers: Zeigt alle verfügbaren Header der Datei an, einschließlich der ELF-Header, Abschnitts-Header und Program-Header.

Beispielverwendung

Nehmen wir an, du hast eine kompilierte C-Datei `meinprogramm` und möchtest verschiedene Informationen über sie herausfinden:

Disassemblierung:

objdump -d meinprogramm
Dieser Befehl zeigt den vollständigen Assemblercode der Datei an, sodass du den generierten Maschinencode sehen kannst.

Symboltabelle anzeigen:

   objdump -t meinprogramm
Dieser Befehl zeigt alle Symbole (wie Funktionen und Variablen) und ihre Adressen in der Datei an.

Relokationen anzeigen:

objdump -r meinprogramm
Dieser Befehl zeigt Relokationseinträge an, die beim Verknüpfungsvorgang verwendet werden, um Adressen dynamisch zu aktualisieren.

Abschnitte anzeigen:

objdump -h meinprogramm
Hiermit wird eine Liste der Abschnitte (z.B. `.text`, `.data`, `.bss`) und ihre Speicherpositionen ausgegeben.

Typische Abschnitte in einer Objektdatei oder einer ausführbaren Datei

  1. .text: Dieser Abschnitt enthält den ausführbaren Maschinencode des Programms.
  2. .data: Hier werden initialisierte globale und statische Variablen gespeichert.
  3. .bss: Dieser Abschnitt enthält uninitialisierte globale und statische Variablen, die zur Laufzeit auf Null gesetzt werden.
  4. .rodata: Dieser Abschnitt enthält schreibgeschützte Daten wie Konstanten und String-Literale.
  5. .rel.text und .rel.data: Diese Abschnitte enthalten die Relokationseinträge für den Code- und Datensegment.

Anwendungsbeispiele

  • Reverse Engineering: Da `objdump` den Maschinencode disassemblieren kann, wird es oft verwendet, um zu analysieren, wie ein Programm auf Maschinenebene funktioniert. Dies ist nützlich bei der Fehlerbehebung oder bei der Analyse unbekannter Binärdateien.
  • Fehlersuche bei der Verknüpfung: Wenn der Linker Probleme meldet, wie z.B. nicht gefundene Symbole, kann `objdump` verwendet werden, um die Objektdateien und Bibliotheken zu analysieren und festzustellen, ob alle benötigten Symbole vorhanden sind.
  • Optimierungen analysieren: Entwickler können `objdump` verwenden, um den von einem Compiler erzeugten Code zu untersuchen und zu sehen, wie gut der Code optimiert wurde.

Fazit

GNU `objdump` ist ein unverzichtbares Tool für Entwickler und Systemprogrammierer, das es ermöglicht, tiefgehende Informationen über ausführbare Dateien, Objektdateien und Bibliotheken zu erhalten. Ob beim Debugging, der Fehleranalyse oder dem Reverse Engineering – `objdump` bietet eine Vielzahl von Funktionen, um Maschinencode und Dateistrukturen verständlicher zu machen.