Ultra blazing fast cross-references, struct layout recovery, program slicing & structured pseudo-C for x86-64 ELF binaries.
Zero-index binary analysis in pure safe Rust (#![forbid(unsafe_code)]). Function boundaries come directly from .eh_frame unwind tables (with span fallback) and whole-binary queries decode across all CPU cores in milliseconds — even on completely stripped Rust release binaries where symbol tables are empty.
Interactive Workbench (xrefcode.com) · By Alexander Panasenko
Why · Install · Quick Start · Recorded Examples · CLI Reference · Architecture · Benchmarks · Limitations · Citation
Why
Traditional reverse-engineering suites assume one interactive analyst willing to wait minutes for an upfront whole-program database import before asking the first question. Stripped Rust binaries make this worse: symbols are gone, strings are non-NUL (ptr, len) slices in .rodata pools, and bounds-check panics shatter loops into cold edges that turn naive decompilers into unreadable goto spaghetti.
XRef Code (xref) is built for fast iterative investigation by both reverse engineers and autonomous AI agents:
- Zero index, zero stale cache. Every invocation maps the ELF image in memory, extracts exact function ranges from
.eh_frameunwind records (with automatic span fallback), and scans functions in parallel viarayon. - Native structured typed pseudo-C (
xref c). Lifts x86-64 machine code directly to readable C without external tools — recovering immutablearg_0..arg_5signatures, SSA live-range webs (ptr_*,v_*,slot_*), element-indexed SIB arrays, 1-operand128-bitwideningmul/imul/div/idiv, multi-precisionadc/sbbcarry/borrow chains, signed arithmetic overflow intrinsics, and structuredif/else/while/do-while/switchregions. - Rust-aware stripped binary recovery. Recognizes stripped Rust runtime helpers (
rust_panic_bounds_check,rust_slice_index_fail,rust_capacity_overflow), slices exact(ptr, len)&strliterals, mapscore::panic::Location(file:line:col) descriptors back to original crate paths, and resolvesDisplayjump-table arms. - Slicing & cross-build diffing (
xref slice,xref match,xref diff-c). Isolates balanced statements and control guards reaching an exact call or instruction IP, relocates shifted stripped functions across builds, and diffs normalized pseudo-C with volatile hex addresses abstracted away.
Explore 114 verbatim recorded CLI runs against stripped xref itself in the static browser workbench at xrefcode.com.
Installation
Homebrew (macOS Apple Silicon & Linux x86_64)
Installs the prebuilt xref binary directly from the alex09x/homebrew-apps tap (no Cargo compilation required):
Prebuilt Release Tarballs (Linux x86_64 & macOS arm64)
Prebuilt archives (x86_64-unknown-linux-gnu, requiring glibc >= 2.34, and aarch64-apple-darwin) bundle xref, README.md, LICENSE-MIT, LICENSE-APACHE, and CITATION.cff:
Cargo & crates.io (Linux & macOS)
Published on crates.io as xref-code, which installs the xref CLI binary (requires rustc 1.88+ for Edition 2024 let chains; prebuilt binaries also work via cargo-binstall):
# or prebuilt via cargo-binstall:
# or directly from the pinned release tag:
Quick Start
Pass -b <ELF> on each command or export XREF_BIN=/path/to/binary.elf once per shell session. Addresses use ELF virtual numbering (objdump addresses) in 0x hex or decimal:
Recorded Examples
All outputs below are complete, unedited runs captured against xref.stripped (1,962,608 bytes, 0 symbols, sha256:3f3ba3b311f3eca8e26a929285d4fc9ffef4e4b6e8fc015105766180a2a6869d) and verified in CI to match docs/recorded-data.js line-for-line (modulo trailing line-end spaces).
1. Structured Typed Pseudo-C with Field Offset Hints (xref c --fields)
$ xref -b xref.stripped c 0x9a8a0 --fields
/* field offsets: arg_0 [+0x0:u64, +0x8:u64, +0x10:u64, +0x18:u64] */
/*
* fn_9a8a0 — 0x9a8a0..0x9a97a (218 bytes, 1 direct caller; synthetic FDE entry)
* source: src/cfg.rs:154:22, src/cfg.rs:75:25, src/cfg.rs:154:57
* params:
* arg_0 (rdi): const void * — reads +0x0 (8B), +0x8 (8B), +0x10 (8B), +0x18 (8B)
* arg_1 (rsi): unk64 — 64-bit register (signedness unconstrained)
* arg_2 (rdx): unk64 — 64-bit register (signedness unconstrained)
* return: u8 in rax (consumed by 1/1 direct call site)
*/
u8
2. Interprocedural Struct Layout Recovery (xref layout --callees)
$ xref -b xref.stripped layout 0xa2270 --reg rsi --callees
layout of rsi in 0xa2270..0xa2566:
+0 size 4 u32 r:0 w:2
+8 size 8 u64 r:2 w:0
+10 size 8 u64 r:2 w:0
+20 size 8 u64 r:1 w:0
+28 size 8 u64 r:1 w:0
5 fields (min span 0x30)
other pointer args: rdi (3 fields), rdx (1 fields) (use --reg <REG>)
3. Backward Program Slicing (xref slice)
$ xref -b xref.stripped slice 0xc7d60 --to fn_160bb0
/* slice of 0xc7d60..0xc7fbf -> fn_160bb0 (37/131 lines) */
void
4. Cross-Build Relocation & Normalized Pseudo-C Diff (xref diff-c)
The indented ... lines below are emitted directly by xref diff-c to mark unchanged normalized lines outside the diff hunk:
$ xref -b xref.stripped diff-c --other xref-v0.0.2.stripped 0xd57c0
=== diff 0xd57c0..0xd6301 (current) vs 0xd5530..0xd6071 (other, score 384: locs:240 strs:0 imms:4 disps:10 nbrs:105 size:0xb41 callees:8) ===
...
}
@var_11 = (@slot_10 + @var_8);
- @var_1 = 0xc2bc;
+ @var_1 = 0xc518;
@var_32 = @slot_9;
switch (*(u64 *)(@var_11)) {
...
Command Reference
Inventory, Symbols & Cross-References
xref -b BIN stats # functions, .text bytes, pointers, imports, panic locations
xref -b BIN sym PATTERN # symbol search (non-stripped binaries)
xref -b BIN func 0xa1b50 # function span containing an address
xref -b BIN refs "goto L_" 0xa1b50 # .rodata / pointer / code xrefs (--inline for mov/movabs stores)
xref -b BIN istr "text" # shorthand for refs --inline
xref -b BIN imm 24 --in 0xa1b50 # immediate constants (--store, --cmp, --in FN)
xref -b BIN find --src src/loops.rs --calls 0x160bb0 # single-pass multi-predicate function search (--any K)
Struct Layouts, Displacements & Call Graphs
xref -b BIN disp 0x20 0x28 --all # field loads/stores/leas (--write, --lea, --stride, --in FN)
xref -b BIN layout 0xa2270 --reg rsi --callees # aggregate field offsets, widths, strides & 1-hop callees
xref -b BIN callers 0xcafb0 # direct calls/tail-jumps, address-taken & pointer-table xrefs
xref -b BIN calls 0xcafb0 # outgoing calls and tail-jumps in instruction order
xref -b BIN args 0xa2270 --max 20 # constant & symbolic arguments across all call sites
xref -b BIN path 0xc7fc0 0x160bb0 --depth 8 # shortest call chains between two functions
xref -b BIN tree 0xd0aa0 --callers --depth 2 # indented caller/callee tree with panic source anchors
Disassembly, Pseudo-C, Slicing, Crate Export & Diffing
xref -b BIN asm 0xc7d60 --from A --to B # annotated Intel disassembly (strings, slots, targets)
xref -b BIN c 0x9a8a0 --fields # structured typed pseudo-C (--out DIR for parallel batch export)
xref -b BIN slice 0xc7d60 --to fn_160bb0 --fields # backward slice to target call, hex IP, offset, or string
xref -b BIN dump --out DIR --src src/loops.rs # parallel modular .c export grouped by panic source paths
xref -b BIN match --other OLD_BIN 0xc7d60 --top 3 # relocate shifted stripped functions across two builds
xref -b BIN diff-c --other OLD_BIN 0xd57c0 # normalized cross-build pseudo-C LCS diff
Rust Source Locations & Enum Jump Tables
xref -b BIN src 0x9a8a0 # core::panic::Location (file:line:col) descriptors in function
xref -b BIN where src/image.rs --line 46 # stripped functions referencing a Rust file (and line)
xref -b BIN files src/ # distinct Rust source files recovered from panic descriptors
xref -b BIN error "invalid" # jump-table discriminant whose Display arm names text
xref -b BIN variant 0xc7fc0 1 2 # inverse of error: texts referenced by jump-table arms
xref -b BIN arm 0xc8010 # jump-table indices whose arm contains an address
Architecture
flowchart LR
ELF["x86-64 ELF Image\n(.text, .rodata, .eh_frame, .rela)"] --> Span["Span & Runtime Discovery\n(.eh_frame FDEs + fallback,\npanic Location & helper map)"]
Span --> Decode["Parallel Decode (rayon)\niced-x86 instruction stream\n& jump-table recovery"]
Decode --> Xref["Direct Xref & Layout Queries\nrefs / disp / layout / find /\ncallers / args / match"]
Decode --> CFG["CFG & Region Structurer\nnatural loops, cold noreturn\ninlining & skip-flag guards"]
CFG --> SSA["SSA Webs & Lifting\n128-bit widening ALU, carry/borrow,\nbidirectional types & SIB arrays"]
SSA --> Emit["C Emitter, Slicer & Differ\nxref c / slice / dump / diff-c"]
Recorded Performance
Single-run CLI wall times reported by xref 0.0.5 (stderr) on AMD Ryzen 9 9950X (16 cores / 32 threads, Linux 6.8 x86_64, warm OS page cache) analyzing stripped xref.stripped (1.96 MB, 1,974 functions, 0 symbols):
| Operation | Command | ELF Load | Total Time |
|---|---|---|---|
Binary inventory (1,974 functions, 588 panic locations) |
xref -b xref.stripped stats |
0.84 ms |
2.2 ms |
| Whole-binary string & pointer cross-reference scan | xref -b xref.stripped refs "goto L_" |
0.80 ms |
3.9 ms |
| Rust module mapping from embedded panic locations | xref -b xref.stripped where src/loops.rs |
0.79 ms |
3.4 ms |
| Interprocedural struct layout recovery (1-hop callees) | xref -b xref.stripped layout 0xa2270 --reg rsi --callees |
0.81 ms |
2.6 ms |
Backward program slice + field offset hints (37 / 131 lines) |
xref -b xref.stripped slice 0xc7d60 --to fn_160bb0 --fields |
0.81 ms |
5.1 ms |
| Cross-build function matching & normalized pseudo-C diff | xref -b xref.stripped diff-c --other xref-v0.0.2.stripped 0xc7d60 |
0.86 ms |
13.4 ms |
Scope & Limitations
- Supported input format:
x86-64ELF binaries and shared objects (ET_EXEC,ET_DYN). PE/Mach-O and AArch64 are outside current scope. - Function boundary discovery: Exact function spans come from
.eh_frameunwind tables (emitted by default byrustc,clang, andgcconx86-64even afterstrip --strip-all), with gap/call-target span fallback when unwind entries are absent. Binaries stripped of.eh_frame(strip -R .eh_frame) rely on heuristic span boundaries. - Static pseudo-C & offset inference: Parameter signatures (
arg_*), inferred pointer/integer types (const void *,usize,unk64, etc.), and--fieldsoffset hints (->f_<off>) are conservative static reconstructions from machine-code uses, not DWARF source types. Unmodeled SIMD/system instructions are preserved inline as explicit/* 0xaddr: ... */assembly comments rather than silently dropped — always cross-check critical invariants withxref asm.
Development & Testing
rustc must be available on PATH when running tests: the end-to-end suite compiles tests/fixtures/sample.rs into a temporary ELF fixture and verifies CLI subcommands against it.
Citation
For academic, security, or archival reference, cite the published v0.1.0 release via Zenodo or CITATION.cff:
- Alexander Panasenko (2026). XRef Code — Ultra Blazing Fast x86-64 ELF Cross-References & Pseudo-C Decompiler (v0.1.0). Zenodo. https://doi.org/10.5281/zenodo.23878790 (concept DOI: 10.5281/zenodo.23878789)
License
Copyright © 2026 Alexander Panasenko (alex@prod.codes).
Dual-licensed under either of:
- Apache License, Version 2.0 (
LICENSE-APACHEor http://www.apache.org/licenses/LICENSE-2.0) - MIT License (
LICENSE-MITor http://opensource.org/licenses/MIT)
at your option.