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’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’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’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’re on your own! I’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’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’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’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’s just a single entry for the symbol <code>hello</code> (which points to our hello 109 world string). The relocation table entry’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’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 & loader guide</a> we can find at hand, 123 let’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| ..>............. 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’ (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’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 & 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| ..>.......@..... 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’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>