fold/docs/research/vendor-architecture-map-2026-05-31.md

110 lines
4.5 KiB
Markdown

# Vendor Architecture Map
> Date: 2026-05-31; updated after Ghidra x86/x86-64 and P-Code summary work.
> Reading list: `docs/research/vendor-library-study-2026-05-31.md`.
## Architecture decision
Fold has three vendor-facing lanes:
1. **Ghidra/SLEIGH owns binary semantics.** It produces raw/high P-Code and
def-use evidence for binary detectors.
2. **LIEF is the next metadata candidate.** It can replace or supplement r2 for
ELF/PE/Mach-O structure, symbols, sections, imports, exports, and entry
points.
3. **Souffle is the next fact-engine candidate.** It should consume Fold-owned
MidIR facts only after stable IDs and provenance exist.
Everything else is deferred research. RetDec, Remill/McSema, PhASAR, and
Crab/Clam should not have active Meson options or `third_party/` slots until a
fixture proves need.
## Binary path
```text
Binary
├─ r2 metadata now ───────────────▶ metadata facts + heuristic findings
├─ LIEF metadata candidate ───────▶ stable ELF/PE/Mach-O metadata facts
├─ Ghidra raw P-Code ─────────────▶ op-level hazards for Z3/observers
└─ Ghidra high P-Code / SSA ──────▶ def-use, write summaries, call evidence
```
Ghidra and LIEF are complementary: Ghidra models instructions; LIEF models file
structure.
## Lane ownership
| Lane | Owner | Output | Status |
|---|---|---|---|
| Binary metadata | r2 now; LIEF candidate | format, arch, sections, symbols, imports, exports, entry point | r2 active; LIEF manifest-only |
| Binary semantics | Ghidra/SLEIGH | P-Code ops, varnodes, def-use, path/call/write evidence | active behind `-Dghidra=enabled` |
| Source semantics | Clang AST/CFG | source observer hooks, source findings | active |
| Interprocedural facts | native graph code now; Souffle candidate | reachability, taint, transitive calls | Souffle manifest-only |
| Final proof/query | Fold Z3 encoder | proved/heuristic/syntactic findings | active |
## Required provenance
Every future fact or finding must identify its producer:
```text
backend: source | binary | rust | swift
lane: clang | r2-metadata | lief-metadata | ghidra-raw | ghidra-ssa | souffle-fact
precision: exact | heuristic | over-approximated | bailed
location: source location or binary address/range
```
Do not widen `core::AnalysisBackend` for vendor-specific payloads. Add small
adapter structs or MidIR/fact records instead.
## Integration sequence
### 1. Continue Ghidra stabilization
- Keep Ghidra types isolated in `src/binary/ghidra_*` and P-Code modules.
- Expand P-Code path predicates and summary tests before broadening hazard gates.
- Keep checked-in `.sla` runtime copies plus Meson-generated `.sla` validation.
- Preserve binary/source provenance on every finding.
### 2. Prototype LIEF metadata
- Inventory current r2 metadata fields used by `R2Backend` reports.
- Map those fields to LIEF C++ APIs for ELF, Mach-O, and PE.
- Emit read-only metadata facts with `lief-metadata` provenance.
- Keep r2 fallback until LIEF covers all fields needed by binary reports.
### 3. Define MidIR/fact IDs
Required before Souffle or any other fact producer:
```text
FunctionId = backend + artifact + entry/source-name
BlockId = FunctionId + block ordinal/address
OpId = FunctionId + op ordinal + original address/source loc
ValueId = lane + varnode/register/local/temp identity
```
### 4. Prototype Souffle facts
- Start with standalone TSV facts and `.dl` rules.
- First relations: `Reachable`, `ValueFlowsTo`, `TaintedAt`,
`CallsTransitively`.
- Treat outputs as derived facts with provenance, not as silent detector filters.
- Consider generated C++ only after the standalone prototype shows value.
## Deferred-lane policy
| Candidate | Revisit only when |
|---|---|
| RetDec | Ghidra misses a concrete binary semantic class that LLVM lifting preserves. |
| Remill/McSema | A single-block Remill prototype demonstrates needed precision over Ghidra. |
| PhASAR | Fold commits to LLVM IR as a first-class input. |
| Crab/Clam | Native summaries cannot close a concrete numeric range false positive. |
## Guardrails
- Keep source and binary backends separate.
- Do not decompile binary to C and route it through source detectors.
- Do not link optional vendors into `fold-core` without a fixture-backed reason.
- Keep binary metadata metrics separate from binary semantic metrics.
- Do not let derived facts hide source or binary coverage unless the user
explicitly requested a capped/filtered scan.