Leanpub Header

Skip to main content

Mastering ELF: From Bytes to Execution

Mastering ELF: From Bytes to Execution
This book is 100% completeLast updated on 2026-10-27

A Deep Systems Engineering Guide to ELF64 Internals, Dynamic Linking, Kernel Loading, Binary Instrumentation, and Executable Runtime Architecture

Every executable binary contains more than machine instructions. It encodes the structural information, symbol relationships, relocation rules, memory mappings, and runtime metadata required to transform compiled code into a functioning process. Understanding this transformation requires looking beyond compiler output and examining the mechanisms that connect binary formats, operating-system loaders, dynamic linkers, virtual memory, and processor execution.

Mastering ELF: From Bytes to Execution is a comprehensive, implementation-focused engineering reference to the Executable and Linkable Format (ELF), with a particular emphasis on ELF64 internals and low-level runtime behavior. Across 50 chapters, it follows the complete execution pipeline from raw binary structures and defensive parsing to kernel-space loading, dynamic symbol resolution, thread-local storage, exception unwinding, executable modification, and custom loader architecture.

Minimum price

$27.55

$27.55

You pay

Author earns

$

Also available for 1 book credit with a Reader Membership

PDF
583
Pages
Discussion Forum
About

About

About the Book

Mastering ELF: From Bytes to Execution

A Deep Systems Engineering Guide to ELF64 Internals, Dynamic Linking, Kernel Loading, Binary Instrumentation, and Executable Runtime Architecture

Every executable binary contains more than machine instructions. It encodes the structural information, symbol relationships, relocation rules, memory mappings, and runtime metadata required to transform compiled code into a functioning process. Understanding this transformation requires looking beyond compiler output and examining the mechanisms that connect binary formats, operating-system loaders, dynamic linkers, virtual memory, and processor execution.

Mastering ELF: From Bytes to Execution is a comprehensive, implementation-focused engineering reference to the Executable and Linkable Format (ELF), with a particular emphasis on ELF64 internals and low-level runtime behavior. Across 50 chapters, it follows the complete execution pipeline from raw binary structures and defensive parsing to kernel-space loading, dynamic symbol resolution, thread-local storage, exception unwinding, executable modification, and custom loader architecture.

The book approaches ELF as a systems engineering discipline rather than a collection of file-format definitions. It examines how individual fields influence loading decisions, how relocation records connect compiled components, how dynamic linkers resolve dependencies, and how memory permissions and runtime structures shape the behavior of executable programs.

The result is a detailed exploration of the mechanisms that make native software loadable, linkable, inspectable, and executable on modern ELF-based systems.

What You Will Learn

Understand the internal organization of ELF64 binaries, including header fields, machine identification, endianness, word size, section headers, string tables, symbol tables, symbol versioning, and dynamic metadata. Explore the differences between file offsets, virtual addresses, sections, and loadable segments, and learn how robust parsers validate binary structures without relying on assumptions about the input.

Examine the architecture of symbol resolution, including symbol binding, visibility, version dependencies, the traditional System V hash table, and the GNU hash table with its Bloom-filter-based lookup acceleration. Understand how these mechanisms influence dynamic linking and the resolution of functions and data across shared libraries.

Investigate the transition from an executable file to a running process. Follow the execve interface into the Linux ELF loader, examine the responsibilities of binfmt_elf.c, and explore how program headers, PT_LOAD segments, memory alignment, page granularity, process arguments, environment variables, and the auxiliary vector contribute to initial process construction.

Develop a deeper understanding of relocation mechanics across x86-64 and AArch64. Explore relocation addends, absolute and PC-relative references, instruction-level relocation behavior, the Global Offset Table (GOT), the Procedure Linkage Table (PLT), lazy binding, dynamic resolver trampolines, copy relocations, and the implementation of partial and full RELRO.

Explore thread-local storage from its binary representation to its runtime implementation. Examine TLS models, thread control blocks, segment registers, allocation strategies, and the initialization requirements that allow compiled code to access thread-specific data efficiently.

Build practical systems knowledge through custom binary tooling and runtime components. The book covers a zero-dependency ELF64 parser in C, a userland static loader, custom dynamic-linker architecture, DWARF-based stack unwinding, position-independent code, compiler and linker code generation, Build ID verification, and the structural consequences of stripping and binary modification.

The final chapters examine executable instrumentation and advanced binary engineering, including dynamic section and segment injection, GOT and PLT interception, inline hooking, detour trampolines, control-flow protections, in-memory ELF execution, binary obfuscation, and packer architecture.

From Raw Bytes to a Validated Binary Model

Reliable binary engineering begins with correctly interpreting the data on disk. ELF files contain structures with architecture-dependent fields, alignment constraints, offsets, counts, and references between different regions of the file. An incorrect assumption about any of these elements can produce invalid parsing results or unsafe memory access.

This book explores ELF64 header anatomy, byte order, machine identification, section header tables, string tables, and symbol representations as interconnected parts of a binary format. It examines how structural validation, boundary checks, and careful handling of untrusted metadata contribute to robust parsing engines.

The discussion extends to symbol versioning and dynamic hash structures, connecting the representation of symbols to the algorithms used to locate them. The System V hash table and GNU hash table illustrate different approaches to symbol lookup, while GNU hash Bloom filters demonstrate how compact probabilistic structures can accelerate searches.

Particular attention is given to the distinction between descriptive file structures and the structures that govern runtime loading. Sections organize information for linking and analysis; program headers describe the segments and interpreter requirements relevant to execution.

Understanding this distinction provides the foundation for every subsequent stage of the ELF lifecycle.

Kernel Loading and Process Construction

Loading an executable is a coordinated operation involving the operating system, virtual memory, the executable format, and the process startup environment.

The book examines the Linux execve interface and the ELF loader implementation in binfmt_elf.c, tracing how an executable's program headers influence the construction of a process image. It explores PT_LOAD mappings, page alignment, memory permissions, zero-initialized memory regions, and the interpreter path specified by PT_INTERP.

Process startup also requires more than mapping executable segments. Arguments, environment variables, and the auxiliary vector establish information required by the runtime environment. The book examines how this initial state is constructed and how the virtual dynamic shared object (vDSO) provides selected kernel services through a user-space interface.

Security-related program headers receive dedicated treatment, including PT_GNU_STACK, PT_GNU_RELRO, and PT_GNU_PROPERTY. These structures connect binary metadata to runtime protections and platform-specific security features.

The objective is to understand the loading pipeline as an explicit sequence of operating-system and runtime responsibilities, rather than treating executable startup as a black box.

Dynamic Linking, Relocations, and Symbol Resolution

Modern native applications depend on a network of executable components, shared libraries, symbols, and relocation records. The dynamic linker coordinates these relationships and establishes the addresses required for code and data references to work correctly.

This book examines relocation semantics, including the role of addends, relocation targets, and architecture-specific calculations. It covers x86-64 and AArch64 relocation mechanisms, highlighting the relationship between binary metadata, instruction encoding, address calculations, and position-dependent references.

The GOT and PLT provide a central example of how ELF connects compiled call sites to dynamically resolved functions. Through lazy binding, resolver trampolines, and runtime symbol lookup, these structures allow references to shared-library functions to be resolved according to the applicable linking rules.

The discussion also explores copy relocations, symbol interposition, dependency resolution, loaded-module tracking, and the runtime link map. Techniques such as LD_PRELOAD illustrate how symbol precedence can influence application behavior, while symbol versioning helps explain how libraries manage interfaces across different releases.

RELRO provides another important connection between linking and runtime memory protection. The book examines partial and full RELRO in terms of relocation processing and the protection of relevant memory regions after initialization.

Together, these topics provide a detailed architectural understanding of how independently compiled components become a functioning process.

Thread-Local Storage and Runtime Initialization

Thread-local storage allows each thread to access its own instance of selected data without requiring every access to pass through an explicit lookup mechanism. Implementing this behavior efficiently depends on compiler conventions, executable metadata, thread initialization, and runtime memory management.

The book examines static and dynamic TLS models, including Local Exec, Initial Exec, General Dynamic, and Local Dynamic. It explores the role of thread control blocks, architecture-specific segment registers, and the runtime allocation of thread-local storage.

The discussion connects these mechanisms to the dynamic linker's bootstrap process, including self-relocation in position-independent code. This is a particularly important systems problem: the runtime linker must establish enough of its own execution environment to perform the work required to load and link other components.

By examining TLS and bootstrap initialization together, the book reveals how low-level runtime infrastructure establishes the conditions required for more complex linking and execution operations.

Building ELF Parsers, Loaders, and Dynamic-Linking Infrastructure

Understanding a binary format becomes more valuable when its structures can be processed by working software.

This book explores the architecture of a zero-dependency ELF64 parser written in C, emphasizing direct access to binary structures, defensive validation, and explicit interpretation of metadata. It then extends the discussion to userland loading and custom dynamic-linker architecture.

A static loader must reproduce the loading responsibilities relevant to its supported execution environment, including segment mapping, memory initialization, and transfer of control. A dynamic linker introduces additional complexity through dependency discovery, symbol resolution, relocations, and runtime module management.

The book examines these components as distinct but related engineering challenges. It highlights the importance of separating parsing from execution, validating inputs before acting on them, respecting architecture-specific rules, and accounting for the operating system's role in process creation and memory management.

These foundations are useful for systems programmers, runtime engineers, researchers, and developers investigating how executable infrastructure works beneath familiar development tools.

DWARF, Exception Frames, and Stack Unwinding

Executable behavior is not limited to the instructions that run successfully along the normal control path. Debugging, exception handling, profiling, and runtime diagnostics may depend on metadata describing how execution state can be reconstructed as the program moves through its call stack.

The book examines .eh_frame, .eh_frame_hdr, Call Frame Information (CFI), Common Information Entries, and Frame Description Entries. It explores how these structures describe the information required to recover register state and traverse stack frames.

The discussion extends to the design of a userland unwinding engine that interprets DWARF-related instructions. This connects the binary representation of unwind metadata to the algorithms needed to reconstruct execution context.

Position-independent code, position-independent executables, and compiler and linker code generation provide the broader context for understanding how code layout and runtime addresses interact with these mechanisms.

The result is a systems-level perspective on the relationship between compiled output, runtime state, and the metadata that makes execution easier to inspect and recover.

Binary Identity, Modification, and Instrumentation

ELF engineering also involves examining how binaries can be identified, modified, instrumented, and protected.

The book covers GNU Build IDs and their use in identifying binary artifacts, along with static and dynamic stripping and the removal of identifiers or other nonessential information. These topics illustrate the difference between reducing a binary's metadata and preserving the structural requirements for successful execution.

Further chapters explore in-place machine-code modification, dynamic section and segment injection, GOT and PLT interception, and inline function hooking through detour trampolines. These techniques reveal how binary structure, address calculations, calling conventions, memory permissions, and instruction boundaries constrain executable modification.

The book also examines security mechanisms including Control-Flow Integrity, Intel Control-flow Enforcement Technology (CET), and ARM Pointer Authentication Codes (PAC) and Branch Target Identification (BTI). These mechanisms demonstrate how processor capabilities, compiler output, binary properties, and runtime enforcement work together to constrain control-flow manipulation.

Advanced topics include in-memory ELF execution using mechanisms such as memfd_create, custom symbol and section obfuscation, and ELF packer architecture involving self-decrypting stubs and memory reconstruction.

These subjects are presented as binary engineering and runtime architecture topics, with attention to structural correctness, platform behavior, and the security implications of modifying executable code.

Who Is This Book For?

This book is intended for systems programmers, Linux developers, C and C++ engineers, compiler and toolchain developers, runtime engineers, reverse engineers, binary analysts, and security researchers working with native executable formats.

It is particularly relevant to practitioners who want to understand Linux program loading, investigate dynamic-linking failures, implement binary inspection tools, explore custom loaders, analyze compiled software, or study the relationship between executable metadata and runtime behavior.

Readers should have a working understanding of programming, memory addressing, and basic computer architecture. Familiarity with C, assembly language, Linux, compiler toolchains, and virtual memory will help readers engage with the implementation-oriented material. Knowledge of x86-64 or AArch64 assembly is useful for the architecture-specific chapters.

Why This Book?

Executable files are often treated as finished products of a compiler. Yet their internal structures determine how code is linked, how memory is organized, how libraries are resolved, and how execution begins.

Understanding ELF means understanding the interfaces between compilers, linkers, loaders, operating systems, shared libraries, and processors. It also means recognizing that a binary is not simply a collection of instructions, but a structured artifact interpreted by multiple layers of software and hardware.

Mastering ELF: From Bytes to Execution brings these layers together in a unified engineering framework spanning ELF64 parsing, kernel loading, relocation processing, dynamic linking, TLS, runtime initialization, DWARF unwinding, binary instrumentation, and executable hardening.

Across 50 chapters, the book provides a foundation for investigating native binaries at the level where file structures become memory mappings, symbols become addresses, and compiled code becomes a running process.

50 Chapters. ELF64. Linux Kernel Loading. Dynamic Linking. x86-64 and AArch64. Custom Loaders. DWARF. Binary Instrumentation. Runtime Security.

From bytes to structures. From relocations to resolved symbols. From executable files to runtime behavior.

Understand the binary. Master the loader. Trace every step from bytes to execution.

Author

About the Author

Krzysztof Rybiński

I am an independent technology developer and systems engineer who built my technical path largely through self-directed engineering, experimentation, and continuous learning outside a traditional academic or corporate technology career.

My professional background began far from the technology industry. I spent years working in manufacturing, while independently developing my knowledge of software engineering, computer systems, and advanced computing. Over time, that self-directed work evolved into a broad technical practice spanning autonomous AI, cybersecurity, systems programming, GPU computing, automation, and advanced computational architectures.

Today, I design, build, and publish projects involving agentic AI, autonomous defense systems, SIEM/EDR integration, secure software architecture, C/C++, Go, Python, CUDA, quantum computing, cryptography, and privacy-oriented local AI infrastructure.

I approach technology from a systems perspective — from low-level software, memory architecture, and GPU performance to distributed systems, intelligent agents, and high-assurance security architectures.

I also explore aerospace and high-assurance software concepts, including safety-critical architectures, multi-level security, cross-domain solutions, and advanced computational systems.

Alongside active development, I publish long-form engineering projects covering AI, cybersecurity, cloud engineering, quantum computing, GPU programming, cryptography, automation, blockchain, and aerospace engineering.

My current focus is on autonomous software agents, privacy-first local infrastructure, advanced computing, and reliable systems designed to operate with a high degree of independence.

I am open to opportunities involving AI engineering, cybersecurity, software engineering, autonomous systems, HPC/GPU computing, and advanced technology development.

https://businessofmachines.blogspot.com/

https://learn.microsoft.com/en-us/users/machinadeusex/

https://g.dev/machinadeusex

https://github.com/porucznikswext-source

https://www.linkedin.com/in/krzysztof-r-93a37b287/

Get the free sample chapters

Click the buttons to get the free sample in PDF or EPUB, or read the sample online here

Also by the Author

Also by the Author

The Leanpub 60 Day 100% Happiness Guarantee

Within 60 days of purchase you can get a 100% refund on any Leanpub purchase, in two clicks.

See full terms...

Earn $8 on a $10 Purchase, and $16 on a $20 Purchase

We pay 80% royalties on purchases of $7.99 or more, and 80% royalties minus a 50 cent flat fee on purchases between $0.99 and $7.98. You earn $8 on a $10 sale, and $16 on a $20 sale. So, if we sell 5000 non-refunded copies of your book for $20, you'll earn $80,000.

(Yes, some authors have already earned much more than that on Leanpub.)

Learn more about writing on Leanpub

Free Updates. DRM Free.

If you buy a Leanpub book, you get free updates for as long as the author updates the book! Many authors use Leanpub to publish their books in-progress, while they are writing them. All readers get free updates, regardless of when they bought the book or how much they paid (including free).

Most Leanpub books are available in PDF (for computers) and EPUB (for phones, tablets and Kindle). The formats that a book includes are shown at the top right corner of this page.

Finally, Leanpub books don't have any DRM copy-protection nonsense, so you can easily read them on any supported device.

Learn more about Leanpub's ebook formats and where to read them

Write and Publish on Leanpub

You can use Leanpub to easily write, publish and sell in-progress and completed ebooks and online courses!

Leanpub is a powerful platform for serious authors, combining a simple, elegant writing and publishing workflow with a store focused on selling in-progress ebooks.

Leanpub is a magical typewriter for authors: just write in plain text, and to publish your ebook, just click a button. (Or, if you are producing your ebook your own way, you can even upload your own PDF and/or EPUB files and then publish with one click!) It really is that easy.

Learn more about writing on Leanpub