How 3mper0rr/reverse-llm-analysis works
1. Repository shape
- This is a single-script CLI tool centered in rvllm.py, not a multi-module service.
- The architecture is a linear analysis pipeline with one external dependency boundary: local binary analysis first, then optional LLM calls, then Markdown report generation.
2. Primary purpose
- The tool performs static reverse engineering of unknown binaries.
- It targets ELF64 and PE32+ binaries, extracts code and metadata, then asks an LLM to explain selected code regions in plain English.
3. Entry point and configuration
- rvllm.py serves as both the executable and the orchestrator.
- Top-of-file constants control the main runtime behavior: API keys, active LLM backend, block size, maximum analyzed blocks, and output directory.
- The user selects the backend at runtime or through the configured default.
4. Binary intake and format detection
- The first stage reads the target file from disk and detects whether it is ELF or PE from its magic/signature.
- This is a local-only parsing boundary: no external tooling like pefile or pyelftools is used.
- The parser then branches based on file format and supported architecture.
5. Format-specific metadata extraction
- For PE, the tool resolves imports from the Import Directory Table and maps them to readable names like KERNEL32!VirtualAlloc.
- For ELF, it resolves symbols from .dynsym and .dynstr, with a fallback strategy for stripped binaries using loadable segments.
- This stage produces the basic metadata needed for later symbol-aware analysis.
6. Code and data extraction
- The tool extracts executable code regions such as .text or equivalent PT_LOAD-backed segments.
- It also extracts strings from .rodata / .rdata, which are later included in the report as contextual clues.
- These extractions support both human inspection and later hotspot interpretation.
7. Disassembly layer
- Disassembly is done with Capstone.
- The disassembler turns bytes into instruction streams, instruction counts, and address-annotated blocks that can be reasoned about by pattern detectors and by the LLM.
- This is the core intermediate representation between raw binary parsing and semantic analysis.
8. Hotspot detection subsystem
- The tool identifies “interesting” code regions rather than sending the whole binary to the LLM.
- Hotspot types include:
- external calls to known APIs/functions,
- indirect calls,
- branch-condition chains,
- bulk memory operations,
- struct/array-style access patterns.
- This is the main reduction step that makes the analysis economical and focused.
9. LLM analysis boundary
- For each selected hotspot, the tool sends a bounded instruction window to an external LLM backend.
- Supported backends are Groq, Claude, and OpenRouter, all accessed over HTTP via requests.
- This is the only cloud/external dependency; everything else is performed locally.
10. Report generation
- The final artifact is a Markdown report written under rvllm_out/.
- The report combines binary metadata, extracted strings, disassembly excerpts, detected patterns, referenced symbols, and LLM-generated summaries.
- Output filenames include an MD5-based suffix so each analyzed binary gets a unique report instance.
11. Data flow summary
- Input binary file → format/arch detection → raw parsing of headers/imports/symbols → code and string extraction → Capstone disassembly → hotspot selection → per-block LLM explanation → Markdown output.
- The architecture is intentionally one-pass and block-oriented, with no inter-procedural analysis or decompilation stage.
12. Important architectural boundaries
- Local analysis boundary: parsing, disassembly, string extraction, and hotspot detection happen entirely on the machine.
- Remote reasoning boundary: only compact selected blocks are sent to the LLM, which limits cost and avoids transmitting the full binary.
- Supported vs unsupported boundary: packed/obfuscated binaries and PE32 x86 are explicitly out of scope, so the pipeline assumes relatively clean native binaries.
Main entry points: rvllm.py Markdown report
Components 15
Core pipeline
Local binary analysis and orchestration in the main script.
- rvllm.py · Single-script entry point that drives the full reverse-engineering pipeline.
rvllm.py - Runtime config · Top-of-file settings for backend choice, API keys, block size, limits, and output directory.
rvllm.py - Binary intake · Reads the target binary from disk and starts format detection.
rvllm.py - Format detect · Identifies ELF or PE by signature and branches by supported architecture.
rvllm.py - PE parse · Resolves import table entries and maps imported APIs to readable names.
rvllm.py - ELF parse · Resolves symbols from dynsym/dynstr and falls back to loadable segments for stripped binaries.
rvllm.py - Code extract · Pulls executable code regions such as .text or PT_LOAD-backed segments.
rvllm.py - String extract · Collects strings from .rodata or .rdata for contextual clues in the report.
rvllm.py - Capstone · Converts bytes into instruction streams, counts, and address-annotated blocks.
rvllm.py - Hotspots · Selects interesting regions such as external calls, indirect calls, branch chains, memory ops, and struct-style access.
rvllm.py - Block window · Builds bounded instruction excerpts for per-hotspot analysis.
rvllm.py
Remote reasoning
Optional LLM backends used for hotspot explanation.
- Groq · HTTP-based remote explanation backend.
rvllm.py - Claude · HTTP-based remote explanation backend.
rvllm.py - OpenRouter · HTTP-based remote explanation backend.
rvllm.py
Reporting
Markdown report assembly and output files.
- Markdown report · Writes the final Markdown analysis under rvllm_out/ with an MD5-suffixed filename.
rvllm.py
Connections 20
- rvllm.py → Runtime config: uses · Runtime settings configure the analysis flow.
- rvllm.py → Binary intake: starts · The script begins by loading the target binary.
- Binary intake → Format detect: detects · Binary signature determines format and architecture branch.
- Format detect → PE parse: PE · PE binaries follow import and metadata extraction.
- Format detect → ELF parse: ELF · ELF binaries follow symbol and segment extraction.
- PE parse → Code extract: feeds · Resolved metadata supports code-region extraction.
- ELF parse → Code extract: feeds · Resolved metadata supports code-region extraction.
- Code extract → String extract: adds context · Textual data is gathered alongside executable regions.
- Code extract → Capstone: disassembles · Raw code bytes are converted into instruction streams.
- Capstone → Hotspots: analyzes · Instruction patterns are scanned for interesting regions.
- Hotspots → Block window: selects · Each hotspot is packaged as a bounded instruction window.
- Block window → Groq: optional · Selected blocks may be sent to Groq for explanation.
- Block window → Claude: optional · Selected blocks may be sent to Claude for explanation.
- Block window → OpenRouter: optional · Selected blocks may be sent to OpenRouter for explanation.
- Hotspots → Markdown report: summarizes · Detected patterns are included in the final report.
- String extract → Markdown report: context · Recovered strings are embedded into the output.
- Groq → Markdown report: writes back · LLM summaries are merged into the Markdown report.
- Claude → Markdown report: writes back · LLM summaries are merged into the Markdown report.
- OpenRouter → Markdown report: writes back · LLM summaries are merged into the Markdown report.
- rvllm.py → Markdown report: emits · The orchestrator assembles the final artifact.