Wenn Sie sich für die Programmierung unter Linux interessieren und sich Ihre Arbeit um Compiler dreht, gibt es eine Handvoll Befehlszeilen-Dienstprogramme, die Sie kennen sollten. Ein solches Werkzeug ist objdump . In diesem Tutorial werden wir die Grundlagen dieses Befehls anhand einiger leicht verständlicher Beispiele besprechen.
Aber bevor wir das tun, ist es erwähnenswert, dass alle Beispiele hier auf einem Ubuntu 20.04 LTS-Rechner und auf Debian 10 getestet wurden.
Linux objdump-Befehl
Der Befehl objdump in Linux zeigt, wie der Name schon sagt, Informationen aus Objektdateien an. Es folgt die Syntax des Tools:
objdump OPTIONEN objfile ...
Und hier ist, was die Manpage dazu sagt:
objdump zeigt Informationen über eine oder mehrere Objektdateien an. Die Optionen steuern, welche speziellen
Informationen angezeigt werden. Diese Informationen sind hauptsächlich für Programmierer nützlich, die an den
Kompilierungswerkzeugen arbeiten, im Gegensatz zu Programmierern, die nur wollen, dass ihr Programm kompiliert und funktioniert.
objfile... sind die Objektdateien für geprüft werden. Wenn Sie Archive angeben, zeigt objdump
Informationen zu allen Mitgliedsobjektdateien an.
Im Folgenden finden Sie einige Beispiele im Q&A-Stil, die Ihnen eine noch bessere Vorstellung davon vermitteln sollen, wie objdump funktioniert.
Q1. Wie bringt man objdump dazu, den Inhalt der Dateikopfzeile anzuzeigen?
Dies kann mit der Befehlszeilenoption -f erfolgen.
Zum Beispiel:
objdump -f /bin/ls
Und hier ist die Ausgabe des obigen Befehls:
/bin/ls: Dateiformat elf64-x86-64
Architektur:i386:x86-64, Flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
Startadresse 0x00000000000067d0
So können Sie sehen, dass der Header-Inhalt von 'ls' in der Ausgabe angezeigt wurde.
Q2. Wie kann man objdump dazu bringen, objektformatspezifische Dateiheaderinhalte anzuzeigen?
Dies kann mit der Befehlszeilenoption -p erfolgen. Beispielsweise der folgende Befehl:
objdump -p /bin/ls
Erzeugte die folgende Ausgabe:
/ bin / ls:Dateiformat elf64-x86-64
Programmkopf:
PHDR off 0x0000000000000040 VADDR 0x0000000000000040 pAddr 0x0000000000000040 align 2 ** 3
filesz 0x00000000000001f8 MEMSZ 0x00000000000001f8 flags r-x
INTERP off 0x0000000000000238 VADDR 0x0000000000000238 pAddr 0x0000000000000238 align 2 ** 0
filesz 0x000000000000001c MEMSZ 0x000000000000001c flags r--
LOAD off 0x0000000000000000 VADDR 0x0000000000000000 pAddr 0x0000000000000000 align 2 ** 21
filesz 0x000000000001e6e8 MEMSZ 0x000000000001e6e8 flags r-x
LOAD off 0x000000000001eff0 VADDR 0x000000000021eff0 pAddr 0x000000000021eff0 align 2 ** 21
filesz 0x0000000000001278 MEMSZ 0x0000000000002570 flags rw-
DYNAMIC off 0x000000000001fa38 VADDR 0x000000000021fa38 pAddr 0x000000000021fa38 align 2 ** 3
filesz 0x0000000000000200 memsz 0x0000000000000200 flags rw-
NOTE off 0x0000000000000254 vaddr 0x 0000000000000254 pAddr 0x0000000000000254 align 2 ** 2
filesz 0x0000000000000044 MEMSZ 0x0000000000000044 Flaggen r--
EH_FRAME off 0x000000000001b1a0 VADDR 0x000000000001b1a0 pAddr 0x000000000001b1a0 align 2 ** 2
filesz 0x0000000000000884 MEMSZ 0x0000000000000884 Flaggen r -
STACK off 0x0000000000000000 VADDR 0x0000000000000000 pAddr 0x0000000000000000 align 2 ** 4
filesz 0x0000000000000000 MEMSZ 0x0000000000000000 Flaggen rw-
RELRO off 0x000000000001eff0 VADDR 0x000000000021eff0 pAddr 0x000000000021eff0 align 2 ** 0
filesz 0x0000000000001010 MEMSZ 0x0000000000001010 Flaggen r--
Dynamischer Abschnitt:
benötigte libselinux.so.1
benötigtes libc.so.6
init 0x00000000003758
Fini 0x000000000001636C
INIT_ARRAY 0x00000000021eff0
INIT_ARRAYSZ 0x0000000000000008
FINI_ARRAY 0x000000000021eff8
FINI_ARRAYSZ 0x0000000000000008 GNU_HASH 0x0000000000000298
STRTAB 0x0000000000001180
SYMTAB 0x0000000000000388
STRSZ 0x0000000000000682
SYMENT 0x0000000000000018
DEBUG 0x0000000000000000
PLTGOT 0x000000000021fc38
PLTRELSZ 0x0000000000000a68
PLTREL 0x0000000000000007
JMPREL 0x0000000000002cf0
RELA 0x00000000000019a0
RELASZ 0x0000000000001350
RELAENT 0x0000000000000018
FLAGS 0x0000000000000008
FLAGS_1 0x0000000008000001
Verneed 0x0000000000001930
Verneednum 0x0000000000000001
Versym 0x00000000001802
Relacount 0x000000000000c1
Versionsreferenzen:
Erforderlich von libc.soSo. 0,6:
0x06969194 0x00 07 GLIBC_2.14
0x0d696914 0x00 06 GLIBC_2.4
0x06969197 0x00 05 GLIBC_2.17
0x09691974 0x00 04 GLIBC_2.3.4
0x09691a75 0x00 03 GLIBC_2.2.5
0x0d696913 0x00 02 GLIBC_2.3
Q3. Wie bringt man objdump dazu, Inhalte von Abschnittsüberschriften anzuzeigen?
Dies kann mit der Befehlszeilenoption -h erfolgen. Beispielsweise der folgende Befehl:
objdump -h /bin/ls
erzeugte die folgende Ausgabe auf meinem System:
/bin /ls:Dateiformat ELF64-X86-64
Abschnitte:
idx Name Größe VMA LMA-Datei aus Algn
0 .Interp 0000001c 0000000000000238 00000000000238 00000238 2**** *0
Inhalt, Alloc, Load, Readonly, Daten
1 .note.abi-Tag 00000020 00000000000254 00000000000254 00000254 2 ** 2
Inhalt, Alloc, Last, readonly, Daten
2 .note.gnu.build-ID 00000024 0000000000000274 0000000000000274 00000274 2 ** 2
INHALT, ALLOC, LOAD, NURLESE-, DATA
3 .gnu.hash 000000ec 0000000000000298 0000000000000298 00000298 2 ** 3
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
4 .dynsym 00000df8 0000000000000388 0000000000000388 00.000.388 2 ** 3
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
5 .dynstr 00000682 0000000000001180 0000000000001180 00001180 2**0
INHALT, ZUTEIL , LOAD, nur lesbar, DATA
6 .gnu.version 0000012a 0000000000001802 0000000000001802 00.001.802 2 ** 1
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
7 .gnu.version_r 00.000.070 0000000000001930 0000000000001930 00.001.930 2 ** 3
Inhalt, Alloc, Load, Readonly, Daten
8 .rela.dyn 00001350 00000000000019A0 000000000019A0 000019A0 2 ** 3
Inhalte, Alloc, Last, Readonly, Daten
> 9 .rela.PLT 00000A68 0000000000002CF0 0000000000002CF0 00002CF0 2 ** 3
Inhalt, Alloc, Last, readonly, Daten
. , nur lesbar, CODE
11 .plt 00.000.700 0000000000003770 0000000000003770 00.003.770 2 ** 4
CONTENTS, ALLOC, LOAD, nur lesbar, CODE
12 .plt.got 00.000.018 0000000000003e70 0000000000003e70 00003e70 2 ** 3
INHALT, ALLOC, LOAD, nur lesbar, CODE
13 .text 000124d9 0000000000003e90 0000000000003e90 00003e90 2 ** 4
CONTENTS, ALLOC, LOAD, nur lesbar, CODE
14 .fini 00000009 000000000001636c 000000000001636c 0001636c 2 * *2
Inhalt, Alloc, Load, Readonly, Code
15 .Rodata 00004e1d 0000000000016380 00000000016380 00016380 2 ** 5
Inhalt, Alloc, Lade, Readonly, Daten
16 .Eh_frame_Frame_HDRE_RAME_HDREM. 00000884 000000000001b1a0 000000000001b1a0 0001b1a0 2 ** 2
INHALT, ALLOC, LOAD, NURLESE-, DATA
17 .eh_frame 00002cc0 000000000001ba28 000000000001ba28 0001ba28 2 ** 3
INHALT, ALLOC, LOAD, NURLESE-, DATA
18 .init_array 00000008 000000000021eff0 000000000021eff0 0001eff0 2 ** 3
Inhalt, Alloc, Last, Daten
19 .Fini_array 00000008 0000000021eff8 0000000021Eff8 0001eff8 2 ** 320 .data.rel * 3
CONTENTS, ALLOC, LOAD, DATA
22 .got 000003c8 000000000021fc38 000000000021fc38 0001fc38 2 ** 3
CONTENTS, ALLOC, LOAD, DATA
23 .data 00.000.268 0000000000220000 0000000000220000 00020000 2 ** 5
CONTENTS, ALLOC, LOAD, DATA
24 .bss 000012e0 0000000000220280 0000000000220280 00.020.268 2 ** 5
ALLOC
25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 00.020.268 2 ** 2
INHALT, NUR LESEN
Q4. Wie bringt man objdump dazu, alle Header anzuzeigen?
Um objdump alle Header anzeigen zu lassen, verwenden Sie die Befehlszeilenoption -x.
objdump -x /bin/ls
Es folgt die Ausgabe, die dieser Befehl auf meinem System erzeugt:
/bin/ls: Dateiformat elf64-x86-64
/bin/ls
Architektur:i386:x86-64, Flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
Adresse starten 0x0000000000005850
Programmkopf:
PHDR off 0x0000000000000040 VADDR 0x0000000000000040 pAddr 0x0000000000000040 align 2 ** 3
filesz 0x00000000000001f8 MEMSZ 0x00000000000001f8 Flaggen r-x
INTERP off 0x0000000000000238 VADDR 0x0000000000000238 pAddr 0x0000000000000238 align 2 ** 0
filesz 0x000000000000001c MEMSZ 0x000000000000001c flags r--
LOAD off 0x0000000000000000 VADDR 0x0000000000000000 pAddr 0x0000000000000000 align 2 ** 21
filesz 0x000000000001e6e8 MEMSZ 0x000000000001e6e8 flags r-x
LOAD off 0x000000000001eff0 VADDR 0x000000000021eff0 pAddr 0x000000000021eff0 align 2 ** 21
filesz 0x0000000000001278 MEMSZ 0x0000000000002570 Flaggen rw-
DYNAMIC off 0x000000000001fa38 VADDR 0x000000000021fa38 pAddr 0x000000000021fa38 ein lign 2 ** 3
filesz 0x0000000000000200 MEMSZ 0x0000000000000200 Flaggen rw-
HINWEIS off 0x0000000000000254 VADDR 0x0000000000000254 pAddr 0x0000000000000254 align 2 ** 2
filesz 0x0000000000000044 MEMSZ 0x0000000000000044 Flaggen r--
EH_FRAME off 0x000000000001b1a0 VADDR 0x000000000001b1a0 pAddr 0x000000000001b1a0 align 2 ** 2
filesz 0x0000000000000884 MEMSZ 0x0000000000000884 Flaggen r--
STACK off 0x0000000000000000 VADDR 0x0000000000000000 pAddr 0x0000000000000000 align 2 ** 4
filesz 0x0000000000000000 MEMSZ 0x0000000000000000 Flaggen rw-
Relro aus 0x000000000001eff0 VADDR 0x0000000021eff0 PADDR 0x000000000021eff0 Align 2 ** 0
filesz 0x00000000001010 memsz 0x00000000001010 Flags R-
dynamischem Abschnitt:
benötigte libselinux.1
/> ERFORDERLICH libc.so.6
INIT 0x0000000000003758
FINI 0x000000000001636c
INIT_ARRAY 0x000000000021eff0
INIT_ARRAYSZ 0x0000000000000008
FINI_ARRAY 0x000000000021eff8
FINI_ARRAYSZ 0x0000000000000008
GNU_HASH 0x0000000000000298
STRTAB 0x0000000000001180
SYMTAB 0x0000000000000388
STRSZ 0x0000000000000682
SYMENT 0x0000000000000018
DEBUG 0x0000000000000000 PLTGOT 0x000000000021fc38
PLTRELSZ 0x0000000000000a68
PLTREL 0x0000000000000007
JMPREL 0x0000000000002cf0
RELA 0x00000000000019a0
RELASZ 0x0000000000001350
RELAENT 0x0000000000000018
Flags 0x0000000000000008
Flags_1 0x0000000008000001
Verneed 0x00000000001930
Verneednum 0x00000000000001
Versym 0x0000000000001802
RELACOUNT 0x00000000000000c1
Version Referenzen:
von libc.so.6 erforderlich:
0x06969194 0x00 07 GLIBC_2.14
0x0d696914 0x00 06 GLIBC_2.4
0x06969197 0x00 05 GLIBC_2.17
0x09691974 0x00 04 GLIBC_2.3.4
0x09691a75 0x00 03 GLIBC_2.2.5
0x0d696913 2 0x00
idx Name Größe VMA LMA-Datei aus Algn
0 .Interp 0000001C 0000000000000238 00000000000238 00000238 2 ** 0
Inhalt, Alloc, Load, Readonly, Daten
1 .note.abi- Tag 00000020 0000000000000254 0000000000000254 00000254 2 ** 2
Inhalt, Alloc, Last, readonly,
2 .note , LOAD, READONLY, DATA
3 .gnu.hash 000000ec 0000000000000298 0000000000000298 00000298 2**3
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
4 .dynsym 00000df8 0000000000000388 0000000000000388 00.000.388 2 ** 3
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
5 .dynstr 00.000.682 0000000000001180 0000000000001180 00001180 2 ** 0
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
6 .gnu.version 0000012a 0000000000001802 0000000000001802 00.001.802 2 ** 1
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
7 .gnu.version_r 00.000.070 0000000000001930 0000000000001930 00.001.930 2 ** 3
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
8 .rela.dyn 00.001.350 00000000000019a0 00000000000019a0 000019a0 2 ** 3
CONTENTS , ALLOC, LOAD, nur lesbar, DATA
9 .rela.plt 00000a68 0000000000002cf0 0000000000002cf0 00002cf0 2 ** 3
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
10 .init 00.000.017 0000000000003758 0000000000003758 00003758 2 ** 2
Inhalt, Alloc, Load, Readonly, Code
11 .plt 00000700 00000000003770 0000000000003770 00003770 2 ** 4 12 .plt.got 00.000.018 0000000000003e70 0000000000003e70 00003e70 2 ** 3
CONTENTS, ALLOC, LOAD, nur lesbar, CODE
13 .text 000124d9 0000000000003e90 0000000000003e90 00003e90 2 ** 4
CONTENTS, ALLOC, LOAD CODE, READONLY,
14 .fini 00000009 000000000001636c 000000000001636c 0001636c 2 ** 2
CONTENTS, ALLOC, LOAD, nur lesbar, CODE
15 .rodata 00004e1d 0000000000016380 0000000000016380 00.016.380 2 ** 5
INHALT, ALLOC, LOAD, nur lesbar, DATA
16 .eh_frame_hdr 00.000.884 000000000001b1a0 000000000001b1a0 0001b1a0 2 ** 2
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
17 .eh_frame 00002cc0 000000000001ba28 00 0000000001ba28 0001ba28 2 ** 3
CONTENTS, ALLOC, LOAD, nur lesbar, DATA
18 .init_array 00000008 000000000021eff0 000000000021eff0 0001eff0 2 ** 3
CONTENTS, ALLOC, LOAD, DATA
19 .Fini_array 00000008 000000000021eff8 000000000021eff8 0001eff8 2 ** 3
Inhalt, Alloc, Last, Daten
20 .data.rel.ro 00000a38 00000021f000 000000000021F0001f000 2 ** 5 21 .Dynamisches 00000200 000000000021fa38 000000000021fa38 0001fa38 2 ** 3
CONTENTS, ALLOC, LOAD, DATA
22 .got 000003c8 000000000021fc38 000000000021fc38 0001fc38 2 ** 3
CONTENTS, ALLOC, LOAD DATA
23 .data 00.000.268 0000000000220000 0000000000220000 00020000 2 ** 5
CONTENTS, ALLOC, LOAD, DATA
24 .bss 000012e0 0000000000220280 0000000000220280 00.020.268 2 ** 5
ALLOC
25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 00020268 2**2
INHALT, NUR LESEN
SYMBOLTABELLE:
SYMBOLTABELLE:
F5. Wie bringt man objdump dazu, Assembler-Inhalte von ausführbaren Abschnitten anzuzeigen?
Verwenden Sie dazu die Befehlszeilenoption -d. Hier ist ein Beispiel, das diese Option in Aktion zeigt:
objdump -d /bin/lsUnd hier ist ein Auszug aus der Ausgabe:
/bin/ls: Dateiformat elf64-x86-64
Disassemblierung des Abschnitts .init:
0000000000003758 <[email protected]@Base> :
3758:48 83 EC 08 Sub $ 0x8,%RSP
375C:48 8B 05 7d C8 21 00 MOV 0x21C87D (%RIP),%RAX # 21FFE0 <__ GMON_START __>
3763:48 85 C0 Test%Rax,%Rax
3766:74 02 JE 376a <[E -Mail -Protected]@Base+0x12>
3768:ff D0 CALLQ *%RAX
376A:48 83 C4 08 add $0x8,%rsp
376e: c3 retq
Disassemblierung des Abschnitts .plt:
0000000000003770 <[email protected] <[email protected] 7 >::Ff 35 Ca C4 21 00 PUSPQ 0x21c4ca (%RIP) # 21fc40 <[E -Mail -geschützt]@Base+0x260>
3776:FF 25 CC C4 21 00 JMPQ *0x21C4CC (%RIP) # 21fc48 <[E -Mail Protected ]@Base+0x268>
377c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000003780 <[E-Mail-geschützt]>:
3780: ff 25 ca c4 21 00 jmpq *0x21c4ca(%rip) # 21fc50 <[E-Mail-geschützt]_0 0 0 6 : 00 00 pushq $0x0
378b: e9 e0 ff ff ff jmpq 3770 <[email protected]@Base+0x18>
0000000000003790 <[email protected]>:
FF 25 C2 C4 21 00 JMPQ *0x21c4c2 (%RIP) # 21fc58 <[E -Mail Protected] _2.2.5>
3796:68 01 00 00 00 pushq $ 0x1
379b:E9 D0 FF ff ff ff JMPQ $ 3770 <[email protected]@Base+0x18>
00000000000037a0 <[email protected]>:
37a0: ff 25 ba c4 21 00 jmpq *0x21c4ba(%rip) # 21fc60 <[ E-Mail-geschützt]_2.2.5>
37a6: 68 02 00 00 00 pushq $0x2In ähnlicher Weise können Sie die Befehlszeilenoption -D verwenden, damit objdump den Assembler-Inhalt aller Abschnitte anzeigt, und die Option -S, um sicherzustellen, dass das Tool den Quellcode mit der Disassemblierung vermischt.
Q6. Wie kann man objdump dazu bringen, Debug-Informationen anzuzeigen?
Dies kann durch Verwendung der Befehlszeilenoption -S ermöglicht werden.
objdump -g /bin/lsEs folgt ein Auszug aus der Ausgabe dieses Befehls:
Inhalt des Abschnitts .eh_frame (geladen aus /bin/ls):
00000000 0000000000000014 00000000 CIE
Version: 1
Erweiterung: "zR"
Codeausrichtungsfaktor:1
Datenausrichtungsfaktor:-8
Absenderadressenspalte:16
Erweiterungsdaten: 1b
DW_CFA_def_cfa:r7 (rsp) ofs 8
DW_CFA_OFFSET:R16 (RIP) bei CFA-8
dw_cfa_undefined:R16 (RIP)
00000018 000000000000000014 0000001C FDE CIE =000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005850- /> DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000030 0000000000000014 0000000000000014 00000000 CIE
Version: br > Erweiterung: "zR"
Codeausrichtungsfaktor:1
Datenausrichtungsfaktor:-8
Absenderadressenspalte:16
Erweiterungsdaten: 1b
DW_CFA_def_cfa:r7 ( rsp) ofs 8
DW_CFA_offset:r16 (rip) bei cfa-8F7. Wie bringt man objdump dazu, den Inhalt der Symboltabelle anzuzeigen?
Dies kann mit der Befehlszeilenoption -t erfolgen.
objdump -t /bin/lsSchlussfolgerung
Wir haben hier nur an der Oberfläche gekratzt, da der objdump-Befehl viele Befehlszeilenoptionen bietet. Sobald Sie diese geübt haben, können Sie mehr über das Tool erfahren, indem Sie zu seiner Manpage gehen.