This file documents which fields can be safely corrupted, overlapped, or filled with code, while still being loadable by GNU ld.so via LD_PRELOAD. Information gathered via experimentation. This list may be incomplete.
A checkmark means this field is ignored, a plus means part of the field is ignored. offsets are in hex.
Elf64_Ehdr:
- 00-10: e_ident
- 10-12: e_type
- 12-14: e_machine
- 14-18: e_version
- 18-20: e_entry
- 20-28: e_phoff
- 28-30: e_shoff
- 30-34: e_flags
- 34-36: e_ehsize
- 36-38: e_phentsize
- 38-3a: e_phnum
- 3a-3c: e_shentsize
- 3c-3e: e_shnum
- 3e-40: e_shstrndx
Elf64_Phdr:
- 00-04: p_type
- [+] 04-08: p_flags (only lowest 3 bits actually matter)
- [+] 08-10: p_offset (ignored for non-LOAD segments)
- 10-18: p_vaddr
- 18-20: p_paddr
- [+] 20-28: p_filesz (ignored for non-LOAD segments)
- [+] 28-30: p_memsz (ignored for non-LOAD segments, must be larger than filesz for LOAD segments)
- [+] 30-38: p_align (ignored for non-LOAD segments)
Elf64_Dyn:
- [+] 00-08: d_tag (ignored if unrecognized by loader)
- [+] 08-10: d_val / d_ptr (ignored if tag unrecognized by loader)
Notes:
- GNU ld.so seems to want to write into the dynamic table
(make your LOAD segment RWX) - GNU ld.so seems to require at least a DT_SYMTAB and DT_STRTAB entry, though they can both point to EOF
(maybe strtab and symtab can also point into garbage, though I didn't test what ld.so does with that)