Skip to content

Repository files navigation

🔍 recoverage

recoverage mascot — a raccoon detective investigating code coverage
Coverage dashboard for binary-matching decompilation projects.
See every byte. Track every match. Ship the decomp.

Install · Quick Start · Screenshots · Potato Mode


What is recoverage?

recoverage serves a local web dashboard that visualises per-byte match status across .text, .data, .bss, and other PE sections of a decompilation project. Think of it as a defrag map for your decomp — every byte of the original binary is a cell in a grid, colored by how closely your C code matches the original compiled output.

🚀 Features

  • Byte-Perfect Confidence: Stop guessing if your C code produced the correct assembly. See exact byte comparisons visually.
  • Fast Iteration: Quickly identify which parts of a function are matching and which parts have diverged (e.g. register allocation differences, instruction reordering).
  • Interactive Triage: Click any block in the grid to immediately view the corresponding C source, disassembled binary, and hex diff.

✨ Highlights

🧱 Defrag-style grid One cell per chunk — Exact (green), Reloc (cyan), Matching (yellow), Stub (red), None (gray)
🔎 Function detail panel Click any cell to see metadata, C source, disassembly, and hex dump side-by-side
🌗 Light & dark themes Retro CRT dark mode by default, clean light mode one click away
🔗 Clickable cross-references Hex addresses in disassembly are live links — click to jump to that chunk
📊 Interactive progress bar Segmented by status; click a segment to filter the grid
🗜️ First draw in first TCP packet HTML + CSS + JS inlined & compressed (Brotli/Zstd) to ~14.5 KB
🥔 Potato Mode Zero-JS server-rendered fallback for constrained environments
🔄 Live regen One-click re-catalog + rebuild without restarting the server

Screenshots

Main Dashboard

Main dashboard — coverage grid with section tabs and filter buttons

Function Detail

Function detail panel showing metadata, C source, and disassembly

Dark Mode

Dark mode with function detail panel

🥔 Potato Mode

Potato Mode — retro pure-HTML table view

Potato Mode is a zero-JavaScript, server-side rendered HTML fallback. Every view is a plain HTML table — no CSS, no JS — so it works on low-spec machines, restricted browsers, or anywhere you just want a quick glance without loading the full SPA.


Installation

pip install recoverage

For development:

uv pip install -e .

Optional runtime extras

Install an extra to enable its feature: pip install 'recoverage[<extra>]' (or uv sync --extra <extra> in a workspace).

Extra Package What it does
capstone capstone Enables on-demand disassembly in the detail panel
pygments pygments Syntax highlighting in Potato Mode
playwright playwright, pytest-playwright Browser integration tests (tests/test_playwright.py)

Quick Start

# 1. Generate the coverage database (from your project directory)
uv run rebrew catalog --json
# Analyzes the target binary, parses your annotations, and dumps raw match data to db/data_*.json

uv run rebrew build-db
# Consumes the JSON files and builds a fast SQLite database (db/coverage.db) for the dashboard

# 2. Start the dashboard
uv run recoverage serve
# Starts a lightweight Bottle web server serving the frontend SPA and providing the API backend

Note

The server resolves coverage.db from the current working directory: [project] db_dir in rebrew-project.toml when set, falling back to db/coverage.db — so run it from your project root.


CLI Commands

recoverage serve

Start the dashboard web server.

Flag Default Description
--port 8001 HTTP port to serve on
--bind 127.0.0.1 Interface to bind to (use 0.0.0.0 for LAN access)
--allow-remote off Required with a non-loopback --bind: acknowledge the API is reachable on the network
--token off Require this token for every request (Authorization: Bearer, ?token=, or open /?token=<token> to set the SPA cookie)
--no-open off Don't auto-open the browser
--regen off Run rebrew catalog + rebrew build-db before starting
--cors off Enable CORS processing (allowlisted origins only; the wildcard is never emitted)
--cors-origin none Origin URL allowed to read the API cross-origin (repeatable; without it --cors allows no cross-origin reads)

recoverage stats

Print per-section coverage stats as a Rich table, or as JSON with --json.

recoverage stats                    # all targets
recoverage stats --target SERVER    # single target
recoverage stats --json             # machine-readable

recoverage export

Export coverage data to stdout.

recoverage export --format json     # JSON (default)
recoverage export --format csv      # CSV
recoverage export --format md       # Markdown table

recoverage check

CI gate — exits non-zero if coverage is below a threshold. Sections the grid never records matches for (e.g. .bss/.data when only .text matches are tracked) are skipped, not failed.

recoverage check --min-coverage 60                              # all targets, all sections
recoverage check --min-coverage 60 --target SERVER --section .text   # specific
recoverage check --min-coverage 60 --json                       # machine-readable verdict

Exit codes: 0 = gate passed, 1 = coverage below threshold (or bad input), 2 = infrastructure error (database missing/unreadable).

recoverage regen

Re-run rebrew catalog + rebrew build-db to regenerate coverage.db.

recoverage regen

recoverage open

Open the dashboard in a browser (useful when --no-open was used).

recoverage open --port 8001

API Endpoints

Path Method Description
/ GET Main SPA dashboard
/potato GET Potato Mode (pure-HTML fallback)
/api/health GET Server version, DB info, installed extras
/api/targets GET List available targets
/api/targets/<target>/stats GET Per-section coverage stats with percentages
/api/targets/<target>/data GET Section + cell data (?section=.text for partial)
/api/targets/<target>/functions GET Paginated list (?status=&search=&sort=&limit=&offset=)
/api/targets/<target>/functions POST Batch lookup: {"vas": [...]} → function/global details in input order
/api/targets/<target>/functions/<va> GET Single function/global detail
/api/targets/<target>/asm GET Disassembly (?format=json for structured output)
/api/targets/<target>/sections/<section>/bytes GET Raw byte slice (?offset=&size=)
/api/events GET Server-Sent Events: db-updated when coverage.db changes (SPA auto-refresh)
/api/regen POST Re-run catalog + build-db (localhost only, rate-limited)

Architecture & How it works

recoverage is designed as a standalone consumer of the data that rebrew produces — the two packages are intentionally decoupled.

rebrew catalog --json          rebrew build-db           recoverage (Bottle + SQLite)
       │                             │                       │
  db/data_*.json  ──────────▶  db/coverage.db  ──────────▶  VanJS Dashboard
  1. rebrew catalog --json: Scans your project's source annotations and writes intermediate db/data_*.json files containing coverage metrics. Jump table / switch data bytes are absorbed into their parent function's size. Use --export-ghidra-labels to generate ghidra_data_labels.json for round-trip Ghidra sync.
  2. rebrew build-db: Consumes those JSON files and builds a structured db/coverage.db (SQLite v4 schema) database, storing per-function metadata (detected_by, size_by_tool, textOffset), per-global metadata (module, size), per-cell metadata (label, parent_function), and stamping db_version for schema detection. See DB_FORMAT.md for the full schema.
  3. recoverage: Starts a Bottle web server. The backend serves API endpoints querying the SQLite database, while the frontend is a zero-build Single Page Application (SPA) powered by VanJS, rendering the interactive defrag grid.

You can run recoverage independently on any machine (or even host it remotely) as long as it has access to a compiled coverage.db — no rebrew dependency or compiler toolchain is required.


Project layout

recoverage/
├── pyproject.toml
├── README.md
├── docs/                     # Screenshots, mascot & design doc
│   ├── DESIGN.md             # Detailed architecture & design doc
│   ├── DESIGN_PRINCIPLES.md  # Core operational philosophies
│   ├── USER_STORIES.md       # User stories with acceptance criteria
│   └── ideas.md              # Future improvement ideas
├── tests/
│   ├── conftest.py           # Shared fixtures (synthetic coverage.db)
│   ├── test_api.py           # API validation & security tests
│   ├── test_cli.py           # CSV export, formatting tests
│   ├── test_lifecycle.py     # Process lifecycle (regen timeouts, opener reaping)
│   ├── test_paths.py         # DB path resolution tests
│   ├── test_server.py        # Compression, encoding tests
│   ├── test_potato.py        # Potato Mode rendering tests
│   └── test_playwright.py    # Browser integration tests
└── src/recoverage/
    ├── __init__.py
    ├── __main__.py           # python -m recoverage
    ├── _paths.py             # DB path resolution (rebrew-project.toml db_dir)
    ├── cli.py                # Typer CLI entry point
    ├── server.py             # Bottle app, shared helpers & compression
    ├── regen.py              # rebrew regen subprocess lifecycle (group kill + reap)
    ├── api.py                # REST API routes (/api/*)
    ├── ui.py                 # UI routes (/, /potato, static files)
    ├── potato.py             # Potato Mode renderer
    ├── webapp.py             # Composition root: imports api+ui so app has every route
    └── assets/
        ├── index.html        # SPA shell
        ├── style.css         # All styles
        ├── print.css         # Print stylesheet
        ├── app.js            # VanJS frontend
        ├── detail.js         # Deferred panel logic (hex dump, modal, live reload)
        ├── van.min.js        # VanJS library (~2 KB)
        ├── favicon.svg       # Retro "R" logo favicon
        ├── hljs.min.js       # Highlight.js core
        ├── hljs-c.min.js     # Highlight.js C grammar
        ├── hljs-x86asm.min.js # Highlight.js x86 asm grammar (hex lang is in detail.js)
        └── hljs.css          # Highlight.js theme

Vendored third-party assets

The browser libraries under src/recoverage/assets/ are vendored so the dashboard works air-gapped (see docs/DESIGN.md); nothing is fetched from a CDN at runtime. Licenses and versions are recorded here because the minified blobs themselves carry little provenance:

File Upstream Version License
van.min.js VanJS core, classic-script build (window.van) not embedded in the blob MIT (upstream license)
hljs.min.js Highlight.js core 11.11.1 (in-file banner) BSD-3-Clause
hljs-c.min.js Highlight.js c grammar compiled for 11.11.1 BSD-3-Clause
hljs-x86asm.min.js Highlight.js x86asm grammar compiled for 11.11.1 BSD-3-Clause

hljs.css is a first-party theme (not upstream Highlight.js CSS). When re-vendoring any of these files, keep the upstream license banner in the minified output so this table stays verifiable against the blobs.


License

MIT

About

Coverage dashboard for binary-matching decompilation projects

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages