Skip to content

Latest commit

 

History

2,521 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rebrew mascot

Rebrew

Compiler-in-the-loop decompilation workbench for binary-matching game reversing.

Rebrew is a reusable Python tooling package for reconstructing exact C source code from compiled binaries. It provides a genetic algorithm engine, source metadata pipeline, verification framework, and CLI tools.

Features

Core Loop

Tool What it does
rebrew test Compile your C and diff it byte-by-byte against the original binary
rebrew match GA engine — single file or batch (--all); brute-force compiler flags and mutate source to find exact byte matches
rebrew climb Deterministic hill-climb over adjacent statements in one function body — the complement to match when the residual is statement order
rebrew verify Bulk compile + report match status; auto-updates metadata unless --no-promote; --compare for CI regression checks; --watch re-verifies on every change
rebrew prove Symbolic equivalence via angr + Z3 — mathematically prove NEAR_MATCHING functions are equivalent
rebrew near-diag Classify why a NEAR_MATCHING function misses: register allocation, equivalent instruction selection, relocation masking, or structural layout
rebrew probe Measure one function against the reference without writing metadata
rebrew qual-sweep Sweep declaration qualifiers over one function, keeping winners
rebrew gap-trace Trace length-gap drift between object and reference instruction streams
rebrew residue Section diffs plus per-function attribution of remaining .text bytes

Authoring

Tool What it does
rebrew skeleton Generate annotated .c stubs from VAs; --decomp for inline decompilation; --xrefs for caller context
rebrew rename Rename a function across the entire codebase (symbol, filename, cross-references)
rebrew split Break multi-function .c files into individual files; --va to extract one function
rebrew merge Combine single-function files into one multi-function file
rebrew lint Validate source marker correctness (10 E-codes, 23 W-codes incl. W019 inline-metadata and W020 asm-dump warnings; see ANNOTATIONS.md for the emitted set)

Analysis

Tool What it does
rebrew todo Prioritized action list: what to work on next
rebrew status Per-target breakdown of EXACT / RELOC / NEAR_MATCHING / STUB counts
rebrew graph Call graph from extern declarations (mermaid, DOT, summary)
rebrew data Inventory .data/.rdata/.bss globals; detect dispatch tables and vtables
rebrew flirt Identify known library functions via FLIRT signatures — no IDA required
rebrew crt-match Cross-reference functions against CRT/library source directories
rebrew similar Rank binary functions by structural similarity to a solved function — find which STUBs share its source family
rebrew fingerprints File hashes, imphash, MSVC Rich-header hash, and per-section entropy for a binary
rebrew pe-info PE metadata dump: identity, sections with protection flags, DllCharacteristics security flags, Authenticode, debug/PDB, and Rich header
rebrew crypto-scan Detect crypto constant tables (AES/SHA/MD5), crypto imports, and crypto-named functions
rebrew security-scan Scan C sources for unsafe API use: unbounded copies, non-literal format strings, command execution, unchecked memcpy, weak randomness, non-literal alloca

Infrastructure

Tool What it does
rebrew init Scaffold a new project with config, directories, and agent skills
rebrew doctor Validate project health (config, toolchain image, binary)
rebrew catalog Build function catalog and coverage JSON
rebrew build-db Write clear-text per-target coverage documents from the catalog
rebrew cache Compile cache management (stats, clear)
rebrew cfg Read/write rebrew-project.toml settings
rebrew extract Batch extract function bytes and disassembly
rebrew binsync Umbrella for BinSync sync: push (export + git commit, optional --git-push), pull (git fast-forward + import), summary, plus init/diff/overlay
rebrew binsync-export Export source markers and metadata to BinSync state directory (IDA/BinNinja import; real types + struct fields, --module, --git)
rebrew binsync-import Import a BinSync state directory into rebrew metadata (names + prototypes + globals, --accept-binsync/--accept-local, --module)
rebrew round-trip Splice matched functions back into the target PE and verify byte equality
rebrew asm Quick offline disassembly
rebrew skills List/show the bundled agent skills
rebrew sync Sync with Ghidra: BinSync state dir field sync + MCP structural ops

Onboarding & Intelligence

Tool What it does
rebrew intake One-shot binary onboarding: init + toolchain detect + functions + document-unmatched in a single command
rebrew analyze One-shot intelligence dossier for a binary — layout, toolchain, strings, imports, dispatch tables, FLIRT matches. Works standalone outside a project
rebrew discover-functions Function enumeration (rizin aaa/aap + capstone sweep + .eh_frame / .pdata unwind tables) with validated boundaries and sizes
rebrew document-unmatched Write STUB skeletons + blockers for every function in the list that isn't documented yet (re-discovery workflow; idempotent)
rebrew identify-library Identify library functions (FLIRT + imports + CRT) into library_*.h; --build-sigs generates the sigs from the toolchain .lib files first
rebrew pdb-info Extract compiler version, flags (S_COMPILE3), and function names from a PDB

Design

  • Config-driven — all tools read from rebrew-project.toml, zero manual path arguments
  • Multi-target — PE, ELF, Mach-O, and 16-bit Windows NE across x86-16, x86, x64, ARM32/64 with --target selection
  • Idempotent — every tool is safe to re-run
  • Composable — small single-purpose tools designed for scripting and AI agent chaining
  • Compile cache — disk-backed SHA-256 cache avoids redundant recompilations
  • Agent-friendly — bundled agent-skills/ copied to projects on rebrew init

Agent Skills

Six bundled skills for AI coding agent integration:

Skill Purpose
rebrew-init Scaffold a new project from a bare directory + binary
rebrew-workflow End-to-end reversing workflow and status tracking
rebrew-matching GA matching engine, flag sweeps, diff analysis
rebrew-data-analysis Global data scanning, BSS layout, dispatch tables
rebrew-intake Binary onboarding, triage, and initial FLIRT scanning
rebrew-ghidra-sync Ghidra field sync via BinSync; ReVa MCP only for create-functions, bookmarks, and pull-data

Quick Start

Host requirements: Linux x86_64 with Docker. Every Windows/DOS compiler profile executes inside its toolchain image (wine/DOSBox live in the image; there is no host wine path) — build or pull it with rebrew toolchain build <name> (see docs/TOOLCHAIN.md). Shipped compiler images are *-linux-x64 / *-win32 / *-win16, plus the IDO rebrew/ido:<version>-linux images; CI runs on ubuntu-24.04 (x86_64). Analysis-only commands (asm, analyze, flirt, catalog, …) are pure Python 3.13+ and avoid host-OS assumptions in path and text I/O, but are only CI-validated on Linux x86_64.

# 1. Install
uv tool install git+https://github.com/maci0/rebrew.git

# 2. Create a project
mkdir my-decomp && cd my-decomp
rebrew init --target server --binary server.dll

# 3. Place your binary
cp /path/to/server.dll original/

# 4. Start reversing
rebrew doctor                       # verify setup
rebrew todo -c start-function       # find easiest uncovered functions
rebrew skeleton 0x10003DA0          # generate first stub
rebrew test src/server/func_10003da0.c  # compile and compare

rebrew init creates rebrew-project.toml, source/bin directories, and agent skills. All tools find the config by searching upward from the current directory (like git finds .git/).

Library usage

Install as a dependency (uv add git+https://github.com/maci0/rebrew.git or pip install from the same URL). Import submodules directly. The same entry points are also attributes of the package (from rebrew import load_config), loaded on first use, and a star-import binds them along with __version__:

from rebrew.config import load_config
from rebrew.errors import RebrewError
from rebrew.sources import iter_sources
from rebrew.toolchain import ToolchainError, get_toolchain

cfg = load_config()  # walks up for rebrew-project.toml
for path in iter_sources(cfg):  # a bare path works too: iter_sources("src/game")
    print(path)

try:
    get_toolchain(cfg.compiler_profile)  # e.g. "msvc-6.0"
except ToolchainError as exc:
    # Branch on exc.kind / exc.name / exc.retryable — not message substrings.
    raise

# The legal profile names are the registry, not a hardcoded list. TOOLCHAINS
# maps name -> ToolchainSpec, so a consumer can enumerate and inspect them
# with attributes rather than parsing `rebrew toolchain list` output:
from rebrew.toolchain import TOOLCHAINS, get_toolchain

for name, spec in sorted(TOOLCHAINS.items()):
    print(name, spec.family, spec.bits, spec.obj_ext, spec.image)

# `list_toolchains()` is the other view of the same table: `rebrew toolchain
# list --json` prints it verbatim, as a list of dicts. Reach for it when you
# want the origin and the docker-present flag alongside each row.

# Byte-level matching uses the same entry as the CLI:
#   from rebrew.compile import CompareResult, CompareStatus, compile_and_compare
#   result = compile_and_compare(cfg, source_path, symbol, target_bytes, cflags)
#   result.matched / result.status / result.match_percent / result.message
#   `status` is a `CompareStatus` ("EXACT" / "RELOC" / "NEAR_MATCHING" /
#   "COMPILE_ERROR" / ...), so an annotation on it type-checks.

Remote compile transport, registry plugins, workspace helpers, and the GA matcher follow the same pattern (rebrew.recompile_client, rebrew.registry, rebrew.plugin, rebrew.workspace, rebrew.matcher). Every error class is importable from rebrew.errors, whichever submodule defines it. Catch the specific type (ConfigError, RecompileError, McpError, ToolchainError, RegistryError, ...) when the recovery differs per failure, and RebrewError when it does not:

try:
    result = compile_and_compare(cfg, source_path, symbol, target_bytes, cflags)
except RebrewError as exc:
    if exc.retryable:
        ...  # transient docker/daemon blip or transport hiccup
    raise

# A remote recompile failure does not raise: it is a COMPILE_ERROR result
# with the structured error attached, so the retry decision survives the
# compile boundary.
if result.status == "COMPILE_ERROR" and result.error is not None:
    if result.error.retryable:
        ...  # compile service unreachable / 503 - retry later
    else:
        ...  # the service rejected the request; rebrewing the C will not help

Persisting that result keeps the decision: CompareResult.to_dict() writes error through RebrewError.to_dict(), and CompareResult.from_dict() reads it back as the same exception class, so result.error.retryable and result.error.kind still work on a result loaded from JSON. RebrewError gains the same to_dict() / from_dict() pair for any other error you store.

Every rebrew error type inherits RebrewError alongside its original RuntimeError/ValueError base, so a new error type in a later release lands in that handler instead of escaping it. The structured fields kind, name, status_code and group are declared on that base too, so one except RebrewError can read them without getattr; a field the arriving error does not fill is None, and a serialized error leaves it out.

The clients that talk to a service take the HTTP client as an argument, so your tests never need a live one. HttpClient (from rebrew.recompile_client or rebrew.decompme) is the two-method shape those clients call: .post and .get. A stand-in that takes **kwargs satisfies both, so one fake covers both of them. What it returns is a reply, and that is typed too: HttpResponse names the members each transport reads. rebrew.recompile_client needs status_code, text, json() and content (the artifact bytes); rebrew.decompme needs the same minus content plus close(), because the module-level httpx.post / httpx.get reply owns a connection. An httpx.Response satisfies both, and a stand-in missing a member is a type error rather than a wrong value at the far end:

from rebrew.recompile_client import compile_source


class _Reply:
    """Satisfies rebrew.recompile_client.HttpResponse."""

    def __init__(self, status_code, *, json_body=None, content=b"", text=""):
        self.status_code = status_code
        self._json = json_body
        self.content = content
        self.text = text

    def json(self):
        if self._json is None:
            raise ValueError("not json")
        return self._json


class FakeService:
    def post(self, url, **kwargs):
        return _Reply(200, json_body={"status": "ok", "artifact_url": "/api/v1/artifacts/1.obj"})

    def get(self, url, **kwargs):
        return _Reply(200, content=b"\x90" * 8)


result = compile_source(
    "http://localhost:8080",  # base URL
    "msvc-6.0",  # compiler
    "int f(void) { return 0; }",  # source
    ["/O2"],  # flags: a str is split on whitespace
    client=FakeService(),
)
result.ok / result.obj_bytes / result.log / result.compiler_version

# No client means rebrew builds an httpx.Client(timeout=...) for the call and
# closes it after. `retries=N` re-attempts a retryable RecompileError with
# exponential backoff; `RecompileError.kind` is "network" / "http" /
# "validation" / "protocol" and `status_code` is set for the "http" ones.
# `result.to_dict()` / `RecompileResult.from_dict()` store the verdict (not
# the object bytes) the way `CompareResult` does.
#
# `rebrew.decompme`'s `upload_scratch` is the same shape: `client=` injects a
# stand-in, and `retries=N` re-attempts a retryable `DecompmeError` on the
# same backoff (`retry_backoff_delay` in `rebrew.utils`) and the same
# transient status set, so both service clients recover from a blip the
# same way. Its `payload` is what `build_scratch_payload` returns (a `data`
# form mapping and a `files` multipart mapping); both keys are checked before
# the request is built, so a payload you assembled wrongly arrives as
# `kind="validation"`, not as a network failure a retry could chase.

The ReVa MCP client (rebrew.ghidra, the transport behind rebrew sync) injects McpHttpClient instead: post and delete, because it opens a session and terminates it on every exit path. Both take a url plus **kwargs (the JSON-RPC json= body, the headers session id, the per-call timeout), so a stand-in carrying those two methods satisfies it. The reply is typed as McpResponse and has to carry status_code, headers, text, json() and raise_for_status(). That is the FakeService above with delete added, over a _Reply that also carries headers and raise_for_status(). close() is optional on both reply protocols, so a stand-in holding no connection to release is still a valid answer.

The CLI commands, flags, and the rebrew-project.toml schema are frozen for the 2.x line. The Python import surface and the dashboard /api/* JSON are not: a removal, move, or signature change there ships in a minor release with a **Breaking:** entry in the changelog, and there is no deprecation window, so pin the minor version if you import rebrew as a library. See CONTRIBUTING.md.

Usage & Workflow

Most CLI tools must be run from within a project directory that contains a rebrew-project.toml config file. The analysis-only commands (analyze, toolchain detect) also work standalone against a binary path.

cd /path/to/your-decomp-project    # must contain rebrew-project.toml

# Project Setup
rebrew init --target mygame --binary mygame.exe --toolchain msvc-6.0 # initialize project
rebrew cfg list-targets              # list configured targets
rebrew cfg set-cflags ZLIB "/O3"        # set the cflags preset for module ZLIB
rebrew cfg set compiler.cflags "/O1" # set a config value
rebrew cfg show targets.main.arch     # read a value (supports dotted target names)
rebrew cfg raw                       # dump config as JSON
rebrew cfg path                      # print config file path
rebrew cfg detect-crt --write        # auto-detect MSVC CRT source directories

# Development
rebrew skeleton 0x10003DA0          # generate C skeleton from disassembly
rebrew skeleton --xrefs 0x10003DA0  # skeleton with Ghidra cross-reference context
rebrew test src/target_name/f.c     # test implementation against target
rebrew todo                         # see highest ROI action items
rebrew todo --stats                 # show overall progress statistics
rebrew todo -c fix-delta --json     # tiny byte diffs (quick wins, sorted by ROI)
rebrew todo -c extract-error        # symbols missing from .obj (marker/impl issue)
rebrew flirt --json                 # FLIRT scan: identify known library functions
rebrew crt-match 0x10006c00         # match a single VA against CRT source
rebrew crt-match --all                     # match all library functions
rebrew crt-match --fix-source --all  # auto-write // SOURCE: markers
rebrew crt-match --index            # show CRT source index
rebrew graph --cu-map               # infer compilation unit boundaries
rebrew graph --cu-map --json        # JSON output for scripting
rebrew lint                         # lint source markers in your files
rebrew split src/target_name/multi.c           # split multi-function file into individual files
rebrew split --va 0x10003DA0 src/target_name/multi.c  # extract one function into multi_c/
rebrew merge --output merged.c a.c b.c          # merge files into one multi-function file
rebrew merge -o multi.c --force --delete multi_c/ multi.c  # merge extracted function back
rebrew catalog                      # summarize the function catalog
rebrew catalog --export-ghidra-labels  # generate ghidra_data_labels.json from detected tables
rebrew build-db                     # write db/coverage-<target>.toml
rebrew binsync-export ./binsync_out # export source markers and metadata to BinSync state directory
rebrew binsync-import --dry-run ./binsync_out # import names + prototypes + globals from a BinSync state (dry-run)

# Matching
rebrew diff src/target_name/f.c                     # side-by-side disassembly diff
rebrew diff --mismatches-only src/target_name/f.c  # show only structural diffs (**)
rebrew match src/target_name/f.c    # run the Genetic Algorithm Engine to resolve diffs
rebrew match --all                          # batch GA on all STUB functions
rebrew match --all --improve                # batch GA on all NEAR_MATCHING functions
rebrew match --all --near-miss --threshold 5 # batch GA on NEAR_MATCHING with ≤5B delta
rebrew match --all --flag-sweep             # batch flag sweep on all NEAR_MATCHING functions
rebrew match --all --flag-sweep --fix-cflags  # sweep NEAR_MATCHING, write CFLAGS on an exact match

# Semantic Equivalence (requires angr: uv tool install --reinstall 'rebrew[prove] @ git+https://github.com/maci0/rebrew.git')
rebrew prove src/server.dll/calculate_physics.c      # prove NEAR_MATCHING function equivalent
rebrew prove --json src/server.dll/calculate_physics.c  # JSON output
rebrew prove --dry-run my_func                       # find by symbol, preview only

# Export & Sync
rebrew verify                       # bulk compile and auto-update STATUS/BLOCKER metadata
rebrew verify --json                # structured JSON report to stdout
rebrew verify --compare             # detect regressions against last saved report
rebrew split --dry-run src/target_name/multi.c  # preview split without writing
rebrew split --va 0x10003DA0 --dry-run src/target_name/multi.c  # preview single extraction
rebrew merge -o merged.c --delete a.c b.c       # merge and delete originals
rebrew extract list                 # list un-reversed candidates
rebrew extract batch 20             # extract and disassemble first 20 smallest
rebrew asm                          # quick offline disassembly
rebrew cache stats                  # show compile cache hit rate and size
rebrew doctor                       # validate config, toolchain image, and binary

# Ghidra Sync via BinSync state dir + ReVa MCP
rebrew sync --push                  # export source markers and metadata to the state dir
rebrew sync --pull                  # import the state dir into rebrew
rebrew sync --pull --accept-binsync # accept BinSync names on pull conflicts
rebrew sync --pull-data             # pull Ghidra data labels into rebrew_globals.h (MCP)
rebrew sync --create-functions      # create functions in Ghidra (MCP)
rebrew sync --bookmarks             # set status bookmarks in Ghidra (MCP)
rebrew sync --pull --dry-run        # preview pull without modifying files

Match Statuses

Every annotated function carries a STATUS. Status is earned, never claimed: rebrew verify / rebrew test derive it from the real byte comparison of the compiled .c against the target binary, and write it through the metadata writer. A hand-claimed status is demoted to the actual byte result with a metadata: warning.

Status Meaning How it is earned
EXACT Compiled bytes identical to the target rebrew verify — every non-relocation byte matches
RELOC Identical except relocation slots rebrew verify — all non-reloc bytes match and the reloc slots (linker-filled symbol addresses) validate against the catalog
PROVEN Semantically equivalent despite structurally different bytes rebrew prove (symbolic equivalence via angr/Z3). Not a byte match and not protected: the next rebrew test / rebrew verify records the byte result (NEAR_MATCHING, EXACT, …) over it
NEAR_MATCHING Close but not byte-identical — at least 60 % of bytes match rebrew verify — typically register allocation, instruction scheduling, or a flag variant; try rebrew match --flag-sweep
STUB Below the 60 % near-match threshold — the skeleton was never implemented, or control flow diverges rebrew verify, or manual classification for known-unimplemented code
SKIP Intentionally not worked on (data, out of scope) manual classification
SIZE_MISMATCH Compiles, but the object length differs from the target rebrew verify
COMPILE_ERROR The C does not compile under the function's toolchain and flags rebrew verify
EXTRACT_ERROR The compiled object or the target bytes could not be extracted rebrew verify
MISSING_SIZE / MISSING_FILE Target function size unknown / target binary missing rebrew verify
INVALID_VA Annotation VA sits below the architecture's code floor rebrew verify (annotation problem)

Typical progress runs STUB → NEAR_MATCHING → EXACT / RELOC, with PROVEN for code that is semantically correct but structurally different. Only EXACT and RELOC count as matched; PROVEN functions stay on rebrew todo as improve-match work (rebrew status summarizes the rest). Source-marker mechanics live in docs/ANNOTATIONS.md.

Supported Platforms

Architecture Binary Format Compiler Binary Loading Object Parsing GA Matching Verification
x86 (16-bit) NE (Windows 3.x) Borland Delphi 1.0 / Turbo Pascal ✅ ⬜ ⬜ ⬜
x86 (16-bit) NE (Windows 3.x) MSVC 16-bit (C 7.0 / VC 1.x) ✅ ✅ ✅ ✅
x86 (32-bit) PE (.exe/.dll) MSVC 5.0 / 6.0 ✅ ✅ ✅ ✅
x86 (32-bit) PE MSVC 7.x+ ✅ ✅ ✅ ✅
x86 (32-bit) PE MinGW GCC / Zig (mingw-16.2.0 profile) ✅ ✅ ✅ ✅
x86 (32-bit) PE Watcom C ✅ ✅ (OMF→COFF via objconv) ✅ ⬜
x86 (32-bit) ELF (.so/exec) GCC/Clang ✅ ✅ ⬜ ⬜
x86_64 PE MSVC ✅ ✅ ⬜ ⬜
x86_64 ELF GCC/Clang ✅ ✅ ⬜ ⬜
x86_64 Mach-O Clang ✅ ✅ ⬜ ⬜
ARM32 ELF GCC/Clang ✅ ✅ ⬜ ⬜
ARM64 ELF GCC/Clang ✅ ✅ ⬜ ⬜
ARM64 Mach-O Clang ✅ ✅ ⬜ ⬜

Legend: ✅ Supported ⬜ Planned / Not yet implemented (a linked output with no per-function object, such as delphi-1.0, also has no byte-matching path)

16-bit NE targets are parsed, enumerated, and analyzed natively (intake, analyze, asm, describe, data, report — see docs/TOOLCHAIN.md). Byte matching and rebrew verify run when the project profile is registered with bits = 16 and emits a per-function object (msvc-1.0, msvc-1.5, msvc-1.52, borland-2.0, borland-3.1, watcom-2.0-win16, or a plugin that declares the same). delphi-1.0 is 16-bit but emits a linked NE, so verify skips it. Any other profile short-circuits with a notice naming the object profiles and exits 2.

Toolchain detection: rebrew intake/analyze auto-detect the compiler family and version — DIE (diec) signatures first, then PDB records, then PE metadata (Rich header, linker version), then structural heuristics (strings, imports, codegen style, section layout). 16-bit NE family comes from the Borland segment-marker convention (delphi vs MSVC-style markerless segments). When diec misses a compiler record, the Microsoft Linker version still pins the MSVC era.

Compiler profiles: msvc-6.0 is the default — every profile (all msvc* from 1.0 through 11.0, borland-5.5, borland-3.1/borland-2.0, watcom-2.0-win32/watcom-2.0-win16, delphi-1.0, gcc-14.2.0/gcc-12.3.0, clang-18.1.8/clang-16.0.4, mingw-16.2.0/mingw-14.2.0, ido-5.3/ido-7.1) compiles inside a per-toolchain docker image (wine/DOSBox/a native Linux compiler live in the image; there is no host wine/wibo path). mingw-16.2.0 targets MinGW GCC / Zig PE builds, gcc-14.2.0/clang-18.1.8 cover ELF/x86_64, and watcom-2.0-win16 is the 16-bit DOS Watcom profile. Service-pack variants (msvc-6.0-sp1–msvc-6.0-sp6, msvc-7.0-sp1, …) cover the pin-specific codegen differences. Profile selection happens automatically on rebrew intake from the detected family; the full list is rebrew toolchain list.

Development

Clean clone needs uv, Python 3.13+ (.python-version), nasm and node on PATH, a sibling resembl checkout at ../resembl (tag v3.1.0, matching CI RESEMBL_REF / uv.lock; make setup also requires HEAD to be the RESEMBL_SHA commit CI's resembl-sha pins), and bash for the make clone-resembl step below. node drives the tests/dashboard_*.mjs interaction tests, which skip without it, so make test fails on a missing node while make test-one only warns. shellcheck is optional locally but not in CI: the pre-commit shell hook skips itself without it, so make check warns rather than fails, and CI's pre-commit job installs it. See CONTRIBUTING.md; make help lists targets. Run the following from the directory that will hold both checkouts:

git clone https://github.com/maci0/rebrew.git
cd rebrew/
make doctor                # report every missing prerequisite (uv, ../resembl, bash, nasm,
                           # node, shellcheck, venv extras) with the fix for each; read-only
make clone-resembl         # clone sibling resembl pin (tag v3.1.0) into ../resembl
make setup                 # uv sync --locked --all-extras --group similarity + pre-commit hooks
make add-dep ADD_DEP_SPEC=<spec>  # add a dependency (wraps `uv add`; prints the license-table step)
make test-one T=tests/test_annotation.py   # single-file edit-test loop
make test                  # full suite (needs nasm + node)
make lint                  # ruff check (same as CI)
make format                # ruff format (writes)
make all                   # local gates: format-check, lint, mypy, audit, coverage, gen-fixtures-check, cycles-check, layering-check, idempotency-check, cli-contract
make check                 # pre-commit hook parity (before a PR)
make build                 # sdist + wheel + dist/rebrew.buildinfo (CI package job)
make clean                 # remove build/dist artifacts and caches

Flag-axis refresh from decomp.me (maintainer, needs network): uv run --frozen python tools/sync_decomp_flags.py.

Flag Sweep Tiers

The flag sweep uses compiler flag definitions synced from decomp.me. The generate_flag_combinations(tier) function supports five effort levels: quick (192 combos), targeted (~1.2K combos), normal (~5.4K combos), thorough (~258K combos; stride-sampled down to ~51.6K), and full (~6.2M combos; stride-sampled down to ~95.3K, under a 100K memory bound). The msvc-6.0 compiler profile automatically excludes incompatible MSVC 7.x+ flags. See docs/FLAG_SWEEP_TIERS.md.

Ecosystem & Related Tools

Projects rebrew integrates with or draws from:

Integrated

Tool Role Integration
decomp.me Collaborative decompilation platform Flag axes synced via tools/sync_decomp_flags.py; powers rebrew match --flag-sweep
reccmp Binary recompilation comparison framework Source marker format compatibility: reccmp's parser reads rebrew source files
LIEF Binary format parsing (PE/ELF/Mach-O) Used for binary loading, format detection, and PE section analysis
Capstone Disassembly engine Powers rebrew asm, byte-diff scoring, relocation masking, and mnemonic comparison
angr Binary analysis + symbolic execution Powers rebrew prove for Z3-based semantic equivalence proving (optional dep)
declib BinSync artifact layer BinSync state export/import/diff/overlay (binsync extra, declib>=4.5)
ReVa Ghidra MCP bridge rebrew sync structural ops (create-functions, bookmarks, pull-data); field sync is BinSync-primary

Adjacent Tools

Tool What it does Relevance
asm-differ Assembly diff with levenshtein alignment Used by decomp.me for all diffs; rebrew has its own capstone-based differ
decomp-permuter Source-level permutation finder for matching decompilation Complementary to rebrew match's GA: explores semantic-preserving C rewrites (variable types, statement order, parenthesisation) until the compiler emits identical assembly. Candidate for integration as an alternative mutation engine or seed source for the GA.
objdiff Rust GUI for object file diffing (COFF/ELF/Mach-O) Visual companion for inspecting match differences
decomp-toolkit GameCube/Wii decompilation toolkit DOL/REL focused; similar split/link/diff workflow concepts
wibo Lightweight Win32 PE loader Optional host download (rebrew doctor --install-wibo). Shipped compiles run inside the toolchain image; a host wibo is not the compile path
Ghidra NSA's reverse engineering suite Primary disassembler/decompiler; connected via ReVa MCP
FLIRTDB FLIRT signature database Signatures for MSVC, Borland, MinGW used by rebrew flirt

Companion Projects

Project What it is
recompile.online Compiler-as-a-service API over the rebrew toolchain zoo — submit C + a toolchain id, get the compiled artifact (separate workspace: ../recompile)
recoverage Coverage dashboard over rebrew build-db output

License

MIT. See LICENSE.

Optional installs use separate grants, named in NOTICE: the similarity group (resembl, GPL-3.0-only), the m2c group (GPL-3.0-only), and the prove extra (pyvex ships LibVEX under GPL-2.0-or-later).

About

Compiler-in-the-loop decompilation workbench for binary-matching game reversing.

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages