Binary Slicer is a Rust toolkit for slice-oriented reverse engineering of native game/engine binaries (e.g., libExampleGame.so). It helps you carve a large binary into subsystems ("slices") with explicit evidence and repeatable workflows.
No vibes, only receipts. Slice-first, evidence-first.
- Workspace layout:
ritual-corelibrary +binary-slicerbinary. - Persistent project database (
.ritual/project.db) and config (.ritual/project.json). - CLI scaffolding for projects, binaries, slices, and ritual runs:
init-projectcreates.ritual, docs/reports/graphs dirs, config, and DB.list-backendsshows available analysis backends (defaults tovalidate-only; enable optional Capstone/rizin/Ghidra backends via Cargo features). Backend selection order when running a ritual: CLI--backend> specbackend> projectdefault_backend> auto-pick (rizin if available, then capstone, then validate-only).add-binaryregisters binaries with arch + SHA-256 (or user-provided) hash.init-sliceinserts slice records and scaffolds docs underdocs/slices/<Name>.md(optionally link the slice to a default binary via--binaryso later reports/graphs pull the right analysis run).emit-slice-docs/emit-slice-reportsregenerate docs and JSON reports from the DB.list-slices/list-binariesshow stored metadata (human or JSON).
project-inforeports core paths and directory health (human or JSON).- JSON includes
available_backendsand optionaldefault_backend(settable in.ritual/project.json). backendsfield records configured tool paths (rizin, ghidra headless) if set viasetup-backend.run-ritualloads a ritual spec (YAML/JSON), validates it, and creates a per-binary output scaffold underoutputs/binaries/<binary>/<ritual>/(use--forceto overwrite an existing run). Emitsspec.yaml,report.json, andrun_metadata.json(hashes + timestamps).- Also writes
graph.dot(call edges + basic blocks) based on backend results.
- Also writes
list-ritual-specslists ritual specs underrituals/(human/JSON).list-ritual-runsenumerates runs discovered underoutputs/binaries(human/JSON).show-ritual-runprints metadata/paths for a single run (human/JSON).update-ritual-run-statusupdates run status in the DB (pending/running/succeeded/failed/canceled/stubbed).rerun-ritualreuses an existing run's normalized spec to create a new run under a new name.clean-outputssafely deletes run outputs (per binary, per ritual, or all) with--yes.- Run metadata is also persisted in the project DB (binary, ritual, hashes, status, timestamps) for easy querying.
- JSON includes
- Tests + coverage (
cargo llvm-cov --workspace --summary-onlywith gates) and local CI scripts. - Core is modular:
ritual-coreexposes a clean DB layer (db/config,db/layout,db/models,db/project_db,db/util,db/context) so frontends can load config, resolve paths, and open the project DB via shared helpers (e.g.,open_project_db,ProjectContext::from_root).
Planned next milestones:
- Ritual DSL to declare roots/boundaries and traversal rules.
- Capstone/rizin backends feeding a common IR (functions, xrefs, CFG). Capstone backend (feature
capstone-backend) now disassembles symbol-aware functions, basic blocks, and call edges (ELF/PE/Mach-O section mapping); rizin integration is next. - Slice doc/report/graph generation from the DB + analysis runs (now stubbed, later populated).
- Import/export hooks for IDA/Ghidra/rizin annotations.
Binary name: binary-slicer (CLI branding string also binary-slicer).
# 1) Init a project (creates .ritual/, docs/, reports/, graphs/)
binary-slicer init-project --root /path/to/workdir --name GameReverse
# 2) Register a binary (auto-hashes unless you provide/skip)
binary-slicer add-binary --root /path/to/workdir --path /path/to/libExampleGame.so --arch armv7
# or: --hash <precomputed> to store a provided hash
# or: --skip-hash to avoid hashing large files
# 3) Create a slice scaffold
binary-slicer init-slice --root /path/to/workdir --name AutoUpdateManager --description "Handles OTA updates" --binary libExampleGame.so
# Backend selection order for rituals: CLI `--backend` > spec `backend` > project `default_backend` > auto-pick (rizin if available, then capstone, then validate-only).
# 4) List what you have
binary-slicer list-slices --root /path/to/workdir
binary-slicer list-binaries --root /path/to/workdir
# JSON output for scripting
binary-slicer list-slices --root /path/to/workdir --json
binary-slicer list-binaries --root /path/to/workdir --json
# 5) Inspect project health/paths
binary-slicer project-info --root /path/to/workdir
# 6) Generate slice docs/reports from DB records (idempotent regeneration)
binary-slicer emit-slice-docs --root /path/to/workdir
binary-slicer emit-slice-reports --root /path/to/workdir
# 7) Run a ritual spec (analysis stub) - stores normalized spec + report under outputs/binaries/<bin>/<ritual>/
# You can choose a backend with --backend <name>; currently `validate-only` is available by default.
# If you compile with feature `capstone-backend`, `capstone` will appear in list-backends and emit symbol-aware
# disassembly evidence, basic blocks, and call-edges for binaries with symbols (fallback whole-binary disassembly
# otherwise).
cat > /path/to/workdir/rituals/telemetry.yaml <<'YAML'
name: TelemetryRun
binary: DemoBin
roots:
- entry_point
max_depth: 3
YAML
binary-slicer run-ritual --root /path/to/workdir --file /path/to/workdir/rituals/telemetry.yaml
# Example overriding backend:
# binary-slicer run-ritual --root ... --file ... --backend validate-only
# re-run with --force to overwrite an existing run output directory
# binary-slicer run-ritual --root ... --file ... --force
# 8) List ritual runs (per-binary outputs)
binary-slicer list-ritual-runs --root /path/to/workdir
binary-slicer list-ritual-runs --root /path/to/workdir --binary DemoBin --json
# 9) List ritual specs
binary-slicer list-ritual-specs --root /path/to/workdir
binary-slicer list-ritual-specs --root /path/to/workdir --json
# 10) Show a specific run (paths + metadata)
binary-slicer show-ritual-run --root /path/to/workdir --binary DemoBin --ritual TelemetryRun
binary-slicer show-ritual-run --root /path/to/workdir --binary DemoBin --ritual TelemetryRun --json
# 11) List available backends (human/JSON)
binary-slicer list-backends
binary-slicer list-backends --json
# 12) Setup a backend path (records tool path in project config)
binary-slicer setup-backend --root /path/to/workdir --backend rizin --path /usr/bin/rizin --set-default
# add --write-path to append the tool directory to your shell profile PATH
# 13) Update run status in the DB
binary-slicer update-ritual-run-status --root /path/to/workdir --binary DemoBin --ritual TelemetryRun --status succeeded
Allowed statuses: pending, running, succeeded, failed, canceled, stubbed.
# 14) Rerun an existing ritual using its normalized spec
binary-slicer rerun-ritual --root /path/to/workdir --binary DemoBin --ritual TelemetryRun --as-name TelemetryRun2
# add --force to overwrite if the target run directory already exists
# 15) Clean outputs (requires --yes; scope by binary/ritual or --all)
binary-slicer clean-outputs --root /path/to/workdir --binary DemoBin --yes
binary-slicer clean-outputs --root /path/to/workdir --binary DemoBin --ritual TelemetryRun --yes
binary-slicer clean-outputs --root /path/to/workdir --all --yesSlice docs live at docs/slices/<Name>.md and are meant to be edited by humans while also regenerated from analysis later. Reports/graphs will be emitted to reports/ and graphs/ respectively once the analysis pipeline is wired.
capstone-backend: enables a Capstone-based backend (symbol-aware disassembly with basic blocks + call-edge extraction; ELF/PE/Mach-O section mapping) and makes it available via--backend capstone.rizin-backend: rizin-backed analyzer (prefersRIZIN_BINenv, otherwiserizin) that shells out headless to discover functions/metadata. In CI or offline tests you can setBS_RIZIN_FAKE_JSON/BS_RIZIN_FAKE_GRAPH/BS_RIZIN_FAKE_STRINGSandBS_RIZIN_FAKE_VERSIONto avoid needing rizin installed.ghidra-backend: registers a Ghidra headless stub (requiresGHIDRA_ANALYZE_HEADLESSpointing toanalyzeHeadlessorGHIDRA_INSTALL_DIR); Ghidra version is recorded as evidence.setup-backendcan record tool paths in.ritual/project.json(and setdefault_backend), optionally append the tool directory to your shell profile PATH (--write-path), and best-effort detect the tool version to store alongside the path. It never installs software silently.- Recorded backend paths are preferred when running rituals and are captured in run metadata as
backend_path(andbackend_versionwhen available). - Analysis roots + per-root hits from runs are now persisted in the DB (schema v9) so slice docs/reports can be regenerated without relying on on-disk specs; migrations run automatically when you open the DB.
- Evidence/roots summaries now show up in
list-ritual-runsand JSON summaries so you can quickly see analysis coverage without opening each run. - Slice docs/reports/graphs now include backend provenance, high-level analysis summaries (functions/calls/basic blocks/evidence/roots), per-root coverage (matched vs unmatched), and per-function evidence groupings (strings/imports/calls/other) with unmapped evidence called out separately. Run/list/project summaries include root coverage too.
- DB schema upgrades are automatic on open; if you open an older DB, it will migrate to the latest (currently v9: roots + evidence kinds + root hits, run overwrites clear stale rows). Keep backups if you depend on older schema versions.
- JSON snapshots (
project-info --json,list-ritual-runs --json) include ananalysissummary per run with evidence breakdown (strings/imports/calls/other), roots count, and backend provenance.
<root>/
.ritual/
project.json # project config (name, db path, optional default_backend)
project.db # persistent SQLite DB (binaries, slices, future evidence)
docs/
slices/ # per-slice Markdown scaffolds
reports/ # structured JSON output per slice/project (regenerated via emit-slice-reports)
graphs/ # DOT/Graphviz artifacts (planned)
rituals/ # user-authored ritual specs (YAML/JSON)
outputs/
binaries/
<binary_name>/
<ritual_name>/ # per-run artifacts (normalized spec.yaml, report.json, run_metadata.json, future graphs/docs)
demos/ (optional) # scratch space if you want to keep demo runs side-by-side
Prereqs: Rust stable, cargo, plus optional tools:
cargo-llvm-covfor coveragecargo-nextest(optional) if you want to swap in faster test runner locallycargo2junitonly needed if you want local JUnit XML like CI produces
Build/test:
cargo fmt --all
cargo test
# lint (clippy, deny warnings)
cargo lint
# coverage (requires cargo-llvm-cov):
# - core gate: lines >=85%, functions >=80%
# - workspace gate: lines >=80%, functions >=55% (function metric is noisy due to clap-generated helpers)
cargo llvm-cov --package ritual-core --fail-under-lines 85 --fail-under-functions 80
cargo llvm-cov --workspace --summary-only --fail-under-lines 80 --fail-under-functions 55
# one-shot local CI (fmt + clippy + test + coverage)
# scripts:
./scripts/ci-local.sh
# or:
pwsh ./scripts/ci-local.ps1
# or cargo aliases:
cargo ci-local # bash
cargo ci-local-pwsh # PowerShell
# coverage aliases:
cargo cov-core # core-only gate
cargo cov-workspace # workspace gate
# emit LCOV (matches CI artifact)
cargo llvm-cov --workspace --lcov --output-path lcov.infocrates/core: core IR, analysis scaffolding, project DB (SQLite via rusqlite).crates/cli: CLI wiring to the core (init/list/add/emit/run commands, hashing, JSON output, ritual scaffolding).
- Deterministic, evidence-backed analysis (no AI/ML).
- Slice-first worldview with explicit roots, boundaries, and helpers.
- Scriptable and headless: rituals/DSL drive the pipeline; outputs are Markdown/JSON/DOT.
- Long-term memory: project DB tracks binaries, slices, functions, and evidence across builds.
- Interop over replacement: designed to live alongside IDA/Ghidra/rizin, not replace them.
- Ritual DSL for traversal/classification/outputs.
- Backends: Capstone + rizin first; optional Ghidra/IDA headless integration later.
- Evidence index tying doc claims to addresses/xrefs/strings.
- Cross-build diffing for binaries/slices/functions.
- Optional Python bindings for ad-hoc analysis.