understanding elf magic : the elf and program header
lo! the road to elf sorcery is fraught with difficulties and nasty “gotchas”. i don’t know if i’m on the right track, so i’m posting my uncompleted work. and if ever a real wizard passes by, perhaps he could fill me in on some parts i did wrong.
BITS 32 org 0x08048000 ; ---------- ; elf header ; ---------- ehdr: db 0x7f, "ELF", 1, 1, 1 times 9 db 0x0 dw 2 ; e_type dw 3 ; e_machine dd 1 ; e_version dd _start ; e_entry dd phdr - $$ ; e_phoff dd 0 ; e_shoff dd 0 ; e_flags dw ehdrsize ; e_ehsize dw phdrsize ; e_phentsize dw 2 ; e_phnum dw 0 ; 3_shentsize dw 0 ; e_shnum dw 0 ; e_shstrndx ehdrsize equ $ - ehdr ; program header macros %define pt_load 1 %define p_align 0xf %define pf_rx 5 %define pf_rw 6 ; -------------------- ; program header table ; --------------------- phdr: dd pt_load ; p_type dd 0 ; p_offset dd $$ ; p_vaddr dd $$ ; p_paddr dd s1 ; p_filesize dd s1 ; p_memsize dd pf_rx ; p_flags dd p_align ; p_align phdrsize equ $-phdr phdr1: dd pt_load ; p_type dd dsegoff ; p_offset dd p_vadd1+psize ; p_vaddr dd p_vadd1+psize ; p_paddr dd dseglen ; p_filesize dd dseglen ; p_memsize dd pf_rw ; p_flags dd p_align ; p_align ; ---------------------------- ; start of segment definitions ; ---------------------------- _start: ; this will eventually hold sys_exit(0) s1 equ $-$$ dataseg: ; .data is zero bytes big ; linux 2.6.12+? requires explicit .data segment declaration d1 equ $-dataseg ; this part is very ugly.things look good in objdump so far.. i think.; i don't even know if this is right!!! ; align dataseg p_offset to an 8 byte boundary %assign liner (dataseg-$$) dsegoff equ (liner&-8)+8 p_vadd1 equ $$+(dsegoff) dseglen equ $-dataseg %assign multiplier (s1/0x1000)+1 assign psize 0x1000*multiplier ; -------------------- ; section header table ; --------------------
objdump -x elfhead
elfhead: file format elf32-i386
elfhead
architecture: i386, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x08048074
Program Header:
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x00000074 memsz 0x00000074 flags r-x
LOAD off 0x00000078 vaddr 0x08049078 paddr 0x08049078 align 2**12
filesz 0x00000000 memsz 0x00000000 flags rw-
Sections:
Idx Name Size VMA LMA File off Algn
SYMBOL TABLE:
no symbols
contructing the elf header was relatively easier than constructing the program header table thanks to the elf specification. i did look at the elf header example at the whirlwind tutorial from time to time to verify if i was still on the right track of course. objdumps of my former asm programs were very much useful since they provided some sort of blue print-cheat sheet for me.
understanding the difference between “file scope” and “virtal memory scope” was a bit of a stumbling block. again, thanks to my blue print-cheat sheet, i was able to understand those concepts. file scope is offset that is relative to zero. “virtual memory scope” is offset that is relative to the memory address i specified in nasm’s org directive, that being 0x08048000.
anyway, on to the meaty stuff. the code above starts off with an elf header that specifies two (2) program headers (e_phnum) for .text and .data sections respectively. i still haven’t covered the part about “section header table“. reading the elf spec some pages down sure takes a lot toll on your body! i hope to cover more ground tommorrow and post yet another progress report.
for now.. i need steph!
