Remix.run Logo
xerzes 8 hours ago

Hi HN,

I built this because reverse engineering software across multiple versions is painful. You spend hours annotating functions in version 1.07, then version 1.08 drops and every address has shifted — all your work invisible.

The core idea is a normalized function hashing system. It hashes functions by their logical structure — mnemonics, operand categories, control flow — not raw bytes or absolute addresses. When a binary is recompiled or rebased, the same function produces the same hash. All your documentation (names, types, comments) transfers automatically.

Beyond that, it's a full MCP bridge with 110 tools for Ghidra: decompilation, disassembly, cross-referencing, annotation, batch analysis, and headless/Docker deployment. It integrates with Claude, Claude Code, or any MCP-compliant client.

For context, the most popular Ghidra MCP server (LaurieWired's, 7K+ stars) has about 15 tools. This started as a fork of that project but grew into 28,600 lines of substantially different code.

Architecture:

  Java Ghidra Plugin (22K LOC) → embeds HTTP server inside Ghidra
  Python MCP Bridge (6.5K LOC) → 110 tools with batch optimization
  Any MCP client → Claude, scripts, CI pipelines
I validated the hashing against Diablo II — dozens of patch versions, each rebuilding DLLs at different base addresses. The hash registry holds 154K+ entries, and I can propagate 1,300+ function annotations from one version to the next automatically.

The headless mode runs in Docker (docker compose up) for batch processing and CI integration — no GUI required.

v2.0.0 adds localhost-only binding (security), configurable timeouts, label deletion tools, and .env-based configuration.

Happy to discuss the hashing approach, MCP protocol design decisions, or how this fits into modern RE workflows.

Retr0id 2 hours ago | parent | next [-]

What does your function-hashing system offer over ghidra's built in FunctionID, or the bindiff plugin[0]?

[0] https://github.com/google/bindiff

chc4 an hour ago | parent [-]

Or better yet, the built-in Version Tracker, which is designed for porting markup to newer versions of binaries with several different heuristic tools for correlating functions that are the same due to e.g. the same data or function xrefs, and not purely off of identical function hashes...

Going off of only FunctionID will either have a lot of false positives or false negatives, depending on if you compute them masking out operands or not. If you mask out operands, then it says that "*param_1 = 4" and "*param_1 = 123" are the same hash. If you don't mask out operands, then it says that nearly all functions are different because your call displacements have shifted due to different code layout. That's why the built-in Version Tracker tool uses hashes for only one of the heuristics, and has other correlation heuristics to apply as well in addition.

babas 5 hours ago | parent | prev | next [-]

How does this compare to ReVa? https://github.com/cyberkaida/reverse-engineering-assistant

I think your installation instructions are incomplete. I followed the instructions and installed via file -> install in the project view. Restarted. But GhidraMCP is not visible in Tools after opening a binary.

skerit 4 hours ago | parent [-]

I've been using ReVa for a long time (even upstreamed some changes to it) and it works great.

nunobrito 6 hours ago | parent | prev [-]

Thank you for sharing, will soon try out. Does it support decompilation of android binaries?