110 lines
4.5 KiB
Markdown
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.
|