Reading — step 1 of 5
Read
~1 min readProduction
Production Concerns
Real ELF tooling considerations:
Build IDs:
- Each binary has a unique build ID hash in
.note.gnu.build-id. - Used by debug info servers (debuginfod) to fetch matching debug symbols.
- Standard in modern Linux distros.
Debug info:
.debug_info,.debug_line, etc. (DWARF format).objcopy --strip-debugseparates debug info.- Distros ship
package-dbgwith debug info; main package without.
Stripping:
strip: remove symbols + debug info.- Smaller binaries.
- Harder to debug crashes.
Hardening:
- PIE: ASLR.
- RELRO: GOT integrity.
- NX: PT_GNU_STACK with no X (executable stack disabled).
- Stack canaries: detect buffer overflows.
- Fortify source: bounds-checked libc functions.
- All controlled via compiler flags + linker flags.
checksec (Brutal hardening checker):
RELRO STACK CANARY NX PIE RPATH RUNPATH
Full Yes Yes Yes No No
Custom loaders:
- musl-libc: alternative C library + linker.
- ldso/musl-ldso: lighter than glibc.
- mold (linker): faster than gold/ld for big projects.
- LLD: LLVM's linker.
Compatibility:
- ELF used by Linux, BSD, Solaris, Haiku, plenty more.
- Windows: PE (different).
- macOS: Mach-O (different).
- WebAssembly: own format.
Security pitfalls:
- LD_PRELOAD on suid binaries: ignored (security).
- DT_RPATH with $ORIGIN: relative to binary location. Good for portable apps; risky if writable.
- Buggy symbol resolution → memory corruption.
Debug tools:
readelf -a: comprehensive view.objdump: disassembly + sections.nm: symbols.ltrace: library call tracing.strace: syscall tracing.gdb: debugger.
Don't roll your own:
- Binutils (ld, readelf, etc.) is mature.
- LLVM toolchain (lld) is modern.
- ELF spec is dozens of pages but real-world has many edge cases.
Do:
- Understand the format.
- Read
man elf. - Use existing libraries (libelf, GNU BFD).
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…