goblin

repository·master·Indexed 23 days ago

https://github.com/m4b/goblin

A cross-platform Rust library for parsing, loading, and analyzing ELF, Mach-O, and PE binaries, as well as various archive formats. It provides zero-copy, endian-aware implementations supporting both 32-bit and 64-bit formats, with options for both std and no_std environments.

Tokens
16.8K
Snippets
34
Records
112
Agent score
81%

What's inside goblin

  1. Overview of libgoblin capabilities

    master

    libgoblin is a comprehensive library for binary parsing, loading, and analysis. It provides zero-copy, cross-platform, and endian-aware implementations for several major binary formats. Key features include:

    • ELF: 32-bit and 64-bit implementations.
    • Mach-O: 32-bit and 64-bit implementations.
    • PE: 32-bit and 64-bit implementations.
    • Archives: Unix and BSD style archive parsing.
    • Modes: Supports both std mode (for reading/writing files with allocations) and no_std mode (for core, #[repr(C)] struct definitions in constrained environments).
    • Endianness: Supports endian_fd for parsing binaries according to their internal endianness, useful for cross-platform analysis tools.
  2. Install libgoblin via Cargo

    master

    To use libgoblin in your Rust project, add it to your Cargo.toml dependencies. Note that libgoblin requires rustc 1.85.0 (Rust 2024 edition).

    [dependencies]
    goblin = "0.10"
  3. Build bingen using CMake and Ninja

    master

    To build the bingen test binary generator, use CMake with the Ninja generator and the clang-cl compiler. It is highly recommended to use Clang rather than the MSVC toolchain to ensure optimal binary size reduction and linker behavior (e.g., smarter metadata handling via LLD).

    Prerequisites:

    • 64-bit Windows host
    • CMake 3.12 or later
    • Ninja build system
    • Clang (ideally version 17 or later)
    mkdir build
    cd build
    cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang-cl
    cmake --build . --config release
  4. Build bingen using Visual Studio

    master

    You can build bingen using Visual Studio 2022 by opening the bingen.sln file located in etc/projects/bingen/. Ensure you select the Release configuration for compilation.

    Prerequisites:

    • 64-bit Windows host
    • Visual Studio 2022
    • C++ Clang Compiler for Windows (or a manually installed Clang toolchain)
    • MSBuild support for LLVM (clang-cl) toolset
  5. Reference a manually-installed Clang toolchain in Visual Studio

    master

    If Clang is not installed via Visual Studio individual components, you can point MSBuild to your manual installation by creating a Directory.build.props file in the same directory as the .sln file. Populate it with your specific LLVM installation path and version.

    <!-- Directory.build.props -->
    <Project>
      <PropertyGroup>
        <LLVMInstallDir>C:/path/to/llvm/bin</LLVMInstallDir>
        <LLVMToolsVersion>xx.xxxx.x</LLVMToolsVersion>
      </PropertyGroup>
    </Project>
  6. What is a Rich header and how to parse it?

    master

    The Rich header is an undocumented header used by Microsoft Visual Studio to store information about the build environment (e.g., tool versions and usage counts). It is located between the DOS header and the PE header.

    To parse it, use RichHeader::parse. You can then iterate over the decoded metadata using the metadatas() method, which returns a RichMetadataIterator. Each item in the iterator is a RichMetadata struct containing build, product, and use_count fields.

  7. What is a TE header?

    master

    A TE header is a reduced PE32/PE32+ header containing only the fields required for execution in the Platform Initialization (PI) architecture (UEFI). It is a stripped version of a standard PE header.

    To parse a TE header, use TeHeader::parse. Note that the parser automatically performs address fixups for the entry point, base of code, relocation directory, and debug directory to account for the stripped_size.

  8. Access parsed debug information in `DebugData`

    master

    The DebugData struct provides structured access to various types of debug information found in a PE file. Depending on the binary, the following fields may be populated:

    • codeview_pdb70_debug_info: Parsed CodeView PDB 7.0 (RSDS) info (contains GUID, age, and PDB path).
    • codeview_pdb20_debug_info: Parsed CodeView PDB 2.0 (NB10) info.
    • vcfeature_info: Visual C++ feature data (counts for guard stack, SDL, etc.).
    • ex_dll_characteristics_info: Extended DLL characteristics (e.g., CET compatibility).
    • repro_info: Reproducible build (Repro) information (either a 32-byte hash for MSVC or a timestamp for Clang/LLD).
    • pogo_info: Profile-guided optimization (POGO) data.

    You can also retrieve the debugging GUID used for matching against a PDB file using the .guid() method.

  9. Use Container and Ctx for parsing context

    master

    The container module provides abstractions for managing binary container size and byte-order context.

    • Container: An enum representing Little or Big endianness/container size.
    • Ctx: A struct that combines a Container and a scroll::Endian value to provide a complete parsing context.

    Ctx can be used to manage how addresses and endianness are interpreted during parsing.

  10. Structure of a GNU hash table

    master

    A GNU hash table is composed of four distinct sections in order:

    1. Header: An array of four u32 values:
      • nbuckets: Number of hash buckets.
      • symndx: Index of the first symbol in the .dynsym table accessible via the hash table.
      • maskwords: Number of words in the bloom filter (must be a power of two).
      • shift2: Shift count used in the bloom filter.
    2. Bloom Filter: A bitmask used to quickly rule out symbols not present in the table.
    3. Hash Buckets: An array of u32 values that index into both the symbol table and the chain table.
    4. Chains: An array of u32 values containing symbol table indexes and chain pointers.
  11. Use the unified Sym type for ELF symbols

    master
    The Sym struct provides a unified representation of ELF symbols, regardless of whether the underlying binary uses 32-bit (sym32::Sym) or 64-bit (sym64::Sym) symbol definitions. It provides helper methods to inspect symbol properties like binding, type, and visibility, and can be converted to/from the architecture-specific types.
  12. Understand the PE Optional Header structure

    master

    The OptionalHeader is a critical component of the Portable Executable (PE) NT headers. Despite its name, it is required for all PE image files. It is composed of three main parts:

    1. standard_fields (StandardFields): Contains unified COFF fields that are common to both 32-bit (PE32) and 64-bit (PE32+) binaries. The architecture (32 vs 64-bit) is determined by the magic field within these standard fields.
    2. windows_fields (WindowsFields): Contains Windows-specific fields (often called 'NT additional fields'). In goblin, WindowsFields is a type alias for WindowsFields64, providing a unified interface for both architectures.
    3. data_directories (DataDirectories): Contains an array of data directory entries describing locations and sizes of various PE data structures.

    The OptionalHeader is located in the PE binary after the CoffHeader and before the section table.