Linux objdump Command with Practical Examples

LinuxLinuxBeginner
Practice Now

Introduction

In this lab, you will learn how to use the Linux objdump command, which is a powerful tool for analyzing the contents of object files. You will start by understanding the purpose of the objdump command, then explore its basic syntax and options, and finally analyze the output of objdump on a simple C program. This lab covers essential skills in the area of scripting and programming, and the knowledge gained can be applied to various software development and debugging tasks.

Linux Commands Cheat Sheet


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("`Linux`")) -.-> linux/PackagesandSoftwaresGroup(["`Packages and Softwares`"]) linux/PackagesandSoftwaresGroup -.-> linux/software("`Linux Software`") subgraph Lab Skills linux/software -.-> lab-422847{{"`Linux objdump Command with Practical Examples`"}} end

Understand the Purpose of objdump Command

In this step, you will learn about the purpose of the objdump command in Linux. The objdump command is a powerful tool used to analyze the contents of object files, which are binary files that contain machine code and other information.

The objdump command can be used to disassemble the machine code in an object file, which means it can translate the binary instructions into a human-readable format. This can be useful for understanding how a program works, debugging issues, or even reverse-engineering software.

Let's start by creating a simple C program and using objdump to analyze its contents.

First, create a new file called hello.c in the ~/project directory with the following content:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

Next, compile the program using the gcc compiler:

cd ~/project
gcc -o hello hello.c

Now, let's use the objdump command to analyze the contents of the hello executable:

objdump -d hello

Example output:

hello:     file format elf64-x86-64

Disassembly of section .init:

0000000000001000 <_init>:
    1000:   f3 0f 1e fa             endbr64
    1004:   48 83 ec 08             sub    $0x8,%rsp
    1008:   48 8b 05 d9 2f 00 00    mov    0x2fd9(%rip),%rax        ## 3fe8 <__gmon_start__>
    100f:   48 85 c0                test   %rax,%rax
    1012:   74 02                   je     1016 <_init+0x16>
    1014:   ff d0                   callq  *%rax
    1016:   48 83 c4 08             add    $0x8,%rsp
    101a:   c3                      retq

The objdump command disassembles the machine code in the hello executable, showing the low-level instructions that the processor will execute when the program runs. This can be useful for understanding how the program works and for debugging issues.

In the next step, you will explore the basic syntax and options of the objdump command.

Explore the Basic Syntax and Options of objdump

In this step, you will explore the basic syntax and options of the objdump command. The objdump command has a variety of options that allow you to customize the output and extract specific information from the object file.

Let's start by reviewing the basic syntax of the objdump command:

objdump [options] file

Here are some of the most common options for the objdump command:

  • -d or --disassemble: Disassemble the executable code.
  • -S or --source: Intermix source code with disassembly.
  • -t or --syms: Display the contents of the symbol table.
  • -x or --all-headers: Display all available header information.
  • -h or --section-headers: Display the contents of the section headers.

Let's try some of these options with the hello executable we created in the previous step:

## Display the disassembly with source code
objdump -dS hello

## Display the symbol table
objdump -t hello

## Display all available header information
objdump -x hello

Example output:

hello:     file format elf64-x86-64

Disassembly of section .text:

0000000000001000 <_init>:
    1000:   f3 0f 1e fa             endbr64
    1004:   48 83 ec 08             sub    $0x8,%rsp
    1008:   48 8b 05 d9 2f 00 00    mov    0x2fd9(%rip),%rax        ## 3fe8 <__gmon_start__>
    100f:   48 85 c0                test   %rax,%rax
    1012:   74 02                   je     1016 <_init+0x16>
    1014:   ff d0                   callq  *%rax
    1016:   48 83 c4 08             add    $0x8,%rsp
    101a:   c3                      retq

0000000000001020 <__libc_csu_init>:
    1020:   f3 0f 1e fa             endbr64
    1024:   41 57                   push   %r15
    1026:   4c 8d 3d 93 2c 00 00    lea    0x2c93(%rip),%r15        ## 3cc0 <__frame_dummy_init_array_entry>
    102d:   41 56                   push   %r14
    102f:   49 89 e6                mov    %rsp,%r14
    1032:   41 55                   push   %r13
    1034:   41 54                   push   %r12
    1036:   4c 8d 25 83 2c 00 00    lea    0x2c83(%rip),%r12        ## 3cc0 <__frame_dummy_init_array_entry>
    103d:   55                      push   %rbp
    103e:   48 8d 2d 83 2c 00 00    lea    0x2c83(%rip),%rbp        ## 3cc8 <__do_global_dtors_aux_fini_array_entry>
    1045:   53                      push   %rbx
    1046:   4c 29 e5                sub    %r12,%rbp
    1049:   48 83 ec 08             sub    $0x8,%rsp
    104d:   e8 ae fe ff ff          callq  f00 <_init>
    1052:   48 c1 fd 03             sar    $0x3,%rbp
    1056:   74 1f                   je     1077 <__libc_csu_init+0x57>
    1058:   31 db                   xor    %ebx,%ebx
    105a:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
    105f:   4c 89 f2                mov    %r14,%rdx
    1062:   4c 89 ee                mov    %r13,%rsi
    1065:   44 89 e7                mov    %r12d,%edi
    1068:   41 ff 14 df             callq  *(%r15,%rbx,8)
    106c:   48 83 c3 01             add    $0x1,%rbx
    1070:   48 39 dd                cmp    %rbx,%rbp
    1073:   75 ea                   jne    105f <__libc_csu_init+0x3f>
    1075:   48 83 c4 08             add    $0x8,%rsp
    1079:   5b                      pop    %rbx
    107a:   5d                      pop    %rbp
    107b:   41 5c                   pop    %r12
    107d:   41 5d                   pop    %r13
    107f:   41 5e                   pop    %r14
    1081:   41 5f                   pop    %r15
    1083:   c3                      retq

0000000000001084 <__libc_csu_fini>:
    1084:   f3 0f 1e fa             endbr64
    1088:   c3                      retq

0000000000001089 <main>:
    1089:   f3 0f 1e fa             endbr64
    108d:   55                      push   %rbp
    108e:   48 89 e5                mov    %rsp,%rbp
    1091:   bf 00 00 00 00          mov    $0x0,%edi
    1096:   e8 85 fe ff ff          callq  f20 <puts@plt>
    109b:   b8 00 00 00 00          mov    $0x0,%eax
    10a0:   5d                      pop    %rbp
    10a1:   c3                      retq
    10a2:   66 2e 0f 1f 84 00 00 00 00 00 nopw   %cs:0x0(%rax,%rax,1)
    10ac:   0f 1f 40 00             nopl   0x0(%rax)

Disassembly of section .fini:

00000000000010b0 <_fini>:
    10b0:   f3 0f 1e fa             endbr64
    10b4:   48 83 ec 08             sub    $0x8,%rsp
    10b8:   48 83 c4 08             add    $0x8,%rsp
    10bc:   c3                      retq

The output shows the disassembly of the hello executable, including the source code intermixed with the machine instructions. This can be very useful for understanding how the program works at a low level.

In the next step, you will analyze the output of objdump on the hello program in more detail.

Analyze the Output of objdump on a Simple C Program

In this final step, you will analyze the output of the objdump command in more detail, focusing on the hello program we created earlier.

Let's start by taking a closer look at the disassembly output:

objdump -d hello

Example output:

hello:     file format elf64-x86-64

Disassembly of section .text:

0000000000001089 <main>:
    1089:   f3 0f 1e fa             endbr64
    108d:   55                      push   %rbp
    108e:   48 89 e5                mov    %rsp,%rbp
    1091:   bf 00 00 00 00          mov    $0x0,%edi
    1096:   e8 85 fe ff ff          callq  f20 <puts@plt>
    109b:   b8 00 00 00 00          mov    $0x0,%eax
    10a0:   5d                      pop    %rbp
    10a1:   c3                      retq

The disassembly output shows the machine instructions that make up the main function of the hello program. Let's break down the instructions:

  1. f3 0f 1e fa: This is the endbr64 instruction, which is a security feature to prevent certain types of attacks.
  2. 55: This is the push %rbp instruction, which saves the base pointer register on the stack.
  3. 48 89 e5: This is the mov %rsp,%rbp instruction, which sets the base pointer to the current stack pointer.
  4. bf 00 00 00 00: This is the mov $0x0,%edi instruction, which sets the first argument (the file descriptor) to 0 for the puts function call.
  5. e8 85 fe ff ff: This is the callq f20 <puts@plt> instruction, which calls the puts function to print the "Hello, World!" message.
  6. b8 00 00 00 00: This is the mov $0x0,%eax instruction, which sets the return value of the main function to 0.
  7. 5d: This is the pop %rbp instruction, which restores the base pointer from the stack.
  8. c3: This is the retq instruction, which returns from the main function.

By understanding the disassembly output, you can gain a deeper understanding of how the hello program works at a low level. This can be especially useful for debugging issues or reverse-engineering software.

Summary

In this lab, you first learned about the purpose of the objdump command in Linux, which is a powerful tool used to analyze the contents of object files. You created a simple C program, compiled it, and then used objdump to disassemble the machine code in the executable, allowing you to understand how the program works at a low level. Next, you explored the basic syntax and options of the objdump command, which can be used to extract various types of information from object files, such as the symbol table, relocation information, and more. By the end of the lab, you had a good understanding of how to use objdump to analyze the contents of executable files on a Linux system.

Linux Commands Cheat Sheet

Other Linux Tutorials you may like