Architecture, Internals, Parsing, Linking, Loading and Runtime Execution
Introduction
Chapter 1: Why Binary Formats Matter
- The Role of Executable Formats in System Design
- From A.OUT to ELF to Mach-O
- Object Files vs Executables vs Shared Libraries
- The Linker and Loader as Format Interpreters
- Why Mach-O on Apple Platforms
Chapter 2: Computer Architecture Fundamentals for Binary Formats
- Instruction Set Architectures and Endianness
- Virtual Memory and Address Spaces
- Alignment, Padding and Data Layout
- Position-Dependent vs Position-Independent Code
- Calling Conventions and ABI Requirements
Chapter 3: The Mach-O Header
- Magic Numbers and Architecture Identification
- The fat_header and FAT Architecture Descriptors
- thin_struct (32-bit) and mach_header_64 (64-bit)
- Platform-Specific Flags: MH_NOUNDEFS, MH_PIE, MH_DYLIB and Beyond
- File Types
- Version History and Compatibility Guarantees
Chapter 4: FAT and Universal Binaries
- The FAT File Format Specification
- Fat Architectures: cputype, cpusubtype and Alignment
- Construction and Extraction with lipo
- Historical Context: PowerPC to Intel Transition
- Modern Universal Binaries and Rosetta 2
Chapter 5: Load Commands: The Nervous System of Mach-O
- Load Command Structure and Parsing
- LC_SEGMENT vs LC_SEGMENT_64
- LC_SYMTAB, LC_STRTAB, LC_DYSYMTAB
- LC_LOAD_DYLIB Family and Dependencies
- LC_RPATH, LC_ID_DYLIB, LC_MAIN, LC_UNIXTHREAD
- Platform-Specific Load Commands (iOS, watchOS)
Chapter 6: Segments and Memory Mapping
- Segment Design and Protection Flags
- Standard Segments: __TEXT, __DATA, __DATA_CONST, __LINKEDIT
- Non-Standard and Platform-Specific Segments
- Segment Alignment, File Offsets and Virtual Addresses
- Virtual Address to File Offset Translation
Chapter 7: Sections, Section Types and Section Flags
- Section Header Structure and Field Semantics
- Code Sections: __text, __stubs, __stub_helper, __got, __lazy_symbol_pointers
- Data Sections: __data, __const, __rodata, __cstring, __const
- BSS and Zero-Fill Sections
- Special Sections: __mod_init_func, __mod_term_func, _objc*
Chapter 8: Symbol Tables and String Tables
- nlist and nlist_64 Structures
- The String Table: Layout, Offsets and Null Termination
- Symbol Table Layout and Symbol Sorting
- Global vs Local Symbols: Binding and Visibility
- Special Symbols: _mh_header, __mh_execute_header, _dyld_func_lookup
Chapter 9: Relocation Records and Position Independence
- Relocation Record Structures (32-bit and 64-bit)
- External vs Internal Relocations
- Absolute, PC-Relative and Scatter Relocations
- Relocations in Object Files vs Executables
- Runtime Relocations and the LINKEDIT Segment
Chapter 10: The Dynamic Symbol Table
- dysymtab_command Structure
- Symbol Table Indices: ilocalsym, iextdefsym, iundefsym
- Indirect Symbol Table: Layout, Encoding and Null Entries
- The Local Symbol Table and Debugging
- Export and Import Symbol Resolution
Chapter 11: Dynamic Library Loading
- Library Identification: LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB
- Library Paths: ID, Install Name, Run Path, @rpath, @executable_path
- rpath Resolution and Search Order
- Weak Linking and Conditional Dependencies
- Library Reexports and Symbol Reexports
Chapter 12: dyld Architecture and Internals
- dyld Initialization and Bootstrap
- Image Loading and Memory Mapping
- Shared Cache Architecture
- Symbol Binding: Non-Lazy vs Lazy Binding
- Two-Level Namespace and Flat Namespace
- dyld Interposition and Function Hooking
Chapter 13: Initialization, Finalization and Thread-Local Storage
- Initializer Mechanisms: LC_ROUTINES, __mod_init_func, __objc_init
- Initialization Ordering and Dependency Graphs
- Terminators and Shutdown
- Thread-Local Storage in Mach-O: __thread, LC_SEGMENT_64 TLS segments
- TLS Models: Local-Exec, Initial-Exec, Local-Dynamic, Global-Dynamic
Chapter 14: Chained Fixups
- Motivation for Chained Fixups
- The LC_DYLD_CHAINED_FIXUPS Payload
- Chain Pointer Structures: chained_fixup_pointer_64
- Fixup Kinds: Target Address, Addend, Rebase, Bind
- Parsing and Traversing Fixup Chains
- Platform-Specific Chained Fixup Variants
Chapter 15: Export Tries and Compressed Symbol Information
- Export Info Load Command
- The Export Trie Data Structure
- Trie Encoding: Terminal Nodes, Edges, Re-export Encoding
- Parsing Algorithms for Export Tries
- Size Savings and Performance Implications
- Export Version Info and Platform Compatibility
Chapter 16: Rebase and Bind Operations
- LC_DYLD_INFO: Rebase and Bind Streams
- Rebase Operands and Encodings
- LC_BIND Operations for Symbol Binding
- Weak Bind, Lazy Bind and Re-export Streams
- Optimization Through Compressed Operations
- Relationship to Chained Fixups
Chapter 17: ARM64 and ARM64e Architecture Specifics
- ARM64 in Mach-O: cputype, cpusubtype, Instruction Encoding
- ARM64 Relocations and Fixup Kinds
- ARM64e and Pointer Authentication
- PAC Signing: aarch64-specific Instructions and Metadata
- Pointer Mask Bits and Branch Protection
- Platform Requirements and Compatibility
Chapter 18: Platform Differences: macOS vs iOS vs watchOS vs tvOS
- Platform-Specific Load Commands
- Security Requirements by Platform
- Signing and Entitlements Differences
- System Library Layout and Paths
- Debug Symbols and Distribution Binaries
Chapter 19: Code Signing Architecture
- The LC_CODE_SIGNATURE Load Command
- __LINKEDIT and Code Signature Data Layout
- SuperBlob Structure and Subblob Types
- The CodeDirectory: Hashes, Teams, Identifiers
- Requirements and the Requirements Blob
- Entitlements and Provisioning Profiles
Chapter 20: Hardened Runtime, Notarization and Runtime Security
- Hardened Runtime and Library Validation
- Notarization and Gatekeeper
- Entitlements and Capabilities
- Library Load Restrictions and dyld Shared Cache
- Sandbox and Mach-O Interaction
- Secure Boot and Code Signing Chain
Chapter 21: Command-Line Analysis Tools
- file, otool, nm and lipo Fundamentals
- dyld_info: Dependencies, Exports and Bindings
- codesign: Verification, Entitlements and Requirements
- llvm-readobj and llvm-objdump (Cross-Platform)
- LLDB: Examining Memory Layout and Symbols
Chapter 22: Building a Mach-O Parser in C
- Design Decisions and Module Architecture
- Reading and Validating FAT Headers
- Parsing Mach-O Headers and Architectures
- Safe Load Command Iteration with Bounds Checking
- Segment and Section Enumeration
- Symbol Table and String Table Extraction
Chapter 23: Advanced Parsing: Exports, Fixups and Signatures
- Export Trie Parsing Implementation
- Chained Fixup Decoding
- Code Signature Inspection and Validation
- Virtual Address to File Offset Mapping
- Structural Validation and Error Reporting
- Test Cases and Verification Against Apple Tools
Chapter 24: The Mach-O Toolchain Lifecycle
- clang Compilation and Assembly Generation
- Object File Creation and Format
- Static Linking with libtool
- Dynamic Linking with ld
- Code Signing and Distribution
- Runtime Loading and Execution Trace
Chapter 25: Reverse Engineering and Forensic Analysis
- Identifying Binary Type and Architecture
- Reconstructing Symbol Information
- Analyzing Dependencies and Strings
- Locating Entry Points and Initializers
- Understanding Control Flow from Sections
- Common Anti-Analysis Techniques
Conclusion
- What Mach-O Design Reveals About Apple’s Philosophy
- Ongoing Evolution and Open Questions
- The Future of Binary Formats on Apple Platforms