# 3mper0rr/reverse-llm-analysis architecture

> Architecture diagram of the GitHub repository 3mper0rr/reverse-llm-analysis, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-21). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/3mper0rr/reverse-llm-analysis
- Repository: https://github.com/3mper0rr/reverse-llm-analysis

## Overview

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`](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py) (Markdown report)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_grp_core["Core pipeline"]
  node_n_entry["rvllm.py<br/>CLI orchestrator<br/>[rvllm.py]"]
  node_n_config["Runtime config<br/>constants<br/>[rvllm.py]"]
  node_n_intake["Binary intake<br/>file loading<br/>[rvllm.py]"]
  node_n_detect{{"Format detect<br/>ELF/PE parser<br/>[rvllm.py]"}}
  node_n_pe["PE parse<br/>PE metadata<br/>[rvllm.py]"]
  node_n_elf["ELF parse<br/>ELF metadata<br/>[rvllm.py]"]
  node_n_extract["Code extract<br/>section reader<br/>[rvllm.py]"]
  node_n_strings["String extract<br/>context data<br/>[rvllm.py]"]
  node_n_disasm["Capstone<br/>disassembly<br/>[rvllm.py]"]
  node_n_hotspots{{"Hotspots<br/>pattern detector<br/>[rvllm.py]"}}
  node_n_window["Block window<br/>instruction slice<br/>[rvllm.py]"]
end

subgraph group_grp_remote["Remote reasoning"]
  node_n_groq(("Groq<br/>LLM backend<br/>[rvllm.py]"))
  node_n_claude(("Claude<br/>LLM backend<br/>[rvllm.py]"))
  node_n_or(("OpenRouter<br/>LLM backend<br/>[rvllm.py]"))
end

subgraph group_grp_output["Reporting"]
  node_n_report["Markdown report<br/>output writer<br/>[rvllm.py]"]
end

node_n_entry -->|"uses"| node_n_config
node_n_entry -->|"starts"| node_n_intake
node_n_intake -->|"detects"| node_n_detect
node_n_detect -->|"PE"| node_n_pe
node_n_detect -->|"ELF"| node_n_elf
node_n_pe -->|"feeds"| node_n_extract
node_n_elf -->|"feeds"| node_n_extract
node_n_extract -->|"adds context"| node_n_strings
node_n_extract -->|"disassembles"| node_n_disasm
node_n_disasm -->|"analyzes"| node_n_hotspots
node_n_hotspots -->|"selects"| node_n_window
node_n_window -->|"optional"| node_n_groq
node_n_window -->|"optional"| node_n_claude
node_n_window -->|"optional"| node_n_or
node_n_hotspots -->|"summarizes"| node_n_report
node_n_strings -->|"context"| node_n_report
node_n_groq -->|"writes back"| node_n_report
node_n_claude -->|"writes back"| node_n_report
node_n_or -->|"writes back"| node_n_report
node_n_entry -->|"emits"| node_n_report

click node_n_entry "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_config "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_intake "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_detect "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_pe "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_elf "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_extract "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_strings "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_disasm "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_hotspots "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_window "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_groq "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_claude "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_or "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"
click node_n_report "https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_n_entry,node_n_config,node_n_intake,node_n_detect,node_n_pe,node_n_elf,node_n_extract,node_n_strings,node_n_disasm,node_n_hotspots,node_n_window toneBlue
class node_n_groq,node_n_claude,node_n_or toneAmber
class node_n_report toneMint
```

## Components

### Core pipeline

Local binary analysis and orchestration in the main script.

- [rvllm.py](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): CLI orchestrator · Single-script entry point that drives the full reverse-engineering pipeline. · `rvllm.py`
- [Runtime config](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): constants · Top-of-file settings for backend choice, API keys, block size, limits, and output directory. · `rvllm.py`
- [Binary intake](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): file loading · Reads the target binary from disk and starts format detection. · `rvllm.py`
- [Format detect](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): ELF/PE parser · Identifies ELF or PE by signature and branches by supported architecture. · `rvllm.py`
- [PE parse](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): PE metadata · Resolves import table entries and maps imported APIs to readable names. · `rvllm.py`
- [ELF parse](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): ELF metadata · Resolves symbols from dynsym/dynstr and falls back to loadable segments for stripped binaries. · `rvllm.py`
- [Code extract](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): section reader · Pulls executable code regions such as .text or PT_LOAD-backed segments. · `rvllm.py`
- [String extract](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): context data · Collects strings from .rodata or .rdata for contextual clues in the report. · `rvllm.py`
- [Capstone](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): disassembly · Converts bytes into instruction streams, counts, and address-annotated blocks. · `rvllm.py`
- [Hotspots](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): pattern detector · Selects interesting regions such as external calls, indirect calls, branch chains, memory ops, and struct-style access. · `rvllm.py`
- [Block window](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): instruction slice · Builds bounded instruction excerpts for per-hotspot analysis. · `rvllm.py`

### Remote reasoning

Optional LLM backends used for hotspot explanation.

- [Groq](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): LLM backend · HTTP-based remote explanation backend. · `rvllm.py`
- [Claude](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): LLM backend · HTTP-based remote explanation backend. · `rvllm.py`
- [OpenRouter](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): LLM backend · HTTP-based remote explanation backend. · `rvllm.py`

### Reporting

Markdown report assembly and output files.

- [Markdown report](https://github.com/3mper0rr/reverse-llm-analysis/blob/main/rvllm.py): output writer · Writes the final Markdown analysis under rvllm_out/ with an MD5-suffixed filename. · `rvllm.py`

## Connections

- 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.
