Expand description
Pure-byte call-graph + fact verifier for the Rust rebuild.
When a rebuild function is tagged origin: 0xADDR, it claims to be a 1:1
port of the function at that VA in the target binary. This crate establishes
ground truth by disassembling the actual bytes (no Ghidra, no decompiled C)
and lets a port declare what it should structurally match:
- direct CALL targets (the call graph)
- struct field offsets (
[reg+0xNN]accesses) - global / static VAs (
[0x00bXXXXX]data refs) - vtable / immediate VAs (
MOV [esi],0x00a7e38c) - virtual-call slots (
CALL [reg+0x84]) - IAT import targets (
CALL [0x00a28xxx])
Use the verify_callgraph! macro to turn declarations into #[test]s.
Re-exports§
pub use disasm::analyze;pub use disasm::reg_params;pub use disasm::resolve_thunk;pub use disasm::tail_referenced;pub use disasm::ArgKind;pub use disasm::CallGraph;pub use disasm::CallSite;pub use pe::FixupStatus;pub use pe::Pe;pub use skel::cfg_fingerprint;pub use skel::CfgFingerprint;
Modules§
- disasm
- Recursive-descent function disassembly over real PE bytes (iced-x86).
- pe
- Minimal, dependency-free PE32 reader — just enough to map a virtual address
(VA) to file bytes. We deliberately hand-parse the headers instead of pulling
in
goblin/object: the contract is “pure byte”, and the only thing the disassembler needs isva -> &[machine code bytes]. - skel
- Byte-derived reference skeleton emitter: turns a function’s machine code into a
Rust-flavored structural outline — labeled basic blocks, ordered calls with their recovered
arguments, struct-field accesses (
rd/wr), globals (g/s), and the branch / loop / switch structure. It is NOT compilable Rust; it is a faithful hint for porting, generated from the same byte-truth the gates verify against. Use it next to the naked asm and the Ghidra C: the asm is ground truth, Ghidra C gives high-level naming, and this gives the byte-accurate call order + arguments + offsets + control flow in the porter’s target idiom.
Macros§
- verify_
callgraph - Declare expected facts for
origin:functions and generate one#[test]per function, checked against the real binary.
Structs§
- Corpus
Diff - Result of diffing a Rust function’s resolved body calls against the binary.
- Diff
- Back-compat thin diff over direct calls only (used by the CLI / build gate).
- Spec
- One declared expectation for a function, checked against the binary’s facts.
Functions§
- diff_
body_ calls - Diff the calls a Rust body makes (already resolved to ported addresses) against
the binary’s real call set at
own_addrs.corpusis the set of all ported origin addresses (only calls within it are diffable). Mirrors the logic oftools/analysis/verify_callgraph.py, but on bytes instead of Ghidra.asm. - diff_
body_ calls_ ext - Like
diff_body_calls, plusindirect_targets: addresses the binary reaches through a register/memory indirect call atown_addrs(a stack-slot callback, a registered handler, an IAT thunk, …). They widen the ACCEPTANCE set only: a body that spells one as a direct call is faithful, and they never become a MISSING requirement (the binary issues no direct CALL to them). - diff_
calls - has_
direct_ branch_ target - Does ANY instruction in
.textstatically targettargetvia a relative branch (CALL/JMP/Jcc rel32)? Used by the macro to warn on vtable-only dispatch.