Priyanshu KumarandClaude Sonnet 5.5 e2159180cb D65: a stub is the stated import's only where its transfer reaches that import
`import_stub` took the import's name from discovery (`import_at(entry)`) and
its signature from the callee the body transfers to, and checked only that the
callee's class was an import. A container-stated stub whose bytes jump through
another import's slot (a patched Mach-O `__stubs` entry) passed: `free`
rendered as `extern void* free(uint64_t)`, `malloc`'s types under `free`'s
name.

The address the transfer reaches must now be bound, by `import_at`, to the
same import the entry is stated as. Both sides are the container's statement
(the stub table, the loader's write into the slot), not the callee identity's
spelling. Otherwise the function is no stub: it renders as a body, and
`R2DEC_TRACE_REFUSAL` prints the stated import, the address reached and what
is bound there. `import_stub` now asks `Program` itself, so `stub_of` takes
the program; the body proof is split out as `lone_transfer` to stay under the
function-length ratchet.

Test `a_stub_whose_jump_goes_to_another_import_is_a_body_not_the_stated_stub`
fails at 298ae95b with
`/* r2sleigh: import stub at 0x1010; this symbol is the import `free` ... */
extern void* free(uint64_t);` and now renders the function with its
`UnresolvedIndirectBranch` gap. `a_stub_the_container_states_is_its_import_s_declaration_where_its_jump_agrees`
pins the container-stated stub whose jump agrees.

Measured, release, base 298ae95b against this tree: pdd of every function of
bash and pumasim (16,866) is byte-identical, 0 changed (pumasim's 522 import
stubs unchanged); pdd of all 6,878 `sym.imp.*` functions of the 781 small
radare2 test ELF, Mach-O and PE binaries (2,222 ELF and 2,814 Mach-O stub
renderings) identical, afl identical. cargo test -p r2engine --all-targets
628 passed; golden 442 and stable_temporaries 24 unmoved;
structure-report.sh exit 0, counts unmoved; fmt, clippy --tests -D warnings
and comment_runs --base clean.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01456qmqCGpCWJkrg6JUZNNM
2026-10-23 17:21:44 +05:30
2026-02-11 12:57:50 +05:30

r2sleigh

A binary analysis engine and certifying decompiler in Rust, with r2s as its shell. Semantics come from Ghidra's Sleigh specifications rather than hand-written per-architecture models, and the decompiler refuses rather than guesses when it cannot prove what it would print. r2s speaks radare2's command language with no radare2 in the process; radare2 is the differential target the engine is graded against.

bytes --> Sleigh --> r2il (low) --> r2ssa (medium) --> r2dec (high) --> C
              |                          |                  |
          r2image                    r2types            r2rewrite
        ELF/Mach-O/DWARF          type inference       term rewriting

Quick start

cargo build --release -p r2s --features sleigh

target/release/r2s -q -c 'afl' /bin/ls                    # functions, and why each is believed
target/release/r2s -q -c 'iz' /bin/ls                     # strings
target/release/r2s -q -c 'axt 0x100003f10' /bin/ls        # references to an address
target/release/r2s -q -c 's main; pdd' /bin/ls            # decompile
target/release/r2s -q -c 's main; wx 9090; pdd' /bin/ls   # patch in memory, then decompile
target/release/r2s -q -c 's main; pd 16' /bin/ls          # disassemble
target/release/r2s /bin/ls                                # interactive; V for the visual mode

pdil prints r2il as lifted and pddo a function's source obligations, so a defect is either in the lift or in the rendering. R2DEC_TRACE_REFUSAL=1 names the predicate and site behind a refusal.

Architectures

Architecture Feature Status
x86-64, x86 x86 decompiles
aarch64 arm decompiles
ARM 32-bit arm disassembles; pdd not yet admitted
RISC-V, MIPS riscv, mips lift

Crates

Crate Purpose
r2s The shell: radare2's command language over the engine
r2s-tui The visual mode
r2engine Query orchestration, discovery, routes, summaries
r2image ELF and Mach-O parsing, DWARF through gimli
r2abi Library prototypes, syscalls, cited ABI rows
r2sleigh-lift Sleigh decoding to r2il; the machine profile from the .cspec
r2il The low IL (Varnode, R2ILOp, R2ILBlock) and its semantics
r2ssa The IR: SSA, indexes, liveness, values, memory, certificates
r2source Contracts between the layers
r2types Type inference, layouts, signatures
r2rewrite Term rewriting with proved rules
r2dec Structuring, binding and C rendering
r2sleigh-cli The Sleigh toolchain and the instruction exporter

Extending

  • An opcode: R2ILOp in crates/r2il/src/opcode.rs, its P-code translation in crates/r2sleigh-lift/src/translate.rs, text in text.rs, SSAOp in crates/r2ssa/src/op.rs, its C in crates/r2dec/src/render/terms.rs.
  • An architecture: a trusted language in crates/r2sleigh-lift (TrustedSleighProfile, embedded_machine) whose compiler specification the LanguageProfile parses; nothing below the lifter matches its name (doc/adr-machine-profile.md).
  • A command: one entry in VERBS in crates/r2s/src/commands.rs, spelled as radare2 spells it.

Documentation

Document What
ROADMAP.md What is done, what is left, in order
AGENTS.md Working rules: ownership, anti-hack standard, validation bar
BUILDING.md Build, features, profiles, troubleshooting
CONTRIBUTING.md Issues, commits, pull requests
doc/engine-vision.md What this is becoming, and why
doc/testing.md Gates and where a test goes
doc/r2il.md, doc/ssa.md, doc/decompiler.md, doc/types.md The tiers
doc/adr-*.md One design decision each, linked from the roadmap
doc/drafts/ Designs not yet adopted

Requirements

Rust 1.99 (edition 2024, pinned in rust-toolchain.toml). radare2 only for the differential harnesses. Z3 optional. License: LGPL-3.0-only.

S
Description
No description provided
Readme GPL-3.0
126 MiB
0 Stars 1 Watchers 0 Forks
Languages
Rust 91.1%
Python 7.4%
C 1.1%
Shell 0.3%