# >>>>>>>>>>>>> ELF FILE HEADER <<<<<<<<<<<<< # All numbers (except in names) are in base sixteen (hexadecimal) # 00 <- number of bytes listed so far 7F 45 4C 46 # 04 e_ident[EI_MAG]: ELF magic number 01 # 05 e_ident[EI_CLASS]: 1: 32-bit, 2: 64-bit 01 # 06 e_ident[EI_DATA]: 1: little-endian, 2: big-endian 01 # 07 e_ident[EI_VERSION]: ELF header version; must be 1 00 # 08 e_ident[EI_OSABI]: Target OS ABI; should be 0 00 # 09 e_ident[EI_ABIVERSION]: ABI version; 0 is ok for Linux 00 00 00 # 0C e_ident[EI_PAD]: unused, should be 0 00 00 00 00 # 10 02 00 # 12 e_type: object file type; 2: executable 03 00 # 14 e_machine: instruction set architecture; 3: x86, 3E: amd64 01 00 00 00 # 18 e_version: ELF identification version; must be 1 54 80 04 08 # 1C e_entry: memory address of entry point (where process starts) 34 00 00 00 # 20 e_phoff: file offset where program headers begin 00 00 00 00 # 24 e_shoff: file offset where section headers begin 00 00 00 00 # 28 e_flags: 0 for x86 34 00 # 2A e_ehsize: size of this header (34: 32-bit, 40: 64-bit) 20 00 # 2C e_phentsize: size of each program header (20: 32-bit, 38: 64-bit) 01 00 # 2E e_phnum: #program headers 28 00 # 30 e_shentsize: size of each section header (28: 32-bit, 40: 64-bit) 00 00 # 32 e_shnum: #section headers 00 00 # 34 e_shstrndx: index of section header containing section names # >>>>>>>>>>>>> ELF PROGRAM HEADER <<<<<<<<<<<<< 01 00 00 00 # 38 p_type: segment type; 1: loadable 00 00 00 00 # 3C p_offset: file offset where segment begins 00 80 04 08 # 40 p_vaddr: virtual address of segment in memory (x86: 08048000) 00 00 00 00 # 44 p_paddr: physical address of segment, unspecified by 386 supplement 94 00 00 00 # 48 p_filesz: size in bytes of the segment in the file image ############ 00 80 FB 77 # 4C p_memsz: size in bytes of the segment in memory; p_filesz <= p_memsz 07 00 00 00 # 50 p_flags: segment-dependent flags (1: X, 2: W, 4: R) 00 10 00 00 # 54 p_align: 1000 for x86 # >>>>>>>>>>>>> PROGRAM <<<<<<<<<<<<< # 08048000 Head (> Stack; see ABI supplement 386) # 08048100 obuf # "HELMO\n": 48 45 4C 4D 4F 0A # INTENTION INSTRUCTION OPCODE ModR/M SIB C6 05 00 81 04 08 48 # [...] = 'H' mov r/m8, imm8 C6 /0 ib 00 000 101 BF 02 81 04 08 # edi = obuf+2 mov r32, imm32 B8+rd id C6 07 4C # [edi] = 'L' mov r/m8, imm8 C6 /0 ib 00 000 111 C6 47 01 4D # [edi+1] = 'M' mov r/m8, imm8 C6 /0 ib 01 000 111 C6 47 FF 45 # [edi-1] = 'E' mov r/m8, imm8 C6 /0 ib 01 000 111 BB 01 00 00 00 # ebx = 1 mov r32, imm32 B8+rd id C6 04 5F 4F # [2*ebx+edi] = 'O' mov r/m8, imm8 C6 /0 ib 00 000 100 01 011 111 C6 44 5F 01 0A # [2*ebx+edi+1] = '\n' mov r/m8, imm8 C6 /0 ib 01 000 100 01 011 111 # Write: # 79 8D 4F FE # ecx = edi-2 (obuf) lea r32, m 8D /r 01 001 111 8D 53 05 # edx = ebx+5 (6 count) lea r32, m 8D /r 01 010 011 # Flush: # 7F 8D 43 03 # eax = ebx+3 (4 write) lea r32, m 8D /r 01 000 011 CD 80 # syscall int imm8 CD ib 85 C0 # cmp eax, 0 test r/m32, r32 85 /r 11 000 000 7C 07 # jump Error if < 88 jl rel8 7C cb 01 C1 # ecx += eax add r/m32, r32 01 /r 11 000 001 29 C2 # edx -= eax sub r/m32, r32 29 /r 11 000 010 75 F1 # jump Flush if != 8E jne rel8 75 cb # Exit: # 4B # ebx-- dec r32 48+rd # Error: # 8F 31 C0 40 # eax = 1 (exit) xor r/m32, r32 31 /r 11 000 000 CD 80 # syscall 94 int imm8 CD ib