Lion Cipher Lab

Take an ELF binary apart and watch dynamic linking happen

Why it matters

Every compiled program you will ever analyze -- a piece of malware, a CTF binary, a service you are defending, a crash you are debugging -- arrives as an ELF file, and the single biggest gap between a beginner and someone who can read one is understanding what happens between `./program` and `main()` actually running. For a dynamic executable that gap is enormous: the kernel doesn't run your program at all, it runs the dynamic linker, which finds libc and every other shared library, maps them in, and rewrites a table of pointers so that your `printf` call lands in the real libc code. Miss…

What you'll learn

Steps in this lab

  1. The one idea: the kernel does not run your dynamic program -- it runs a linker that wires it up first
  2. Get a Linux x86-64 shell and the binutils toolchain
  3. Compile one program two ways: dynamic (default) vs -static
  4. Read the ELF header: the 64-byte cover page every ELF starts with
  5. Segments vs sections: the loader reads segments, the linker reads sections -- and .bss is a beautiful lie
  6. Symbols and the dynamic section: which libraries, which functions, which versions
  7. The PLT and GOT: how a call to puts actually reaches libc
  8. Watch the dynamic linker work: ldd and LD_DEBUG
  9. Lazy vs eager binding: catch a GOT slot pointing back at its own PLT stub
  10. The payoff: function interposition with LD_PRELOAD
  11. The programmatic side: load a plugin at runtime with dlopen/dlsym
  12. Named failure modes: "not found", version mismatch, and RUNPATH hijack
  13. The judgment: what you can now read, and the labs this unlocks

Open the full interactive lab →