Binary Analysis Fundamentals

In this post, I’ll explain and investigate the Executable and Linkable Format (ELF), which is the default binary format on Linux-based systems.

To make practices, I’ve written a simple copy.c source file and we will investigate this:

/**
* Copying…


This content originally appeared on DEV Community and was authored by Ahmet Can Gulmez

In this post, I'll explain and investigate the Executable and Linkable Format (ELF), which is the default binary format on Linux-based systems.

To make practices, I've written a simple copy.c source file and we will investigate this:

/**
 * Copying a file content to another one.
 */

#include "../linux.h"

#ifndef BUF_SIZE
#define BUF_SIZE  1024
#endif

void main(int argc, char *argv[])
{
   int inputFd, outputFd, openFlags;
   mode_t filePerms;
   ssize_t numRead;
   char buf[BUF_SIZE];

   if (argc != 3 || strcmp(argv[1], "--help") == 0)
      usage_error("Wrong command-line usage");

   /* Open input and output files */

   inputFd = open(argv[1], O_RDONLY);
   if (inputFd)
      syscall_error(); 

   openFlags = O_CREAT | O_WRONLY | O_TRUNC;
   filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
               S_IROTH | S_IWOTH;  /* rw-rw-rw- */

   outputFd = open(argv[2], openFlags, filePerms);
   if (outputFd == -1)
      syscall_error();

   /* Transfer data until we encounter end of input or an error */

   while ((numRead == read(inputFd, buf, BUF_SIZE)) > 0)
      if (write(outputFd, buf, numRead) != numRead)
         syscall_error();
   if (numRead == -1)
      syscall_error();

   if (close(inputFd) == -1)
      syscall_error();
   if (close(outputFd) == -1)
      syscall_error();

   exit(EXIT_SUCCESS);
}

Compile this program like this:

$ gcc copy.c -o copy -O0 -g

Binary Composition

Firstly, let's look at binary composition. A binary includes many headers, sections and areas that lets the CPU to run required machine instructions. Below is the 64-bit ELF binary layout:

Every ELF file starts with an executable header, which is just a structured series of bytes telling you that it's an ELF file, what kind of ELF file it is, and where in the file to find all the other contents. It is defined in /usr/include/elf.h and can be seen the executable header with readelf command:

$ readelf -h copy

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1160
  Start of program headers:          64 (bytes into file)
  Start of section headers:          17496 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         37
  Section header string table index: 36

The code and data in an ELF binary are logically divided into contiguous nonoverlapping chunks called sections. Sections don't have any predetermined structure; instead, the structure of each section varies depending on the contents. Every section is described by a section header, which denotes the properties of the section and allows you to locate the bytes belonging to the section. The section headers for all sections in the binary are contained in the section header table.

Typical ELF files that you'll find on a GNU/Linux system are organized into a series of standard sections. Let's see the section names of our binary.

$ readelf --sections --wide copy

There are 37 section headers, starting at offset 0x4458:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000318 000318 00001c 00   A  0   0  1
  [ 2] .note.gnu.property NOTE            0000000000000338 000338 000030 00   A  0   0  8
  [ 3] .note.gnu.build-id NOTE            0000000000000368 000368 000024 00   A  0   0  4
  [ 4] .note.ABI-tag     NOTE            000000000000038c 00038c 000020 00   A  0   0  4
  [ 5] .gnu.hash         GNU_HASH        00000000000003b0 0003b0 000028 00   A  6   0  8
  [ 6] .dynsym           DYNSYM          00000000000003d8 0003d8 000180 18   A  7   1  8
  [ 7] .dynstr           STRTAB          0000000000000558 000558 0000d3 00   A  0   0  1
  [ 8] .gnu.version      VERSYM          000000000000062c 00062c 000020 02   A  6   0  2
  [ 9] .gnu.version_r    VERNEED         0000000000000650 000650 000030 00   A  7   1  8
  [10] .rela.dyn         RELA            0000000000000680 000680 0000d8 18   A  6   0  8
  [11] .rela.plt         RELA            0000000000000758 000758 0000d8 18  AI  6  24  8
  [12] .init             PROGBITS        0000000000001000 001000 00001b 00  AX  0   0  4
  [13] .plt              PROGBITS        0000000000001020 001020 0000a0 10  AX  0   0 16
  [14] .plt.got          PROGBITS        00000000000010c0 0010c0 000010 10  AX  0   0 16
  [15] .plt.sec          PROGBITS        00000000000010d0 0010d0 000090 10  AX  0   0 16
  [16] .text             PROGBITS        0000000000001160 001160 00043a 00  AX  0   0 16
  [17] .fini             PROGBITS        000000000000159c 00159c 00000d 00  AX  0   0  4
  [18] .rodata           PROGBITS        0000000000002000 002000 000040 00   A  0   0  4
  [19] .eh_frame_hdr     PROGBITS        0000000000002040 002040 000034 00   A  0   0  4
  [20] .eh_frame         PROGBITS        0000000000002078 002078 0000a8 00   A  0   0  8
  [21] .init_array       INIT_ARRAY      0000000000003d78 002d78 000008 08  WA  0   0  8
  [22] .fini_array       FINI_ARRAY      0000000000003d80 002d80 000008 08  WA  0   0  8
  [23] .dynamic          DYNAMIC         0000000000003d88 002d88 0001f0 10  WA  7   0  8
  [24] .got              PROGBITS        0000000000003f78 002f78 000088 08  WA  0   0  8
  [25] .data             PROGBITS        0000000000004000 003000 000010 00  WA  0   0  8
  [26] .bss              NOBITS          0000000000004020 003010 000010 00  WA  0   0 32
  [27] .comment          PROGBITS        0000000000000000 003010 00002b 01  MS  0   0  1
  [28] .debug_aranges    PROGBITS        0000000000000000 00303b 000030 00      0   0  1
  [29] .debug_info       PROGBITS        0000000000000000 00306b 000472 00      0   0  1
  [30] .debug_abbrev     PROGBITS        0000000000000000 0034dd 000184 00      0   0  1
  [31] .debug_line       PROGBITS        0000000000000000 003661 00017e 00      0   0  1
  [32] .debug_str        PROGBITS        0000000000000000 0037df 00031a 01  MS  0   0  1
  [33] .debug_line_str   PROGBITS        0000000000000000 003af9 00012f 01  MS  0   0  1
  [34] .symtab           SYMTAB          0000000000000000 003c28 000438 18     35  18  8
  [35] .strtab           STRTAB          0000000000000000 004060 00028c 00      0   0  1
  [36] .shstrtab         STRTAB          0000000000000000 0042ec 00016a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)

For each section, readelf shows the relevant basic information, including the index, name, type of the sections. Let's focus on some important section names:

  • .init and .fini: The .init section contains executable code that performs initialization tasks and needs to run before any other code in the binary is executed like a constructor. .fini runs after the main program completes like a destructor.

  • .text: The .text section is where the main code of the program resides, so it will frequently be the main focus of your binary analysis or reverse engineering efforts.

  • The .bss, .data and .rodata: The program variables are kept in one or more dedicated sections, which are writable (.text is just readable). .bss is used to store uninitialized data and .data for initialized data. .rodata is also for constant (look for const keyword) variables.

Let's see the .rodata section:

$ objdump -sj .rodata -d copy

copy:     file format elf64-x86-64

Contents of section .rodata:
 2000 01000200 2d2d6865 6c700063 6f70792e  ....--help.copy.
 2010 63005772 6f6e6720 636f6d6d 616e642d  c.Wrong command-
 2020 6c696e65 20757361 6765002a 2a2a2025  line usage.*** %
 2030 73202825 733a3a25 6429202a 2a2a0a00  s (%s::%d) ***..

Disassembly of section .rodata:

0000000000002000 <_IO_stdin_used>:
    2000:   01 00 02 00 2d 2d 68 65 6c 70 00 63 6f 70 79 2e     ....--help.copy.
    2010:   63 00 57 72 6f 6e 67 20 63 6f 6d 6d 61 6e 64 2d     c.Wrong command-
    2020:   6c 69 6e 65 20 75 73 61 67 65 00 2a 2a 2a 20 25     line usage.*** %
    2030:   73 20 28 25 73 3a 3a 25 64 29 20 2a 2a 2a 0a 00     s (%s::%d) ***..

The program header table provides a segment view of the binary, as opposed to the section view provided by the section header table. The section view of an ELF binary is meant for static linking purposes only.

Binary Anaysis

After looked at the ELF binary composition, right now, I'll introduce the basic binary analysis in Linux.


This content originally appeared on DEV Community and was authored by Ahmet Can Gulmez


Print Share Comment Cite Upload Translate Updates
APA

Ahmet Can Gulmez | Sciencx (2025-09-27T08:29:09+00:00) Binary Analysis Fundamentals. Retrieved from https://www.scien.cx/2025/09/27/binary-analysis-fundamentals/

MLA
" » Binary Analysis Fundamentals." Ahmet Can Gulmez | Sciencx - Saturday September 27, 2025, https://www.scien.cx/2025/09/27/binary-analysis-fundamentals/
HARVARD
Ahmet Can Gulmez | Sciencx Saturday September 27, 2025 » Binary Analysis Fundamentals., viewed ,<https://www.scien.cx/2025/09/27/binary-analysis-fundamentals/>
VANCOUVER
Ahmet Can Gulmez | Sciencx - » Binary Analysis Fundamentals. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/27/binary-analysis-fundamentals/
CHICAGO
" » Binary Analysis Fundamentals." Ahmet Can Gulmez | Sciencx - Accessed . https://www.scien.cx/2025/09/27/binary-analysis-fundamentals/
IEEE
" » Binary Analysis Fundamentals." Ahmet Can Gulmez | Sciencx [Online]. Available: https://www.scien.cx/2025/09/27/binary-analysis-fundamentals/. [Accessed: ]
rf:citation
» Binary Analysis Fundamentals | Ahmet Can Gulmez | Sciencx | https://www.scien.cx/2025/09/27/binary-analysis-fundamentals/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.