fold/docs/internal/binary-fuzz-corpus.md
trvon ffc7917957
feat: symbolic IR, swift backend, binary-to-fuzz pipeline, SARIF fixes
- Rust IR encoder (encodeRustIr): walks HIR expr trees, fires SafetyObserver hooks
- Swift SIL frontend (fold-swift): swiftc -emit-sil parser, demangling, NDJSON output
- SwiftBackend: --mode swift CLI routing, shells out to fold-swift
- Binary-to-fuzz: Mach-O export discovery, ARM64 ABI param-count inference, dlopen harness generation
- Language-agnostic IR: json_keys canonical constants, Call/Member/ArraySubscript/Cast/HeapNew nodes
- Dogfood fixes: SARIF kind field, cross-detector dedup, harness_file in predictions, Swift stoi safety
- Corpuses: swift-sil-z3-corpus.md, binary-fuzz-corpus.md
- AGENTS.md: cross-language wire format rule
2026-05-27 15:29:14 -04:00

4.5 KiB
Raw Permalink Blame History

Binary-to-Fuzz Pipeline Corpus

Generated 2026-05-27. Reference for Mach-O binary → ABI inference → harness → fuzz.

ARM64 Mach-O ABI (Apple Platforms)

Source: Apple "ARM64 Function Calling Conventions"

Register Assignment

Register Role
x0–x7 Integer/pointer arguments 0–7
d0–d7 Floating-point arguments 0–7
x8 Indirect result location
x9–x15 Temporary (caller-saved)
x16–x17 Intra-procedure-call scratch
x18 Platform register
x19–x28 Callee-saved
x29 (fp) Frame pointer
x30 (lr) Link register (return address)
sp Stack pointer

Parameter Count Inference Heuristic

For each exported function, r2 disassembles the first basic block. Count distinct register reads (not writes) among x0–x7 BEFORE the first call/branch. This estimates the parameter count.

Example: function reads x0, x1, x2 → 3 parameters
         function reads x0 only → 1 parameter
         function writes to x0, reads nothing → 0 parameters

Limitations:

  • Variadic functions are not detected
  • Struct-by-value arguments (passed via x8 indirect + x0 pointer) may be miscounted
  • Functions that stash args to callee-saved regs before use may be undercounted
  • Heuristic only — not a formal ABI analysis

Mach-O Structure

Section Contents
__TEXT,__text Executable code
__TEXT,__cstring C string literals
__DATA,__data Initialized data
__DATA,__bss Zero-initialized data
__LINKEDIT Export trie, symbol table, string table
__TEXT,__swift5_* Swift metadata sections

r2 Binary Analysis Commands (fold usage)

r2 Command Output fold Use
aflj Function list JSON Discover functions for fuzz targets
isj Symbol table JSON Resolve function names, classify exports
iEj Exports JSON Identify dlopen-able symbols
izzj String catalog JSON Existing binary security detector path
pdbj @ addr Basic block disassembly JSON ABI parameter-count inference
afij @ addr Function info JSON Function boundaries, call graph

dlopen Harness Pattern

Source: rev.ng blog, AFL++ binary-only fuzzing docs

// Auto-generated by fold binary-fuzz-prep
// Target: /path/to/library.node or Mach-O binary
#include <dlfcn.h>
#include <stdint.h>
#include <stddef.h>

// Resolved function pointers
typedef void (*target_fn_t)(uint64_t, uint64_t, uint64_t);
static target_fn_t target_fn = NULL;

// One-time library load
__attribute__((constructor))
static void load_library(void) {
    void* handle = dlopen("TARGET_PATH", RTLD_NOW);
    if (handle) {
        target_fn = (target_fn_t)dlsym(handle, "TARGET_SYMBOL");
    }
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    if (!target_fn || size < 24) return 0; // 3 × uint64_t
    uint64_t arg0, arg1, arg2;
    memcpy(&arg0, data + 0,  8);
    memcpy(&arg1, data + 8,  8);
    memcpy(&arg2, data + 16, 8);
    target_fn(arg0, arg1, arg2);
    return 0;
}

Compile:

clang++ -fsanitize=fuzzer,address -g -O1 harness.cc -o harness.fuzz

Prior Art

Source Relevance
rev.ng blog "Fuzzing binaries with libFuzzer" dlopen + harness pattern for Mach-O/ELF
arXiv 2306.15596 "Automated Fuzzing Harness Generation" API fuzzing harness synthesis
AFL++ binary-only docs dlopen-based library fuzzing with persistent mode
Romain Thomas "Fuzzing Windows ARM64" ARM64 binary fuzzing with QBDI
JMPscare (BAR 2021) Introspection for binary-only fuzzing
"Binary-level directed fuzzing" (ANSSI thesis) Directed fuzzing of closed-source binaries

Integration Architecture

Mach-O binary → r2 aflj → function list
                    ↓
              r2 pdbj @ addr → param count (ABI inference)
                    ↓
              harness_emitter → dlopen C harness
                    ↓
              clang++ -fsanitize=fuzzer,address → harness.fuzz
                    ↓
              libFuzzer + ASan → crash artifacts
                    ↓
              ASan parser → ConcreteWitness findings

References

  • Apple ARM64 ABI: https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
  • rev.ng binary fuzzing: https://rev.ng/blog/fuzzing-binaries
  • AFL++ binary-only: https://aflplus.plus/docs/fuzzing_binary-only_targets/
  • arXiv 2306.15596: Automated Fuzzing Harness Generation for Library APIs
  • r2 book: https://book.rada.re/