# >>>>>>>>>>>>> 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)
# INTENTION INSTRUCTION OPCODE NOTE
89 E5 # ebp = esp mov r/m32, r32 89 /r 11 100 101
83 ED 10 # ebp -= 10 sub r/m32, imm8 83 /5 ib 11 101 101
31 DB 43 # ebx = 1 (stdout) xor r/m32, r32; inc 31 /r 11 011 011
E8 06 00 00 00 # call Func 61 call rel32 E8 cd
# Exit: #
4B # ebx-- dec r32 48+rd
# Error: # 62
31 C0 40 # eax = 1 (exit) xor r/m32, r32; inc 31 /r 11 000 000
CD 80 # syscall int imm8 CD ib
# Func: # 67
B9 02 00 00 00 # ecx = 3 (Couter) mov r32, imm32 B8+rd id
# Outer: # 6C
51 # push ecx push r32 50+rd S: Couter
B9 03 00 00 00 # ecx = 3 (Cinner) mov r32, imm32 B8+rd id
# Inner: # 72
51 # push ecx push r32 50+rd S: Couter Cinner
89 E9 # ecx = ebp (buf) mov r/m32, r32 89 /r 11 101 001
BA 10 00 00 00 # edx = count mov r32, imm32 B8+rd id
# Flush: # 7A
B8 04 00 00 00 # eax = 4 (write) mov r32, imm32 B8+rd id
CD 80 # syscall int imm8 CD ib
85 C0 # cmp eax, 0 test r/m32, r32 85 /r 11 000 000
7C DD # jump Error if < 85 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 EF # jump Flush if != 8B jne rel8 75 cb
59 # pop ecx pop r32 58+rd S: Couter
49 # ecx-- dec r32 48+rd
75 E3 # jump Inner if != 8F jne rel8 75 cb
59 # pop ecx pop r32 58+rd S:
49 # ecx-- dec r32 48+rd
75 D9 # jump Outer if != 93 jne rel8 75 cb
C3 # return 94 ret C3