Skip to content

CryptoJones/Scylla

Repository files navigation

Scylla

A hexagonal, adapter-headed reverse-engineering platform.

Scylla — watch the demo
▶ Watch the demo

Scylla wraps a proven reverse-engineering engine behind a durable, transport-agnostic reverse-engineering domain model — the body — and exposes it through thin, disposable protocol adapters — the heads.

Named for the six-headed sea monster of Homer's Odyssey: many heads, one immortal body. Lop a head off and grow a new one. Today there are nine heads — an MCP server (so AI agents reverse-engineer binaries directly), a browser/WASM head, a native serving binary, a terminal CLI, a remote Cap'n Proto RPC head, an HTTP/JSON gateway, a GraphQL gateway, a TUI navigator, and an LSP server — all projecting the same body. When MCP is the CORBA of 2040, you grow a new head and the body never notices.

The idea

Reverse-engineering tools fossilize around the universal adapter of their era (Ghidra is Java-shaped because the JVM was the cross-platform answer circa 2000). You can't pick a technology that survives 20 years — so don't. Pick the right seam and bet on the slowest-moving layer.

In reverse engineering, the slowest-moving layer is the domain model itself — functions, basic blocks, cross-references, types, the call graph, symbols, decompiled output, annotations. That vocabulary barely moved from IDA in the '90s to Ghidra in the 2000s to today, and it won't move much in the next 20 years, because it isn't a technology — it's the shape of the problem.

Scylla's architecture (ports-and-adapters / hexagonal):

  • The body — a clean, minimal, transport-agnostic contract for the RE domain model, sitting on top of a proven engine (the engine is sacred; it is never rewritten).
  • The heads — thin, sheddable protocol adapters (MCP first; REST/gRPC/whatever next) that project the body to whatever consumer the era demands. Each head is ~a few hundred lines and disposable; the body is the only bet you can't take back.

You cannot shim your way out of a bad core, so the design effort goes into the body. The heads are cheap on purpose.

Before → After

Before — the current GayHydra / Ghidra implementation Scylla refactors away from: a Java monolith with the UI welded to the framework, the proven C++ decompiler reached across a brittle serialized IPC seam (warts in red, the proven engine in green):

GayHydra current architecture — the "before"

After — the hexagonal target Scylla builds toward: a durable Rust core holding the RE domain model as the system's narrow waist, GayHydra demoted to a droppable proven engine behind the engine-port, and disposable polyglot heads (MCP first) below the client-port. The two ⟡ bands are the narrow waists; the model-artifact is the one bet you can't take back:

Scylla proposed hexagonal architecture — the "after"

The reasoning behind every box is recorded in DesignDecisions.md (all 44 decisions); the build path — prototype-first — is in SprintPlanning.md; what shipped when is in CHANGELOG.md.

The heads

One body — the durable RE domain model (scylla-model) and the client port over it (scylla-port) — and nine heads today, each a thin adapter projecting the same verbs (navigate / annotate / diff / merge / export):

  • Browser (WASM)crates/scylla-wasm: the client port compiled to wasm32, so a browser navigates / annotates / diffs a .scylla model-artifact entirely client-side — no server, no engine. Renders the call graph as an actual graph, paints a structural diff onto it, searches.
  • Native single binarycrates/scylla-serve: a zero-dependency binary that bakes in the browser head and serves it + an artifact over HTTP. scylla-serve old.scylla new.scylla opens straight onto what the rebuild changed.
  • Terminalcrates/scylla-cli (scylla): materialize a binary via the engine, then diff / info / functions / search / view / callers an artifact offline. scylla diff carries git diff --exit-code semantics for CI.
  • AI agents (MCP)crates/scylla-mcp: an MCP server exposing the port 1:1 as tools (list_functions / search / get_function / callers / rename / retype / comment / diff / merge / export), so an agent reverse-engineers a binary directly. Binary-derived text is wrapped untrusted (DD-035).
  • Remote (Cap'n Proto RPC)crates/scylla-rpc: scylla-rpc-serve serves the model over TCP and scylla-rpc-connect drives it from off-box, navigating by promise-pipelining (function(id).callers().view() is one round-trip — the transport the artifact format was chosen for, DD-002), annotating (rename/retype/comment) and pulling the result back down (export). Auth-gated, connection-capped, slow-loris-bounded, TLS-capable.
  • HTTP/JSON gatewaycrates/scylla-http: scylla-http serves the model as a plain HTTP/JSON API (GET /api/info / /api/functions / /api/search?q= / /api/functions/<id> / …/callers, POST /api/diff) and lets any client annotate it (POST …/rename / …/retype / …/comment) then pull the annotated model back as a .scylla (GET /api/export), so any language, dashboard, or curl drives the full verb set — including persistence — with no special client. Token-gated and TLS-capable, like the RPC head.
  • GraphQLcrates/scylla-graphql: scylla-graphql serves the model as one typed GraphQL graph — query { info, functions, search, function, callers, diff, export } and mutation { rename, retype, comment } — so a client fetches exactly the function / caller / diff shape it wants in a single round-trip (no over- or under-fetching), with schema introspection and a GraphiQL console at GET /graphql. Token-gated and TLS-capable, like the HTTP and RPC heads.
  • TUIcrates/scylla-tui: scylla-tui is an interactive terminal navigator over the model — browse the function list, a detail pane (address, basic blocks, size, callees, callers) that follows the selection, a live / search filter, and a structural-diff pane (pass a second artifact, toggle with d) listing renamed / modified / added / removed with per-pair confidence — all over the client port. The App (model + UI state) is a pure projection of the port, conformance-tested verb-for-verb; the ratatui shell is thin on top.
  • LSPcrates/scylla-lsp: scylla-lsp is a Language Server so an editor (nvim, VS Code) navigates the model like source — the program is one virtual document (functions in address order), with go-to-symbol (documentSymbol), hover (the port's view, wrapped untrusted per DD-035), find-references (= the callers verb), rename (the annotate verb, as a WorkspaceEdit), and workspace-symbol (= search). Hand-rolled Content-Length JSON-RPC; the dispatch router is a headless, conformance-tested port projection.

The diff is a real binary-differ: it pairs functions across two builds by structural identity (address-independent), then climbs the BinDiff-style ladder — call-graph propagation, unique strings/imports, BSim feature vectors, mnemonic + ordered-trigram cosine — to report functions matched / renamed / modified / added / removed. Fail-closed throughout: a near-tie is never guessed.

Status

Feature-complete core, nine working heads. The durable Rust body (model + client port + Cap'n Proto model-artifact) is built, with a structural binary-diff engine at parity with the identity-anchored merge. The heads above all run today over that one body — including a remote RPC head over the Cap'n Proto promise-pipelining surface (DD-002), the transport the format was chosen for; the heavy JVM engine is reached over gRPC as a droppable producer (DD-009/040). Sibling project to GayHydra (a hardened fork of NSA Ghidra, which provides the proven engine Scylla wraps).

Acknowledgements

Scylla stands on work it has no intention of replacing:

  • Ghidra (NSA) — the proven reverse-engineering engine Scylla wraps, by way of the GayHydra hardened fork. The engine is sacred: Scylla demotes it to a droppable producer behind the engine-port, never rewrites it.
  • Cap'n Proto — the serialization behind the durable model-artifact (DD-002). The artifact is the one bet Scylla can't take back, so it rests on a format built for schema evolution and bounded, memory-safe reads — and chosen, too, for the promise-pipelining RPC the client port will project if a remote head ever needs it.
  • Protocol Buffers over tonic / Prost, on Tokio — the gRPC engine-port seam to the sandboxed JVM engine-as-service (DD-009/040).
  • The Rust project and its crate ecosystem — the language of the durable core.

Two serialization IDLs in one tree — Cap'n Proto on the model/client waist, Protocol Buffers on the engine seam — is a deliberate, documented choice (see DD-002), not an accident.

License

Apache License 2.0 © Aaron K. Clark — matching Ghidra (Apache 2.0), the engine Scylla builds on.


Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

About

A hexagonal, adapter-headed reverse-engineering platform — durable RE domain core + disposable protocol heads (MCP first). Sibling to GayHydra (Ghidra fork.)

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors