Comando objdump de Linux explicado para principiantes (7 ejemplos)

Comando objdump de Linux explicado para principiantes (7 ejemplos)

Si le gusta programar en Linux y su trabajo gira en torno a los compiladores, hay un puñado de utilidades de línea de comandos que debe tener en cuenta. Una de esas herramientas es objdump. En este tutorial, discutiremos los conceptos básicos de este comando utilizando algunos ejemplos fáciles de entender.

Pero antes de hacerlo, vale la pena mencionar que todos los ejemplos aquí se probaron en una máquina con Ubuntu 20.04 LTS y en Debian 10.

Comando objdump de Linux

El comando objdump en Linux, como sugiere su nombre, muestra información de archivos de objetos. La siguiente es la sintaxis de la herramienta:

objdump OPTIONS objfile ...

Y esto es lo que dice la página del manual al respecto:

objdump displays information about one or more object files.  The options control what particular 
information to display. This information is mostly useful to programmers who are working on the 
compilation tools, as opposed to programmers who just want their program to compile and work.
objfile... are the object files to be examined. When you specify archives, objdump shows
information on each of the member object files.

Los siguientes son algunos ejemplos de estilo de preguntas y respuestas que deberían darle una idea aún mejor de cómo funciona objdump.

Q1. ¿Cómo hacer que objdump muestre el contenido del encabezado del archivo?

Esto se puede hacer usando la opción de línea de comando -f.

Por ejemplo:

objdump -f /bin/ls

Y aquí está el resultado del comando anterior:

/bin/ls:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00000000000067d0

Entonces puede ver que el contenido del encabezado de ‘ls’ se mostró en la salida.

Q2. ¿Cómo hacer que objdump muestre contenido de encabezado de archivo específico en formato de objeto?

Esto se puede hacer usando la opción de línea de comando -p. Por ejemplo, el siguiente comando:

objdump -p /bin/ls

Produjo la siguiente salida:

/bin/ls:     file format elf64-x86-64
Program Header:
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 0x0000000000000254 paddr 0x0000000000000254 align 2**2
filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off    0x000000000001b1a0 vaddr 0x000000000001b1a0 paddr 0x000000000001b1a0 align 2**2
filesz 0x0000000000000884 memsz 0x0000000000000884 flags r--
STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off    0x000000000001eff0 vaddr 0x000000000021eff0 paddr 0x000000000021eff0 align 2**0
filesz 0x0000000000001010 memsz 0x0000000000001010 flags r--

Dynamic Section:
NEEDED               libselinux.so.1
NEEDED               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              0x0000000000001930
VERNEEDNUM           0x0000000000000001
VERSYM               0x0000000000001802
RELACOUNT            0x00000000000000c1

Version References:
required from libc.so.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. ¿Cómo hacer que objdump muestre el contenido de los encabezados de sección?

Esto se puede hacer usando la opción de línea de comando -h. Por ejemplo, el siguiente comando:

objdump -h /bin/ls

produjo el siguiente resultado en mi sistema:

/bin/ls:     file format elf64-x86-64
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
0 .interp       0000001c  0000000000000238  0000000000000238  00000238  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020  0000000000000254  0000000000000254  00000254  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024  0000000000000274  0000000000000274  00000274  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash     000000ec  0000000000000298  0000000000000298  00000298  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym       00000df8  0000000000000388  0000000000000388  00000388  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr       00000682  0000000000001180  0000000000001180  00001180  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version  0000012a  0000000000001802  0000000000001802  00001802  2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000070  0000000000001930  0000000000001930  00001930  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rela.dyn     00001350  00000000000019a0  00000000000019a0  000019a0  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.plt     00000a68  0000000000002cf0  0000000000002cf0  00002cf0  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init         00000017  0000000000003758  0000000000003758  00003758  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt          00000700  0000000000003770  0000000000003770  00003770  2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt.got      00000018  0000000000003e70  0000000000003e70  00003e70  2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text         000124d9  0000000000003e90  0000000000003e90  00003e90  2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini         00000009  000000000001636c  000000000001636c  0001636c  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .rodata       00004e1d  0000000000016380  0000000000016380  00016380  2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame_hdr 00000884  000000000001b1a0  000000000001b1a0  0001b1a0  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame     00002cc0  000000000001ba28  000000000001ba28  0001ba28  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .init_array   00000008  000000000021eff0  000000000021eff0  0001eff0  2**3
CONTENTS, ALLOC, LOAD, DATA
19 .fini_array   00000008  000000000021eff8  000000000021eff8  0001eff8  2**3
CONTENTS, ALLOC, LOAD, DATA
20 .data.rel.ro  00000a38  000000000021f000  000000000021f000  0001f000  2**5
CONTENTS, ALLOC, LOAD, DATA
21 .dynamic      00000200  000000000021fa38  000000000021fa38  0001fa38  2**3
CONTENTS, ALLOC, LOAD, DATA
22 .got          000003c8  000000000021fc38  000000000021fc38  0001fc38  2**3
CONTENTS, ALLOC, LOAD, DATA
23 .data         00000268  0000000000220000  0000000000220000  00020000  2**5
CONTENTS, ALLOC, LOAD, DATA
24 .bss          000012e0  0000000000220280  0000000000220280  00020268  2**5
ALLOC
25 .gnu_debuglink 00000034  0000000000000000  0000000000000000  00020268  2**2
CONTENTS, READONLY

Q4. ¿Cómo hacer que objdump muestre todos los encabezados?

Para hacer que objdump muestre todos los encabezados, use la opción de línea de comando -x.

objdump -x /bin/ls

El siguiente es el resultado que este comando produjo en mi sistema:

/bin/ls:     file format elf64-x86-64
/bin/ls
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000005850
Program Header:
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 0x0000000000000254 paddr 0x0000000000000254 align 2**2
filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off    0x000000000001b1a0 vaddr 0x000000000001b1a0 paddr 0x000000000001b1a0 align 2**2
filesz 0x0000000000000884 memsz 0x0000000000000884 flags r--
STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off    0x000000000001eff0 vaddr 0x000000000021eff0 paddr 0x000000000021eff0 align 2**0
filesz 0x0000000000001010 memsz 0x0000000000001010 flags r--

Dynamic Section:
NEEDED               libselinux.so.1
NEEDED               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              0x0000000000001930
VERNEEDNUM           0x0000000000000001
VERSYM               0x0000000000001802
RELACOUNT            0x00000000000000c1

Version References:
required from libc.so.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

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
0 .interp       0000001c  0000000000000238  0000000000000238  00000238  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020  0000000000000254  0000000000000254  00000254  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024  0000000000000274  0000000000000274  00000274  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash     000000ec  0000000000000298  0000000000000298  00000298  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym       00000df8  0000000000000388  0000000000000388  00000388  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr       00000682  0000000000001180  0000000000001180  00001180  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version  0000012a  0000000000001802  0000000000001802  00001802  2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000070  0000000000001930  0000000000001930  00001930  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rela.dyn     00001350  00000000000019a0  00000000000019a0  000019a0  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.plt     00000a68  0000000000002cf0  0000000000002cf0  00002cf0  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init         00000017  0000000000003758  0000000000003758  00003758  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt          00000700  0000000000003770  0000000000003770  00003770  2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt.got      00000018  0000000000003e70  0000000000003e70  00003e70  2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text         000124d9  0000000000003e90  0000000000003e90  00003e90  2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini         00000009  000000000001636c  000000000001636c  0001636c  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .rodata       00004e1d  0000000000016380  0000000000016380  00016380  2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame_hdr 00000884  000000000001b1a0  000000000001b1a0  0001b1a0  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame     00002cc0  000000000001ba28  000000000001ba28  0001ba28  2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .init_array   00000008  000000000021eff0  000000000021eff0  0001eff0  2**3
CONTENTS, ALLOC, LOAD, DATA
19 .fini_array   00000008  000000000021eff8  000000000021eff8  0001eff8  2**3
CONTENTS, ALLOC, LOAD, DATA
20 .data.rel.ro  00000a38  000000000021f000  000000000021f000  0001f000  2**5
CONTENTS, ALLOC, LOAD, DATA
21 .dynamic      00000200  000000000021fa38  000000000021fa38  0001fa38  2**3
CONTENTS, ALLOC, LOAD, DATA
22 .got          000003c8  000000000021fc38  000000000021fc38  0001fc38  2**3
CONTENTS, ALLOC, LOAD, DATA
23 .data         00000268  0000000000220000  0000000000220000  00020000  2**5
CONTENTS, ALLOC, LOAD, DATA
24 .bss          000012e0  0000000000220280  0000000000220280  00020268  2**5
ALLOC
25 .gnu_debuglink 00000034  0000000000000000  0000000000000000  00020268  2**2
CONTENTS, READONLY
SYMBOL TABLE:
no symbols

P5. ¿Cómo hacer que objdump muestre el contenido del ensamblador de las secciones ejecutables?

Para ello, utilice la opción de línea de comando -d. Aquí hay un ejemplo que muestra esta opción en acción:

objdump -d /bin/ls

Y aquí hay un extracto de la salida:

/bin/ls:     file format elf64-x86-64
Disassembly of section .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 <[email protected]@Base+0x12>
3768:    ff d0                    callq  *%rax
376a:    48 83 c4 08              add    $0x8,%rsp
376e:    c3                       retq

Disassembly of section .plt:

0000000000003770 <[email protected]>:
3770:    ff 35 ca c4 21 00        pushq  0x21c4ca(%rip)        # 21fc40 <[email protected]@Base+0x260>
3776:    ff 25 cc c4 21 00        jmpq   *0x21c4cc(%rip)        # 21fc48 <[email protected]@Base+0x268>
377c:    0f 1f 40 00              nopl   0x0(%rax)

0000000000003780 <[email protected]>:
3780:    ff 25 ca c4 21 00        jmpq   *0x21c4ca(%rip)        # 21fc50 <[email protected]_2.3>
3786:    68 00 00 00 00           pushq  $0x0
378b:    e9 e0 ff ff ff           jmpq   3770 <[email protected]@Base+0x18>

0000000000003790 <[email protected]>:
3790:    ff 25 c2 c4 21 00        jmpq   *0x21c4c2(%rip)        # 21fc58 <[email protected]_2.2.5>
3796:    68 01 00 00 00           pushq  $0x1
379b:    e9 d0 ff ff ff           jmpq   3770 <[email protected]@Base+0x18>

00000000000037a0 <[email protected]>:
37a0:    ff 25 ba c4 21 00        jmpq   *0x21c4ba(%rip)        # 21fc60 <[email protected]_2.2.5>
37a6:    68 02 00 00 00           pushq  $0x2

De manera similar, puede usar la opción de línea de comando -D para hacer que objdump muestre el contenido del ensamblador de todas las secciones, y la opción -S para asegurarse de que la herramienta mezcle el código fuente con el desensamblado.

P6. ¿Cómo hacer que objdump muestre información de depuración?

Esto puede hacerse posible usando la opción de línea de comandos -S.

objdump -g /bin/ls

El siguiente es un extracto de la salida producida por este comando:

Contents of the .eh_frame section (loaded from /bin/ls):
00000000 0000000000000014 00000000 CIE
Version:               1
Augmentation:          "zR"
Code alignment factor: 1
Data alignment factor: -8
Return address column: 16
Augmentation data:     1b
DW_CFA_def_cfa: r7 (rsp) ofs 8
DW_CFA_offset: r16 (rip) at cfa-8
DW_CFA_undefined: r16 (rip)

00000018 0000000000000014 0000001c FDE cie=00000000 pc=0000000000005850..000000000000587b
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop

00000030 0000000000000014 00000000 CIE
Version:               1
Augmentation:          "zR"
Code alignment factor: 1
Data alignment factor: -8
Return address column: 16
Augmentation data:     1b
DW_CFA_def_cfa: r7 (rsp) ofs 8
DW_CFA_offset: r16 (rip) at cfa-8

P7. ¿Cómo hacer que objdump muestre el contenido de la tabla de símbolos?

Esto se puede hacer usando la opción de línea de comando -t.

objdump -t /bin/ls

Conclusión

Acabamos de arañar la superficie aquí, ya que el comando objdump ofrece muchas opciones de línea de comandos. Una vez que haya terminado de practicar estos, puede obtener más información sobre la herramienta dirigiéndose a su página man.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *