Master the fundamental concepts of binary formats through this focused micro-challenge.
After the ELF header comes the section header table, which describes all sections in the file. Sections are the building blocks for linking: .text holds code, .data holds initialized globals, .bss reserves space for zero-initialized data.
Each Elf64_Shdr entry contains:
sh_name: Offset into .shstrtab for the section namesh_type: Section type (PROGBITS, SYMTAB, STRTAB, NOBITS, etc.)sh_flags: Writable, allocatable, executablesh_offset: File offset to section datash_size: Size in bytesCommon flags you will encounter:
SHF_WRITE (0x1): Writable at runtimeSHF_ALLOC (0x2): Loaded into memorySHF_EXECINSTR (0x4): Contains executable instructionsFor example, .text typically has SHF_ALLOC | SHF_EXECINSTR, while .data has SHF_WRITE | SHF_ALLOC.
You will walk the section header table and list every section with its name, type, flags, offset, and size. This is exactly what readelf -S prints, and reverse engineers scan section flags first when triaging an unfamiliar binary.
The section count lives in e_shnum, and each entry is e_shentsize bytes wide. You iterate from e_shoff to e_shoff + e_shnum * e_shentsize, resolving each name through .shstrtab. Linkers merge sections with compatible flags during linking, and loaders map only sections with SHF_ALLOC set into the process address space at runtime.
Implement an ELF section header lister in C.
Requirements:
Test:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it works