fold/docs/internal/binary-backend-architecture-v2.md
trvon d40707c6a7
design: BinaryIR + BinaryDetector pipeline v2
- BinaryExprKind enum (8 kinds): HardcodedString, CallSite, VtableEntry...
- 8 BinaryFindingKind values for binary-specific vulnerabilities
- Detector pipeline mirrors source architecture (standalone functions)
- Phase plan: 4 phases, target 3.7% → 40%+ detection
2026-05-29 20:22:02 -04:00

3.1 KiB

fold Binary Backend Architecture v2 — BinaryIR + BinaryDetector Pipeline

Status: Design (May 2026) Scope: IR, finding taxonomy, detector pipeline for binary/hybrid scan modes

Problem

CTF evaluation showed 3.7% binary detection vs 66.7% source. The binary backend lacks:

  1. Structured IR between r2 data and findings (source has ir::Expr trees)
  2. Detector pipeline (source has 20+ detectors with observer hooks)
  3. Type-aware findings (binary findings are opaque strings)

BinaryIR Design

Mirrors the source IR architecture (include/fold/ir/expr.hpp) but for binary constructs:

enum class BinaryExprKind : uint8_t {
    // Data discovery
    HardcodedString,    // "password", "http://", key patterns
    ImportedSymbol,     // dlsym/GetProcAddress targets
    SectionData,        // .rodata, .data, .text section references
    
    // Control flow
    BasicBlock,         // Disassembled basic block
    CallSite,           // Call instruction with target
    IndirectCall,       // Call through register/memory
    
    // Data flow  
    StringXref,         // Code referencing a string
    DataXref,           // Data referencing data
    CodeXref,           // Code referencing code
    
    // Structure
    ExportEntry,        // Exported function
    VtableEntry,        // Virtual table slot
    SwitchTable,        // Jump table
};

BinaryFindingKind

New finding kinds for binary-specific vulnerabilities:

Finding What it detects Confidence
HardcodedUrl HTTP/HTTPS URLs in .rodata Syntactic
HardcodedPassword "password", "passwd" patterns Heuristic
StackString String built on stack (obfuscation) Heuristic
SuspiciousImport system(), exec(), popen() imports Syntactic
PackedSection UPX/ASPack detection Syntactic
MissingStackCookie No __stack_chk_fail import Heuristic
WritableXSegment RWX memory regions Syntactic
UnresolvedIndirectCall Call through register without known target Heuristic

BinaryDetector Pipeline

Mirrors source detector architecture:

Binary (Mach-O/ELF) → R2Backend → BinaryIR tree → BinaryDetector → Finding
                                        ↓
                              BinaryExpr nodes flow through
                              detector pipeline like source
                              ir::Expr flows through ASTVisitor

Each detector is a standalone function:

std::vector<Finding> detectHardcodedStrings(const BinaryIRTree& tree);
std::vector<Finding> detectSuspiciousImports(const BinaryIRTree& tree);
std::vector<Finding> detectPackedSections(const BinaryIRTree& tree);

Implementation Plan

Phase What Effort
1 BinaryExprKind enum + BinaryIRTree S
2 HardcodedString + SuspiciousImport detectors S
3 PackedSection + WritableXSegment detectors S
4 Wire into scan_router + CLI S
5 Test against 10 CTF binaries, measure improvement S

Target: 3.7% → 40%+ detection rate (Phase 2 alone adds ~10 string+suspicious-import findings).