Wednesday, September 23, 2026

Inside recurse: an agentic reverse engineering IDE with a pure-Rust engine

Inside recurse: an agentic reverse engineering IDE with a pure-Rust engine

recurse is a desktop reverse engineering IDE from Recurse-Labs that pairs a Rust-native disassembler, decompiler and debugger with an LLM agent for authorized binary analysis.

ToolRecurse-Labs/recurse — agentic reverse engineering IDE (Tauri + Rust) with multi-architecture disassembly, decompilation, debugging and an LLM agent
CategoryReverse engineering / static & dynamic binary analysis with agentic AI
Primary UseAnalyzing binaries (ELF/PE/Mach-O), CTF work, malware triage and de-obfuscation via disasm, xrefs, decompile and lift operations driven by an LLM agent
Safe UseIntended for authorized security assessments, CTF competitions, research labs and defensive malware analysis on samples you are licensed to examine; it is local-first and never transmits binaries to third parties by default
Telemetry NoteLocal-first tool: project state persists in ~/.recurse/recurse.db (SQLite with FTS5) and eval traces under target/eval-traces/; agent queries go only to the configured OpenAI-compatible endpoint, so blue teams reviewing its use should audit that endpoint configuration

recurse from Recurse-Labs positions itself as a Ghidra-class desktop environment with a Cursor-style agentic twist, and the README makes clear this is not a thin chatbot wrapper bolted onto an existing disassembler. The desktop app is built on Tauri 2 with a React and TypeScript frontend, sitting on top of a pluggable analysis backend defined by a single Engine trait in crates/recurse-static/src/engine.rs. The default engine is pure Rust — multi-architecture disassembly via Capstone, ELF/PE/Mach-O parsing via object — with no child process and no copyleft dependency in the build. radare2 (r2) is supported as an opt-in alternative engine that runs as a separate process and is never bundled, which is a licensing posture many commercial-adjacent projects avoid thinking about entirely.

The repository layout tells you a lot about the engineering discipline here. It is a Cargo workspace where each concern gets its own crate: recurse-agent holds the LLM loop, tool runtime and SQLite memory; recurse-static handles file parsing, disassembly, CFG and cross-reference recovery; recurse-vtil implements a VTIL-inspired de-obfuscation intermediate language; recurse-mcp is a standalone headless MCP server over stdio; recurse-debug is a cross-platform debugger using ptrace, Mach and Win32 APIs; and recurse-eval is a headless evaluation harness. Critically, no crate depends on Tauri, each builds and tests standalone, and the agent crate pulls in neither the systems code nor the debugger it does not need — a separation that makes the whole tree auditable.

Architecturally, the most interesting decision is that the agent and the UI are backend-agnostic and share a binary world-model. Functions, xrefs, strings and the control-flow graph are first-class state rather than text pasted into a model's context window. The README's argument section is blunt about why this matters: stapling an MCP server onto IDA or Ghidra, or pasting disassembly into a CLI agent, works for five-function CTF challenges and collapses on real binaries with ten thousand functions. Demand-driven tools plus persistent memory beat dumping full decompiles until the context window dies.

The agent itself talks to any OpenAI-compatible endpoint, defaulting to OpenRouter with a model picker, configured either through the in-app Model & Provider dialog or via RECURSE_LLM_API_KEY, RECURSE_LLM_ENDPOINT and RECURSE_LLM_MODEL environment variables. The same agent loop runs in the UI and in the eval harness, which means behaviors you measure headlessly are the behaviors you get interactively. Local inference is a first-class path: Ollama, LM Studio, llama.cpp's llama-server and vLLM are all named as supported endpoints, and when the API key is blank no Authorization header is sent at all.

The grounding story deserves attention from anyone who has watched an LLM confidently invent 0x401023. In recurse, every address is a clickable object — in the function list, graph nodes, xrefs and decompiler annotations — so the model operates on engine-backed references rather than free text it can hallucinate. Renames performed by the agent propagate instantly to the function list, disassembly annotations, the CFG graph and the decompiler view, and the README frames this as verification through visual confirmation: in reverse engineering there is no npm test, so the human confirms or rejects in one click.

Static analysis capability is broad. The native engine disassembles x86/x86-64, ARM, AArch64, MIPS, PowerPC, RISC-V, SPARC, SystemZ, M68K and BPF. The recon page produces binary info, MD5/SHA1/SHA256/CRC32 hashes, entropy, linked libraries and a self-contained hardening report covering RELRO, PIE, NX, stack canaries, FORTIFY and RPATH — no external checksec invocation. Extension-less files load fine, which matters for real sample triage where packers and droppers routinely ship nameless blobs.

The decompilation pipeline lives in recurse-vtil and follows a lift-then-optimize-then-structure flow. A decompile operation renders C-like pseudocode with if/while structuring and total instruction coverage from the same pipeline that powers the more unusual lift operation — raising a function into VTIL-style IL and running whole-routine propagation, folding, dead-code elimination and branch resolution over it. The README explicitly targets the case where disassembly looks like a VM dispatcher or an opaque-predicate chain, which is the exact wall most analysts hit in obfuscated commercial software and serious CTF finals.

Persistence is handled through SQLite with FTS5/BM25 retrieval. Renames, findings and notes survive a /clear of the chat and a full app reopen, and they seed the next session — meaning the workspace accumulates institutional knowledge about a binary the way a human analyst's IDB does. Lazy analysis keeps large binaries responsive: function discovery indexes cheaply and basic blocks decode only when a function is actually viewed, a documented design choice rather than an incidental optimization.

Two integrations extend reach beyond the desktop app. The recurse-mcp crate exposes the same Engine over MCP stdio so any MCP-capable agent — the README names Claude Code, Cursor and Claude Desktop — can drive analysis without Tauri, an IDA seat or a Python bridge. And recurse-eval evaluates the agent headlessly against YAML-configured crackme tiers, with just eval-fetch, just eval-test and just eval-run entry points, per-turn traces written under target/eval-traces/, and cargo test deliberately unable to spend API money because eval execution is a binary, not a test.

From a defensive and privacy standpoint, the design is notable for being malware-safe by default: local-first, bring-your-own-key routing, and an explicit path to fully offline models, so nobody is forced to exfiltrate a sample to a cloud chatbot just to get a decompile. In an era where analysts routinely paste suspicious code into hosted LLMs, an architecture that keeps the binary on disk and only ships derived, engine-verified queries is a meaningful control. Incident-response teams handling NDA-bound or active-campaign samples should read that section of the README as a feature, not a footnote.

Building it requires Node.js ≥ 20, npm ≥ 10 and Rust ≥ 1.77, with just as the single entry point: just dev for the Vite dev server plus Tauri window, just build for .deb/.rpm/AppImage bundles and a standalone binary at target/release/recurse, and just lint/just test wiring cargo clippy --workspace, vitest and eslint. Linux users need the standard Tauri dependencies such as libwebkit2gtk-4.1-dev, and Arch users should expect a documented one-time fix for the AppImage step. With 221 stars, an Apache-2.0 license and an actively documented architecture, recurse is one of the more credible entries in the young agentic-reverse-engineering niche — worth a look for anyone doing authorized binary analysis who wants an LLM in the loop without surrendering the ground truth of a real disassembler.

Official project repository for Recurse-Labs/recurse.
Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.

Share articleFacebookXLinkedIn

Continue exploring

Browse all articles →

0 comentários:

Post a Comment

Note: Only a member of this blog may post a comment.