chris.bracken.jp

Statically generated site for chris.bracken.jp
git clone https://git.bracken.jp/chris.bracken.jp.git
Log | Files | Refs

index.html (41624B)


      1 <!doctype html>
      2 <html lang="en">
      3 <head>
      4 <meta charset="utf-8">
      5 <meta name="viewport" content="width=device-width, initial-scale=1">
      6 <title>Hand-decoding an ELF binary image - Chris Bracken</title>
      7 <link href="/css/site.css" rel="stylesheet">
      8 <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
      9 <link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
     10 <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
     11 <link rel="manifest" href="/favicon/site.webmanifest">
     12 <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#140f42">
     13 <link rel="shortcut icon" href="/favicon/favicon.ico">
     14 <meta name="msapplication-TileColor" content="#603cba">
     15 <meta name="msapplication-config" content="/favicon/browserconfig.xml">
     16 <meta name="theme-color" content="#ffffff">
     17 </head>
     18 <body>
     19 <header id="header">
     20 <div class="site-title">
     21 <h1><a href="/">Chris Bracken</a></h1>
     22 </div>
     23 
     24 <nav class="site-navbar">
     25 <ul id="menu" class="menu">
     26   <li class="menu-item"><a class="menu-item-a" href="/">Home</a></li>
     27   <li class="menu-item"><a class="menu-item-a" href="/about/">About</a></li>
     28   <li class="menu-item"><a class="menu-item-a" href="/code/">Code</a></li>
     29   <li class="menu-item"><a class="menu-item-a" rel="me"href="https://bsd.network/@cbracken">Fediverse</a></li>
     30 </ul>
     31 </nav>
     32 </header>
     33 <main id="main">
     34 <article>
     35 <h2 class="post-title"><a href="https://chris.bracken.jp/2018/10/decoding-an-elf-binary/">Hand-decoding an ELF binary image</a></h2>
     36 31 October 2018
     37 <p>While recovering from some dentistry the other day I figured I&rsquo;d have a go at
     38 better understanding the ELF binary format. What better way to do that than to
     39 compile a small program and hand-decode the resulting binary with a hex editor
     40 and whatever ELF format spec I could find.</p>
     41 <h2 id="overview">Overview</h2>
     42 <p>Below, we&rsquo;ll use <code>nasm</code> to build a small assembly Hello World program to a
     43 64-bit ELF object file, then link that into an ELF executable with GNU <code>ld</code>.
     44 Finally, we&rsquo;ll run the resulting object file and binary image through <code>xxd</code> and
     45 hand-decode the resulting hex.</p>
     46 <p>The code and instructions below work on FreeBSD 11 on x86_64 hardware. For
     47 other operating systems, hardware, and toolchains, you&rsquo;re on your own! I&rsquo;d
     48 imagine this should all work just fine on Linux. If I get bored one day, I may
     49 redo this for Mach-O binaries on macOS.</p>
     50 <h2 id="helloasm">hello.asm</h2>
     51 <p>First we&rsquo;ll bang up a minimal Hello World program in assembly. In the <code>.data</code>
     52 section, we add a null-terminated string, <code>hello</code>, and its length <code>hbytes</code>. In
     53 the program text, we set up and execute the <code>write(stdout, hello, hbytes)</code>
     54 syscall, then set up and execute an <code>exit(0)</code> syscall.</p>
     55 <p>Note that 64-bit FreeBSD, macOS, and Linux all use the SysV AMD64 calling
     56 convention. For calls against the kernel interface, the syscall number is
     57 stored in <code>rax</code> and up to six parameters are passed, in order, in <code>rdi</code>, <code>rsi</code>,
     58 <code>rdx</code>, <code>r10</code>, <code>r8</code>, <code>r9</code>. For user calls, replace <code>r10</code> with <code>rcx</code> in this
     59 list, and pass further arguments on the stack. In all cases, the return value
     60 is passed through <code>rax</code>.  More details can be found in section A.2.1 of the
     61 <a href="https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf">System V AMD64 ABI Reference</a>.</p>
     62 <pre><code>; hello.asm
     63 
     64 %define stdin       0
     65 %define stdout      1
     66 %define stderr      2
     67 %define SYS_exit    1
     68 %define SYS_write   4
     69 
     70 %macro  system      1
     71         mov         rax, %1
     72         syscall
     73 %endmacro
     74 
     75 %macro  sys.exit    0
     76         system      SYS_exit
     77 %endmacro
     78 
     79 %macro  sys.write   0
     80         system      SYS_write
     81 %endmacro
     82 
     83 section  .data
     84     hello   db      'Hello, World!', 0Ah
     85     hbytes  equ     $-hello
     86 
     87 section .text
     88 global  _start
     89 _start:
     90     mov         rdi, stdout
     91     mov         rsi, hello
     92     mov         rdx, hbytes
     93     sys.write
     94 
     95     xor         rdi,rdi
     96     sys.exit
     97 </code></pre>
     98 <h2 id="compile-to-object-code">Compile to object code</h2>
     99 <p>Next, we&rsquo;ll compile <code>hello.asm</code> to a 64-bit ELF object file using <code>nasm</code>:</p>
    100 <pre><code>% nasm -f elf64 hello.asm
    101 </code></pre>
    102 <p>This emits <code>hello.o</code>, an 880-byte ELF-64 object file. Since we haven&rsquo;t yet run
    103 this through the linker, addresses of global symbols (in this case, <code>hello</code>)
    104 are not yet known and thus left with address 0x0 placeholders. We can see this
    105 in the <code>movabs</code> instruction at offset 0x15 of the <code>.text</code> section below.</p>
    106 <p>The relocation section (Section 6: <code>.rela.text</code>) contains an entry for each
    107 symbolic reference that needs to be filled in by the linker. In this case
    108 there&rsquo;s just a single entry for the symbol <code>hello</code> (which points to our hello
    109 world string). The relocation table entry&rsquo;s <code>r_offset</code> indicates the address to
    110 replace is at an offset of 0x7 into the section of the associated symbol table
    111 entry. Its <code>r_info</code> (0x0000000200000001) encodes a relocation type in its lower
    112 4 bytes (0x1: <code>R_AMD64_64</code>) and the associated symbol table entry in its upper
    113 4 bytes (0x2, which, if we look it up in the symbol table is the <code>.text</code>
    114 section).  The <code>r_addend</code> field (0x0) specifies an additional adjustment to the
    115 substituted symbol to be applied at link time; specifically, for the
    116 <code>R_AMD64_64</code>, the final address is computed as S + A, where S is the
    117 substituted symbol value (in our case, the address of <code>hello</code>) and A is the
    118 addend (in our case, 0x0).</p>
    119 <p>Without further ado, let&rsquo;s dump the object file:</p>
    120 <pre><code>% xxd hello.o
    121 </code></pre>
    122 <p>With whatever ELF64 <a href="https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/index.html">linker &amp; loader guide</a> we can find at hand,
    123 let&rsquo;s get decoding this thing:</p>
    124 <h3 id="elf-header">ELF Header</h3>
    125 <pre><code>|00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000|  .ELF............
    126 |00000010: 0100 3e00 0100 0000 0000 0000 0000 0000|  ..&gt;.............
    127 |00000020: 0000 0000 0000 0000 4000 0000 0000 0000|  ........@.......
    128 |00000030: 0000 0000 4000 0000 0000 4000 0700 0300|  ....@.....@.....
    129 
    130 e_ident[EI_MAG0..EI_MAG3]  0x7f + ELF          Magic
    131 e_ident[EI_CLASS]          0x02                64-bit
    132 e_ident[EI_DATA]           0x01                Little-endian
    133 e_ident[EI_VERSION]        0x01                ELF v1
    134 e_ident[EI_OSABI]          0x00                System V
    135 e_ident[EI_ABIVERSION]     0x00                Unused
    136 e_ident[EI_PAD]            0x00000000000000    7 bytes unused padding
    137 e_type                     0x0001              ET_REL
    138 e_machine                  0x003e              x86_64
    139 e_version                  0x00000001          Version 1
    140 e_entry                    0x0000000000000000  Entrypoint address (none)
    141 e_phoff                    0x0000000000000000  Program header table offset in image
    142 e_shoff                    0x0000000000000040  Section header table offset in image
    143 e_flags                    0x00000000          Architecture-dependent interpretation
    144 e_ehsize                   0x0040              Size of this ELF header (64B)
    145 e_phentsize                0x0000              Size of program header table entry
    146 e_phnum                    0x0000              Number of program header table entries
    147 e_shentsize                0x0040              Size of section header table entry (64B)
    148 e_shnum                    0x0007              Number of section header table entries
    149 e_shstrndx                 0x0003              Index of section header for .shstrtab
    150 </code></pre>
    151 <h3 id="section-header-table-entry-0-null">Section header table: Entry 0 (null)</h3>
    152 <pre><code>|00000040: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    153 |00000050: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    154 |00000060: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    155 |00000070: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    156 
    157 sh_name                    0x00000000          Offset into .shstrtab
    158 sh_type                    0x00000000          SHT_NULL
    159 sh_flags                   0x0000000000000000  Section attributes
    160 sh_addr                    0x0000000000000000  Virtual address of section in memory
    161 sh_offset                  0x0000000000000000  Offset of section in file image
    162 sh_size                    0x0000000000000000  Size in bytes of section in file image
    163 sh_link                    0x00000000          Section index of associated section
    164 sh_info                    0x00000000          Extra info about section
    165 sh_addralign               0x0000000000000000  Alignment
    166 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    167 </code></pre>
    168 <h3 id="section-header-table-entry-1-data">Section header table: Entry 1 (.data)</h3>
    169 <pre><code>|00000080: 0100 0000 0100 0000 0300 0000 0000 0000|  ................
    170 |00000090: 0000 0000 0000 0000 0002 0000 0000 0000|  ................
    171 |000000a0: 0e00 0000 0000 0000 0000 0000 0000 0000|  ................
    172 |000000b0: 0400 0000 0000 0000 0000 0000 0000 0000|  ................
    173 
    174 sh_name                    0x00000001          Offset into .shstrtab
    175 sh_type                    0x00000001          SHT_PROGBITS
    176 sh_flags                   0x0000000000000003  SHF_WRITE | SHF_ALLOC
    177 sh_addr                    0x0000000000000000  Virtual address of section in memory
    178 sh_offset                  0x0000000000000200  Offset of section in file image
    179 sh_size                    0x000000000000000e  Size in bytes of section in file image
    180 sh_link                    0x00000000          Section index of associated section
    181 sh_info                    0x00000000          Extra info about section
    182 sh_addralign               0x0000000000000004  Alignment
    183 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    184 </code></pre>
    185 <h3 id="section-header-table-entry-2-text">Section header table: Entry 2 (.text)</h3>
    186 <pre><code>|000000c0: 0700 0000 0100 0000 0600 0000 0000 0000|  ................
    187 |000000d0: 0000 0000 0000 0000 1002 0000 0000 0000|  ................
    188 |000000e0: 2500 0000 0000 0000 0000 0000 0000 0000|  %...............
    189 |000000f0: 1000 0000 0000 0000 0000 0000 0000 0000|  ................
    190 
    191 sh_name                    0x00000007          Offset into .shstrtab
    192 sh_type                    0x00000001          SHT_PROGBITS
    193 sh_flags                   0x0000000000000006  SHF_ALLOC | SHF_EXECINSTR
    194 sh_addr                    0x0000000000000000  Virtual address of section in memory
    195 sh_offset                  0x0000000000000210  Offset of section in file image
    196 sh_size                    0x0000000000000025  Size in bytes of section in file image
    197 sh_link                    0x00000000          Section index of associated section
    198 sh_info                    0x00000000          Extra info about section
    199 sh_addralign               0x0000000000000001  Alignment
    200 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    201 </code></pre>
    202 <h3 id="section-header-table-entry-3-shstrtab">Section header table: Entry 3 (.shstrtab)</h3>
    203 <pre><code>|00000100: 0d00 0000 0300 0000 0000 0000 0000 0000|  ................
    204 |00000110: 0000 0000 0000 0000 4002 0000 0000 0000|  ........@.......
    205 |00000120: 3200 0000 0000 0000 0000 0000 0000 0000|  2...............
    206 |00000130: 0100 0000 0000 0000 0000 0000 0000 0000|  ................
    207 
    208 sh_name                    0x0000000d          Offset into .shstrtab
    209 sh_type                    0x00000003          SHT_STRTAB
    210 sh_flags                   0x0000000000000000  Section attributes
    211 sh_addr                    0x0000000000000000  Virtual address of section in memory
    212 sh_offset                  0x0000000000000240  Offset of section in file image
    213 sh_size                    0x0000000000000032  Size in bytes of section in file image
    214 sh_link                    0x00000000          Section index of associated section
    215 sh_info                    0x00000000          Extra info about section
    216 sh_addralign               0x0000000000000001  Alignment
    217 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    218 </code></pre>
    219 <h3 id="section-header-table-entry-4-symtab">Section header table: Entry 4 (.symtab)</h3>
    220 <pre><code>|00000140: 1700 0000 0200 0000 0000 0000 0000 0000|  ................
    221 |00000150: 0000 0000 0000 0000 8002 0000 0000 0000|  ................
    222 |00000160: a800 0000 0000 0000 0500 0000 0600 0000|  ................
    223 |00000170: 0800 0000 0000 0000 1800 0000 0000 0000|  ................
    224 
    225 sh_name                    0x00000017          Offset into .shstrtab
    226 sh_type                    0x00000002          SHT_SYMTAB
    227 sh_flags                   0x0000000000000000  Section attributes
    228 sh_addr                    0x0000000000000000  Virtual address of section in memory
    229 sh_offset                  0x0000000000000280  Offset of section in file image
    230 sh_size                    0x00000000000000a8  Size in bytes of section in file image
    231 sh_link                    0x00000005          Section index of associated section
    232 sh_info                    0x00000006          Extra info about section
    233 sh_addralign               0x0000000000000008  Alignment
    234 sh_entsize                 0x0000000000000018  Size in bytes of each entry
    235 </code></pre>
    236 <h3 id="section-header-table-entry-5-strtab">Section header table: Entry 5 (.strtab)</h3>
    237 <pre><code>|00000180: 1f00 0000 0300 0000 0000 0000 0000 0000|  ................
    238 |00000190: 0000 0000 0000 0000 3003 0000 0000 0000|  ........0.......
    239 |000001a0: 1f00 0000 0000 0000 0000 0000 0000 0000|  ................
    240 |000001b0: 0100 0000 0000 0000 0000 0000 0000 0000|  ................
    241 
    242 sh_name                    0x0000001f          Offset into .shstrtab
    243 sh_type                    0x00000003          SHT_STRTAB
    244 sh_flags                   0x0000000000000000  Section attributes
    245 sh_addr                    0x0000000000000000  Virtual address of section in memory
    246 sh_offset                  0x0000000000000330  Offset of section in file image
    247 sh_size                    0x000000000000001f  Size in bytes of section in file image
    248 sh_link                    0x00000000          Section index of associated section
    249 sh_info                    0x00000000          Extra info about section
    250 sh_addralign               0x0000000000000001  Alignment
    251 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    252 </code></pre>
    253 <h3 id="section-header-table-entry-6-relatext">Section header table: Entry 6 (.rela.text)</h3>
    254 <pre><code>|000001c0: 2700 0000 0400 0000 0000 0000 0000 0000|  '...............
    255 |000001d0: 0000 0000 0000 0000 5003 0000 0000 0000|  ........P.......
    256 |000001e0: 1800 0000 0000 0000 0400 0000 0200 0000|  ................
    257 |000001f0: 0800 0000 0000 0000 1800 0000 0000 0000|  ................
    258 
    259 sh_name                    0x00000027          Offset into .shstrtab
    260 sh_type                    0x00000004          SHT_RELA
    261 sh_flags                   0x0000000000000000  Section attributes
    262 sh_addr                    0x0000000000000000  Virtual address of section in memory
    263 sh_offset                  0x0000000000000350  Offset of section in file image
    264 sh_size                    0x0000000000000018  Size in bytes of section in file image
    265 sh_link                    0x00000004          Section index of associated section
    266 sh_info                    0x00000002          Extra info about section
    267 sh_addralign               0x0000000000000008  Alignment
    268 sh_entsize                 0x0000000000000018  Size in bytes of each entry
    269 </code></pre>
    270 <h3 id="section-1-data-sht_progbits-shf_write--shf_alloc">Section 1: .data (SHT_PROGBITS; SHF_WRITE | SHF_ALLOC)</h3>
    271 <pre><code>|00000200: 4865 6c6c 6f2c 2057 6f72 6c64 210a 0000|  Hello, World!...
    272 
    273 0x000000  'Hello, World!\n'
    274 Zero-padding (2 bytes starting at 0x20e)
    275 </code></pre>
    276 <h3 id="section-2-text-sht_progbits-shf_alloc--shf_execinstr">Section 2: .text (SHT_PROGBITS; SHF_ALLOC | SHF_EXECINSTR)</h3>
    277 <pre><code>|00000210: bf01 0000 0048 be00 0000 0000 0000 00ba|  .....H..........
    278 |00000220: 0e00 0000 b804 0000 000f 0548 31ff b801|  ...........H1...
    279 |00000230: 0000 000f 0500 0000 0000 0000 0000 0000|  ................
    280 
    281 0x00000010  mov       edi, 0x1
    282 0x00000015  movabs    rsi, 0x000000 (placeholder for db hello)
    283 0x0000001f  mov       edx, 0xe
    284 0x00000024  mov       eax, 0x4
    285 0x00400029  syscall
    286 0x0040002b  xor       rdi, rdi
    287 0x0040002e  mov       eax, 0x1
    288 0x00400033  syscall
    289 Zero-padding (11 bytes starting at 0x235)
    290 </code></pre>
    291 <h3 id="section-3-shstrtab-sht_strtab">Section 3: .shstrtab (SHT_STRTAB;)</h3>
    292 <pre><code>|00000240: 002e 6461 7461 002e 7465 7874 002e 7368|  ..data..text..sh
    293 |00000250: 7374 7274 6162 002e 7379 6d74 6162 002e|  strtab..symtab..
    294 |00000260: 7374 7274 6162 002e 7265 6c61 2e74 6578|  strtab..rela.tex
    295 |00000270: 7400 0000 0000 0000 0000 0000 0000 0000|  t...............
    296 
    297 0x00000000: ''
    298 0x00000001: '.data'
    299 0x00000007: '.text'
    300 0x0000000d: '.shstrtab'
    301 0x00000017: '.symtab'
    302 0x0000001f: '.strtab'
    303 0x00000027: '.rela.text'
    304 Zero-padding (14 bytes starting at 0x272)
    305 </code></pre>
    306 <h3 id="section-4-symtab-sht_symtab">Section 4: .symtab&rsquo; (SHT_SYMTAB;)</h3>
    307 <h4 id="symbol-table-entry-0">Symbol table entry 0</h4>
    308 <pre><code>|00000280: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    309 |00000290: 0000 0000 0000 0000                    |  ........
    310 
    311 st_name                    0x00000000
    312 st_info                    0x00
    313 st_other                   0x00
    314 st_shndx                   0x0000 (SHN_UNDEF)
    315 st_value                   0x0000000000000000
    316 st_size                    0x0000000000000000
    317 </code></pre>
    318 <h4 id="symbol-table-entry-1-helloasm">Symbol table entry 1 (hello.asm)</h4>
    319 <pre><code>|00000298:                     0100 0000 0400 f1ff|          ........
    320 |000002a0: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    321 
    322 st_name                    0x00000001
    323 st_info                    0x04 (STT_FILE)
    324 st_other                   0x00
    325 st_shndx                   0xfff1 (SHN_ABS)
    326 st_value                   0x0000000000000000
    327 st_size                    0x0000000000000000
    328 </code></pre>
    329 <h4 id="symbol-table-entry-2">Symbol table entry 2</h4>
    330 <pre><code>|000002b0: 0000 0000 0300 0100 0000 0000 0000 0000|  ................
    331 |000002c0: 0000 0000 0000 0000                    |  ........
    332 
    333 st_name                    0x00000000
    334 st_info                    0x03 (STT_OBJECT | STT_FUNC)
    335 st_other                   0x00
    336 st_shndx                   0x0001 (Section 1: .data)
    337 st_value                   0x0000000000000000
    338 st_size                    0x0000000000000000
    339 </code></pre>
    340 <h4 id="symbol-table-entry-3">Symbol table entry 3</h4>
    341 <pre><code>|000002c8:                     0000 0000 0300 0200|          ........
    342 |000002d0: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    343 
    344 st_name                    0x00000000
    345 st_info                    0x03 (STT_OBJECT | STT_FUNC)
    346 st_other                   0x00
    347 st_shndx                   0x0002 (Section 2: .text)
    348 st_value                   0x0000000000000000
    349 st_size                    0x0000000000000000
    350 </code></pre>
    351 <h4 id="symbol-table-entry-4-hello">Symbol table entry 4 (hello)</h4>
    352 <pre><code>|000002e0: 0b00 0000 0000 0100 0000 0000 0000 0000|  ................
    353 |000002f0: 0000 0000 0000 0000                    |  ........
    354 
    355 st_name                    0x0000000b
    356 st_info                    0x00
    357 st_other                   0x00
    358 st_shndx                   0x0001 (Section 1: .data)
    359 st_value                   0x0000000000000000
    360 st_size                    0x0000000000000000
    361 </code></pre>
    362 <h3 id="symbol-table-entry-5-hbytes">Symbol table entry 5 (hbytes)</h3>
    363 <pre><code>|000002f8:                     1100 0000 0000 f1ff|          ........
    364 |00000300: 0e00 0000 0000 0000 0000 0000 0000 0000|  ................
    365 
    366 st_name                    0x00000011
    367 st_info                    0x00
    368 st_other                   0x00
    369 st_shndx                   0xfff1 (SHN_ABS)
    370 st_value                   0x000000000000000e
    371 st_size                    0x0000000000000000
    372 </code></pre>
    373 <h4 id="symbol-table-entry-6-_start">Symbol table entry 6 (_start)</h4>
    374 <pre><code>|00000310: 1800 0000 1000 0200 0000 0000 0000 0000|  ................
    375 |00000320: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    376 
    377 st_name                    0x00000018
    378 st_info                    0x01 (STT_OBJECT)
    379 st_other                   0x00
    380 st_shndx                   0x0002 (Section 2: .text)
    381 st_value                   0x0000000000000000
    382 st_size                    0x0000000000000000
    383 Zero-padding (8 bytes starting at 0x328)
    384 </code></pre>
    385 <h3 id="section-5-strtab-sht_strtab">Section 5: .strtab (SHT_STRTAB;)</h3>
    386 <pre><code>|00000330: 0068 656c 6c6f 2e61 736d 0068 656c 6c6f|  .hello.asm.hello
    387 |00000340: 0068 6279 7465 7300 5f73 7461 7274 0000|  .hbytes._start..
    388 
    389 0x00000000: ''
    390 0x00000001: 'hello.asm'
    391 0x0000000b: 'hello'
    392 0x00000011: 'hbytes'
    393 0x00000018: '_start'
    394 Zero-padding (1 byte starting at 0x34f)
    395 </code></pre>
    396 <h3 id="section-6-relatext-sht_rela">Section 6: .rela.text (SHT_RELA;)</h3>
    397 <pre><code>|00000350: 0700 0000 0000 0000 0100 0000 0200 0000|  ................
    398 |00000360: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    399 
    400 r_offset                   0x0000000000000007
    401 r_info                     0x0000000200000001 (Symbol table entry 2, type R_AMD64_64)
    402 r_addend                   0x0000000000000000
    403 Zero-padding (8 bytes starting at 0x368)
    404 </code></pre>
    405 <h2 id="link-to-executable-image">Link to executable image</h2>
    406 <p>Next, let&rsquo;s link <code>hello.o</code> into a 64-bit ELF executable:</p>
    407 <pre><code>% ld -o hello hello.o
    408 </code></pre>
    409 <p>This emits <code>hello</code>, a 951-byte ELF-64 executable image.</p>
    410 <p>Since the linker has decided which segment each section maps into (if any) and
    411 what the segment addresses are, addresses are now known for all (statically
    412 linked) symbols, and address 0x0 placeholders have been replaced with actual
    413 addresses. We can see this in the <code>mov</code> instruction at address 0x4000b5, which
    414 now specifies an address of 0x6000d8.</p>
    415 <p>Running the linked executable image through <code>xxd</code> as above and picking our
    416 trusty linker &amp; loader guide back up, here we go again:</p>
    417 <h3 id="elf-header-1">ELF Header</h3>
    418 <pre><code>|00000000: 7f45 4c46 0201 0109 0000 0000 0000 0000|  .ELF............
    419 |00000010: 0200 3e00 0100 0000 b000 4000 0000 0000|  ..&gt;.......@.....
    420 |00000020: 4000 0000 0000 0000 1001 0000 0000 0000|  @...............
    421 |00000030: 0000 0000 4000 3800 0200 4000 0600 0300|  ....@.8...@.....
    422 
    423 e_ident[EI_MAG0..EI_MAG3]  0x7f + ELF          Magic
    424 e_ident[EI_CLASS]          0x02                64-bit
    425 e_ident[EI_DATA]           0x01                Little-endian
    426 e_ident[EI_VERSION]        0x01                ELF v1
    427 e_ident[EI_OSABI]          0x09                FreeBSD
    428 e_ident[EI_ABIVERSION]     0x00                Unused
    429 e_ident[EI_PAD]            0x0000000000        7 bytes unused padding
    430 e_type                     0x0002              ET_EXEC
    431 e_machine                  0x003e              x86_64
    432 e_version                  0x00000001          Version 1
    433 e_entry                    0x00000000004000b0  Entrypoint addr
    434 e_phoff                    0x0000000000000040  Program header table offset in image
    435 e_shoff                    0x0000000000000110  Section header table offset in image
    436 e_flags                    0x00000000          Architecture-dependent interpretation
    437 e_ehsize                   0x0040              Size of this ELF header
    438 e_phentsize                0x0038              Size of program header table entry
    439 e_phnum                    0x0002              Number of program header table entries
    440 e_shentsize                0x0040              Size of section header table entry
    441 e_shnum                    0x0006              Number of section header table entries
    442 e_shstrndx                 0x0003              Index of section header for .shstrtab
    443 </code></pre>
    444 <h3 id="program-header-table-entry-0-pf_x--pf_r">Program header table: Entry 0 (PF_X | PF_R)</h3>
    445 <pre><code>|00000040: 0100 0000 0500 0000 0000 0000 0000 0000|  ................
    446 |00000050: 0000 4000 0000 0000 0000 4000 0000 0000|  ..@.......@.....
    447 |00000060: d500 0000 0000 0000 d500 0000 0000 0000|  ................
    448 |00000070: 0000 2000 0000 0000                    |  .. .............
    449 
    450 p_type                     0x00000001          PT_LOAD
    451 p_flags                    0x00000005          PF_X | PF_R
    452 p_offset                   0x00000000          Offset of segment in file image
    453 p_vaddr                    0x0000000000400000  Virtual address of segment in memory
    454 p_paddr                    0x0000000000400000  Physical address of segment
    455 p_filesz                   0x00000000000000d5  Size in bytes of segment in file image
    456 p_memsz                    0x00000000000000d5  Size in bytes of segment in memory
    457 p_align                    0x0000000000200000  Alignment (2MB)
    458 </code></pre>
    459 <h3 id="program-header-table-entry-1-pf_w--pf_r">Program header table: Entry 1 (PF_W | PF_R)</h3>
    460 <pre><code>|00000078:                     0100 0000 0600 0000|          ........
    461 |00000080: d800 0000 0000 0000 d800 6000 0000 0000|  ..........`.....
    462 |00000090: d800 6000 0000 0000 0e00 0000 0000 0000|  ..`.............
    463 |000000a0: 0e00 0000 0000 0000 0000 2000 0000 0000|  .......... .....
    464 
    465 p_type                     0x00000001          PT_LOAD
    466 p_flags                    0x00000006          PF_W | PF_R
    467 p_offset                   0x00000000000000d8  Offset of segment in file image
    468 p_vaddr                    0x00000000006000d8  Virtual address of segment in memory
    469 p_paddr                    0x00000000006000d8  Physical address of segment
    470 p_filesz                   0x000000000000000e  Size in bytes of segment in file image
    471 p_memsz                    0x000000000000000e  Size in bytes of segment in memory
    472 p_align                    0x0000000000200000  Alignment (2MB)
    473 </code></pre>
    474 <h3 id="section-1-text-sht_progbits-shf_alloc--shf_execinstr">Section 1: .text (SHT_PROGBITS; SHF_ALLOC | SHF_EXECINSTR)</h3>
    475 <pre><code>|000000b0: bf01 0000 0048 bed8 0060 0000 0000 00ba|  .....H...`......
    476 |000000c0: 0e00 0000 b804 0000 000f 0548 31ff b801|  ...........H1...
    477 |000000d0: 0000 000f 05                           |  .....
    478 
    479 0x4000b0  mov       edi, 0x1
    480 0x4000b5  movabs    rsi, 0x6000d8
    481 0x4000bf  mov       edx, 0xe
    482 0x4000c4  mov       eax, 0x4
    483 0x4000c9  syscall
    484 0x4000cb  xor       rdi, rdi
    485 0x4000ce  mov       eax, 0x1
    486 0x4000d3  syscall
    487 Zero-padding (5 bytes starting at 0x000000d5)
    488 </code></pre>
    489 <h3 id="section-2-data-sht_progbits-shf_write--shf_alloc">Section 2: .data (SHT_PROGBITS; SHF_WRITE | SHF_ALLOC)</h3>
    490 <pre><code>|000000d8:                     4865 6c6c 6f2c 2057|          Hello, W
    491 |000000e0: 6f72 6c64 210a                         |  orld!.
    492 
    493 0x6000d8  'Hello, World!\n'
    494 </code></pre>
    495 <h3 id="section-3-shstrtab-sht_strtab-1">Section 3: .shstrtab (SHT_STRTAB;)</h3>
    496 <pre><code>|000000e6:                002e 7379 6d74 6162 002e|        ..symtab..
    497 |000000f0: 7374 7274 6162 002e 7368 7374 7274 6162|  strtab..shstrtab
    498 |00000100: 002e 7465 7874 002e 6461 7461 0000 0000|  ..text..data.
    499 
    500 0x00000000: ''
    501 0x00000001: '.symtab'
    502 0x00000009: '.strtab'
    503 0x00000011: '.shstrtab'
    504 0x0000001b: '.text'
    505 0x00000021: '.data'
    506 Zero-padding (3 bytes starting at 0x0000010d)
    507 </code></pre>
    508 <h3 id="section-header-table-entry-0-null-1">Section header table: Entry 0 (null)</h3>
    509 <pre><code>|00000110: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    510 |00000120: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    511 |00000130: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    512 |00000140: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    513 
    514 sh_name                    0x00000000          Offset into .shstrtab
    515 sh_type                    0x00000000          SHT_NULL
    516 sh_flags                   0x0000000000000000  Section attributes
    517 sh_addr                    0x0000000000000000  Virtual address of section in memory
    518 sh_offset                  0x0000000000000000  Offset of section in file image
    519 sh_size                    0x0000000000000000  Size in bytes of section in file image
    520 sh_link                    0x00000000          Section index of associated section
    521 sh_info                    0x00000000          Extra info about section
    522 sh_addralign               0x0000000000000000  Alignment
    523 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    524 </code></pre>
    525 <h3 id="section-header-table-entry-1-text">Section header table: Entry 1 (.text)</h3>
    526 <pre><code>|00000150: 1b00 0000 0100 0000 0600 0000 0000 0000|  ................
    527 |00000160: b000 4000 0000 0000 b000 0000 0000 0000|  ..@.............
    528 |00000170: 2500 0000 0000 0000 0000 0000 0000 0000|  %...............
    529 |00000180: 1000 0000 0000 0000 0000 0000 0000 0000|  ................
    530 
    531 sh_name                    0x0000001b          Offset into .shstrtab
    532 sh_type                    0x00000001          SHT_PROGBITS
    533 sh_flags                   0x00000006          SHF_ALLOC | SHF_EXECINSTR
    534 sh_addr                    0x00000000004000b0  Virtual address of section in memory
    535 sh_offset                  0x00000000000000b0  Offset of section in file image
    536 sh_size                    0x0000000000000025  Size in bytes of section in file image
    537 sh_link                    0x00000000          Section index of associated section
    538 sh_info                    0x00000000          Extra info about section
    539 sh_addralign               0x0000000000000010  Alignment (2B)
    540 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    541 </code></pre>
    542 <h3 id="section-header-table-entry-2-data">Section header table: Entry 2 (.data)</h3>
    543 <pre><code>|00000190: 2100 0000 0100 0000 0300 0000 0000 0000|  !...............
    544 |000001a0: d800 6000 0000 0000 d800 0000 0000 0000|  ..`.............
    545 |000001b0: 0e00 0000 0000 0000 0000 0000 0000 0000|  ................
    546 |000001c0: 0400 0000 0000 0000 0000 0000 0000 0000|  ................
    547 
    548 sh_name                    0x00000021          Offset into .shstrtab
    549 sh_type                    0x00000001          SHT_PROGBITS
    550 sh_flags                   0x0000000000000003  SHF_WRITE | SHF_ALLOC
    551 sh_addr                    0x00000000006000d8  Virtual address of section in memory
    552 sh_offset                  0x00000000000000d8  Offset of section in file image
    553 sh_size                    0x000000000000000e  Size in bytes of section in file image
    554 sh_link                    0x00000000          Section index of associated section
    555 sh_info                    0x00000000          Extra info about section
    556 sh_addralign               0x0000000000000004  Alignment (4B)
    557 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    558 </code></pre>
    559 <h3 id="section-header-table-entry-3-shstrtab-1">Section header table: Entry 3 (.shstrtab)</h3>
    560 <pre><code>|000001d0: 1100 0000 0300 0000 0000 0000 0000 0000|  ................
    561 |000001e0: 0000 0000 0000 0000 e600 0000 0000 0000|  ................
    562 |000001f0: 2700 0000 0000 0000 0000 0000 0000 0000|  '...............
    563 |00000200: 0100 0000 0000 0000 0000 0000 0000 0000|  ................
    564 
    565 sh_name                    0x00000011          Offset into .shstrtab
    566 sh_type                    0x00000003          SHT_STRTAB
    567 sh_flags                   0x00000000          No flags
    568 sh_addr                    0x0000000000000000  Virtual address of section in memory
    569 sh_offset                  0x00000000000000e6  Offset of section in file image
    570 sh_size                    0x0000000000000027  Size in bytes of section in file image
    571 sh_link                    0x00000000          Section index of associated section
    572 sh_info                    0x00000000          Extra info about section
    573 sh_addralign               0x0000000000000001  Alignment (1B)
    574 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    575 </code></pre>
    576 <h3 id="section-header-table-entry-4-symtab-1">Section header table: Entry 4 (.symtab)</h3>
    577 <pre><code>|00000210: 0100 0000 0200 0000 0000 0000 0000 0000|  ................
    578 |00000220: 0000 0000 0000 0000 9002 0000 0000 0000|  ................
    579 |00000230: f000 0000 0000 0000 0500 0000 0600 0000|  ................
    580 |00000240: 0800 0000 0000 0000 1800 0000 0000 0000|  ................
    581 
    582 sh_name                    0x00000001          Offset into .shstrtab
    583 sh_type                    0x00000002          SHT_SYMTAB
    584 sh_flags                   0x00000000          No flags
    585 sh_addr                    0x0000000000000000  Virtual address of section in memory
    586 sh_offset                  0x0000000000000290  Offset of section in file image
    587 sh_size                    0x00000000000000f0  Size in bytes of section in file image
    588 sh_link                    0x00000005          Section index of associated section
    589 sh_info                    0x00000006          Flags
    590 sh_addralign               0x0000000000000008  Alignment (8B)
    591 sh_entsize                 0x0000000000000018  Size in bytes of each entry (24B)
    592 </code></pre>
    593 <h3 id="section-header-table-entry-5-strtab-1">Section header table: Entry 5 (.strtab)</h3>
    594 <pre><code>|00000250: 0900 0000 0300 0000 0000 0000 0000 0000|  ................
    595 |00000260: 0000 0000 0000 0000 8003 0000 0000 0000|  ................
    596 |00000270: 3700 0000 0000 0000 0000 0000 0000 0000|  7...............
    597 |00000280: 0100 0000 0000 0000 0000 0000 0000 0000|  ................
    598 
    599 sh_name                    0x00000009          Offset into .shstrtab
    600 sh_type                    0x00000003          SHT_STRTAB
    601 sh_flags                   0x0000000000000000  No flags
    602 sh_addr                    0x0000000000000000  Virtual address of section in memory
    603 sh_offset                  0x0000000000000380  Offset of section in file image
    604 sh_size                    0x0000000000000037  Size in bytes of section in file image
    605 sh_link                    0x00000000          Section index of associated section
    606 sh_info                    0x00000000          Extrac info about section
    607 sh_addralign               0x0000000000000001  Alignment (1B)
    608 sh_entsize                 0x0000000000000000  Size in bytes of each entry
    609 </code></pre>
    610 <h3 id="section-4-symtab-sht_symtab-1">Section 4: .symtab (SHT_SYMTAB;)</h3>
    611 <h4 id="symbol-table-entry-0-1">Symbol table entry 0</h4>
    612 <pre><code>|00000290: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    613 |000002a0: 0000 0000 0000 0000                    |  ........
    614 
    615 st_name                    0x00000000
    616 st_info                    0x00
    617 st_other                   0x00
    618 st_shndx                   0x0000 (SHN_UNDEF)
    619 st_value                   0x0000000000000000
    620 st_size                    0x0000000000000000
    621 </code></pre>
    622 <h4 id="symbol-table-entry-1">Symbol table entry 1</h4>
    623 <pre><code>|000002a8:                     0000 0000 0300 0100|          ........
    624 |000002b0: b000 4000 0000 0000 0000 0000 0000 0000|  ..@.............
    625 
    626 st_name                    0x00000000
    627 st_info                    0x03 (STT_OBJECT | STT_FUNC)
    628 st_other                   0x00
    629 st_shndx                   0x0001 (Section 1: .text)
    630 st_value                   0x00000000004000b0
    631 st_size                    0x0000000000000000
    632 </code></pre>
    633 <h4 id="symbol-table-entry-2-1">Symbol table entry 2</h4>
    634 <pre><code>|000002c0: 0000 0000 0300 0200 d800 6000 0000 0000|  ..........`.....
    635 |000002d0: 0000 0000 0000 0000                    |  ........
    636 
    637 st_name                    0x00000000
    638 st_info                    0x03 (STT_OBJECT | STT_FUNC)
    639 st_other                   0x00
    640 st_shndx                   0x0002 (Section 2: .data)
    641 st_value                   0x00000000006000d8
    642 st_size                    0x0000000000000000
    643 </code></pre>
    644 <h4 id="symbol-table-entry-3-helloasm">Symbol table entry 3 (hello.asm)</h4>
    645 <pre><code>|000002d0:                     0100 0000 0400 f1ff|          ........
    646 |000002e0: 0000 0000 0000 0000 0000 0000 0000 0000|  ................
    647 
    648 st_name                    0x00000001
    649 st_info                    0x04 (STT_FILE)
    650 st_other                   0x00
    651 st_shndx                   0xfff1 (SHN_ABS)
    652 st_value                   0x0000000000000000
    653 st_size                    0x0000000000000000
    654 </code></pre>
    655 <h4 id="symbol-table-entry-4-hello-1">Symbol table entry 4 (hello)</h4>
    656 <pre><code>|000002f0: 0b00 0000 0000 0200 d800 6000 0000 0000|  ..........`.....
    657 |00000300: 0000 0000 0000 0000                    |  ................
    658 
    659 st_name                    0x0000000b
    660 st_info                    0x00
    661 st_other                   0x00
    662 st_shndx                   0x0002 (Section 2: .data)
    663 st_value                   0x00000000006000d8
    664 st_size                    0x0000000000000000
    665 </code></pre>
    666 <h4 id="symbol-table-entry-5-hbytes-1">Symbol table entry 5 (hbytes)</h4>
    667 <pre><code>|00000300:                     1100 0000 0000 f1ff|          ........
    668 |00000310: 0e00 0000 0000 0000 0000 0000 0000 0000|  ................
    669 
    670 st_name                    0x00000011
    671 st_info                    0x00
    672 st_other                   0x00
    673 st_shndx                   0xfff1 (SHN_ABS)
    674 st_value                   0x000000000000000e
    675 st_size                    0x0000000000000000
    676 </code></pre>
    677 <h4 id="symbol-table-entry-6-_start-1">Symbol table entry 6 (_start)</h4>
    678 <pre><code>|00000320: 1800 0000 1000 0100 b000 4000 0000 0000|  ..........@.....
    679 |00000330: 0000 0000 0000 0000                    |  ........
    680 
    681 st_name                    0x00000018
    682 st_info                    0x10 (STB_GLOBAL)
    683 st_other                   0x00
    684 st_shndx                   0x0001 (Section 1: .text)
    685 st_value                   0x00000000004000b0
    686 st_size                    0x0000000000000000
    687 </code></pre>
    688 <h4 id="symbol-table-entry-7-__bss_start">Symbol table entry 7 (__bss_start)</h4>
    689 <pre><code>|00000330:                     1f00 0000 1000 f1ff|          ........
    690 |00000340: e600 6000 0000 0000 0000 0000 0000 0000|  ..`.............
    691 
    692 st_name                    0x0000001f
    693 st_info                    0x10 (STB_GLOBAL)
    694 st_other                   0x00
    695 st_shndx                   0xfff1 (SHN_ABS)
    696 st_value                   0x00000000006000e6
    697 st_size                    0x0000000000000000
    698 </code></pre>
    699 <h4 id="symbol-table-entry-8-_edata">Symbol table entry 8 (_edata)</h4>
    700 <pre><code>|00000350: 2b00 0000 1000 f1ff e600 6000 0000 0000|  +.........`.....
    701 |00000360: 0000 0000 0000 0000                    |  ........
    702 
    703 st_name                    0x0000002b
    704 st_info                    0x10 (STB_GLOBAL)
    705 st_other                   0x00
    706 st_shndx                   0xfff1 (SHN_ABS)
    707 st_value                   0x00000000006000e6
    708 st_size                    0x0000000000000000
    709 </code></pre>
    710 <h4 id="symbol-table-entry-9-_end">Symbol table entry 9 (_end)</h4>
    711 <pre><code>|00000360:                     3200 0000 1000 f1ff|          2.......
    712 |00000370: e800 6000 0000 0000 0000 0000 0000 0000|  ..`.............
    713 
    714 st_name                    0x00000032
    715 st_info                    0x10 (STB_GLOBAL)
    716 st_other                   0x00
    717 st_shndx                   0xfff1 (SHN_ABS)
    718 st_value                   0x00000000006000e8
    719 st_size                    0x0000000000000000
    720 </code></pre>
    721 <h3 id="section-6-strtab-sht_strtab">Section 6: .strtab (SHT_STRTAB;)</h3>
    722 <pre><code>|00000380: 0068 656c 6c6f 2e61 736d 0068 656c 6c6f|  .hello.asm.hello
    723 |00000390: 0068 6279 7465 7300 5f73 7461 7274 005f|  .hbytes._start._
    724 |000003a0: 5f62 7373 5f73 7461 7274 005f 6564 6174|  _bss_start._edat
    725 |000003b0: 6100 5f65 6e64 00                      |  a._end.
    726 
    727 0x00000000: ''
    728 0x00000001: 'hello.asm'
    729 0x0000000b: 'hello'
    730 0x00000011: 'hbytes'
    731 0x00000018: '_start'
    732 0x0000001f: '__bss_start'
    733 0x0000002b: '_edata'
    734 0x00000032: '_end'
    735 </code></pre>
    736 <h2 id="effect-of-stripping">Effect of stripping</h2>
    737 <p>Running <code>strip</code> on the binary has the effect of dropping the <code>.symtab</code> and
    738 <code>.strtab</code> sections along with their section headers and 16 bytes of data (the
    739 section names <code>.symtab</code> and <code>.strtab</code>) from the <code>.shstrtab</code> section, reducing the
    740 total binary size to 512 bytes.</p>
    741 <h2 id="in-memory-process-image">In-memory process image</h2>
    742 <p>FreeBSD uses a memory superpage size of 2MB (page size of 4kB) on x86_64. Since
    743 attributes are set at the page level, read+execute program <code>.text</code> and
    744 read+write <code>.data</code> are loaded into two separate segments on separate pages, as
    745 laid-out by the linker.</p>
    746 <p>On launch, the kernel maps the binary image into memory as specified in the
    747 program header table:</p>
    748 <ul>
    749 <li>PHT Entry 0: The ELF header, program header table, and Section 1 (<code>.text</code>)
    750 are mapped from offset 0x00 of the binary image (with length 0xd6 bytes)
    751 into Segment 1 (readable, executable) at address 0x400000.</li>
    752 <li>PHT Entry 1: Section 2 (<code>.data</code>) at offset 0xd8 of the binary image is
    753 mapped into Segment 2 (readable, writeable) at address 0x6000d8 from offset
    754 0xd8 with length 0x0e bytes.</li>
    755 </ul>
    756 <p>The program entrypoint is specified to be 0x4000b0, the start of the <code>.text</code>
    757 section.</p>
    758 <p>And that&rsquo;s it! Any corrections or comments are always welcome. Shoot me an
    759 email at <a href="mailto:chris@bracken.jp">chris@bracken.jp</a>.</p>
    760 </article>
    761 </main>
    762 
    763 <footer id="footer">
    764 <div class="copyright">
    765 <span xmlns:dct="http://purl.org/dc/terms/" xmlns:cc="http://creativecommons.org/ns#">
    766 The content of this site by
    767 <a rel="cc:attributionURL" href="https://chris.bracken.jp/about"><span rel="cc:attributionName">Chris Bracken</span></a>
    768 is
    769 <a href="https://creativecommons.org/licenses/by/4.0">CC BY 4.0</a>.
    770 </span>
    771 </div>
    772 </footer>
    773 </body>
    774 </html>