sabercat204/muninn-ghidra
GitHub: sabercat204/muninn-ghidra
一款 Ghidra 扩展插件,通过内置 MCP 服务器将逆向工程工具集暴露给 AI 客户端,支持 x64 和 ARM 二进制文件的自动化分析。
Stars: 0 | Forks: 0
# muninn-ghidra
二进制文件的记忆。以北欧神话中奥丁的记忆之鸦(Muninn)命名——该项目旨在恢复被编译器剥离和被混淆器隐藏的内容。
这是一个用于 Ghidra 的单进程 Java 扩展,内置了一个模型上下文协议(MCP)服务器。它将逆向工程工具暴露给 MCP 客户端(如 Claude Code、自定义集成),用于 x64 / ARM 固件和游戏二进制文件分析。
**状态:** 1.0 版之前,属于个人研究范畴。目前已实现五个工具;采用规范优先的方法论——每个工具在实现之前,都会根据库内的行为规范进行编写。
## 环境要求
- Ghidra 12.x
- JDK 21 LTS
- Gradle(任意 8.x 或 9.x 版本;已在 9.5 上测试)
- `GHIDRA_INSTALL_DIR` 环境变量需指向 Ghidra 的安装根目录(即包含 `Ghidra/`、`support/` 等的目录)
## 构建
```
export GHIDRA_INSTALL_DIR=/path/to/ghidra__PUBLIC
gradle buildExtension
```
生成 `dist/ghidra__PUBLIC__muninn-ghidra.zip`(约 8 MB;包含 Jetty 12、Jackson 2.19、MCP Java SDK 0.17.1 及其传递依赖)。
## 安装
有两种途径:
**1. Ghidra GUI** — `File → Install Extensions → +` → 选择该 zip 文件 → 重启 Ghidra。
**2. 文件系统刷新** — 直接解压到 Ghidra 的用户扩展目录,然后重启 Ghidra:
| OS | Path |
|---|---|
| macOS | `~/Library/ghidra/ghidra__PUBLIC/Extensions/` |
| Linux | `$XDG_CONFIG_HOME/ghidra/ghidra__PUBLIC/Extensions/`(默认为 `~/.config/...`) |
| Windows | `%APPDATA%\ghidra\ghidra__PUBLIC\Extensions\` |
在迭代开发过程中,通过文件系统路径安装可以跳过 GUI 的繁琐操作。
安装后:启动 Ghidra → `File → Configure → Developer → 勾选 "Ghidra MCP Plugin"`。
## 运行
插件启用后,会在 `127.0.0.1:8765` 上自动启动 MCP 服务器。可以在 Ghidra 的控制台中确认:
```
muninn-ghidra listening on 127.0.0.1:8765 (sse=/sse, streamable=/mcp); 14 tool(s)
```
同时公开了两种 MCP 传输方式:
| Transport | Endpoint | Use when |
|---|---|---|
| Streamable-HTTP | `http://127.0.0.1:8765/mcp` | 当前的 MCP 客户端(Claude Code 等) |
| SSE | `http://127.0.0.1:8765/sse` + `/message` | 传统的、期望使用 SSE 的客户端 |
服务器仅绑定到 `127.0.0.1`。它**不是**一个网络服务;如果要从其他机器访问,需要由你自己建立反向代理或隧道,并在完成威胁建模后再进行操作。
## 连接(MCP 客户端)
Claude Code 客户端配置示例:
```
{
"mcpServers": {
"ghidra": {
"type": "http",
"url": "http://127.0.0.1:8765/mcp"
}
}
}
```
请根据你所用客户端的配置格式进行调整。可以通过 `tools/list` 命令确认连接——该命令应返回下方列出的 5 个工具名称。
## 工具
目前共有十四个工具。每个工具在 `LOOM.md §4` 中都有完整的行为规范(包含输入、输出、错误模式、威胁说明和验收测试)。
**读取 — 导航与检查**
| Name | Purpose |
|---|---|
| `get_program_info` | 高级元数据:名称、格式、语言 ID、镜像基址、入口点、地址空间、内存大小、函数/符号计数。对于异常加载的二进制文件提供缺失哨兵值。 |
| `list_segments` | 内存映射:每个块的地址范围、读/写/执行权限、初始化状态、来源类型。这是与格式无关的节视图。 |
| `list_functions` | 当前程序中的函数。支持子字符串过滤、最大结果数上限、thunk/外部函数开关。按入口地址确定性排序。 |
| `list_symbols` | 所有符号类型(函数 / 标签 / 全局变量 / 参数 / 局部变量 / 命名空间 / 类)。支持子字符串 + 类型 + 命名空间过滤器;提供排除默认名称的开关。 |
| `list_strings` | 已定义的字符串及其编码(ASCII / UTF-8 / UTF-16 / UTF-32)、长度、地址、文本。支持 min_length 和 address_range 过滤器。是最快的二进制导航信号。 |
| `list_imports` | 该程序调用的外部符号——库、名称、thunk 地址。 |
| `list_exports` | 该程序公开的外部入口点(PE / ELF / Mach-O)。 |
| `get_function_info` | 函数级细节:签名、带存储信息的参数、交叉引用计数、分析标志。可通过 Ghidra 的 `DecompInterface` 进行可选的有界超时反编译。 |
| `get_xrefs` | 统一的交叉引用遍历——入站、出站或两者兼有。提供 9 桶简化版引用类型过滤器。 |
| `disassemble_range` | 对地址范围或整个函数进行指令级反汇编。通过 Ghidra 的 SLEIGH 实现跨架构可移植。 |
| `search_bytes` | 十六进制模式搜索,支持 `??` 通配符、地址范围限定、上下文字节。 |
**审计 — 确定性的漏洞与安全加固信号**
| Name | Purpose |
|---|---|
| `audit` | 四种操作。`dangerous_calls` 标记 strcpy/gets/system/exec* 等的调用点,支持调用者自定义列表。`format_strings` 标记带有非常量格式参数的 printf 系列调用。`hardening` 报告跨 PE/ELF/Mach-O 的堆栈金丝雀 / NX / ASLR / RELRO / CFG / CET 状态。`anti_analysis` 查找调试/虚拟机/计时检查(IsDebuggerPresent / ptrace / RDTSC / cpuid)。仅呈现信号,而非定论。 |
**修改 — 注释**
| Name | Purpose |
|---|---|
| `rename_symbol` | 通过地址或名称重命名 函数 / 标签 / 全局变量 / 参数 / 局部变量 / 命名空间。区分工具级别的失败(`isError=true`)和调用者可恢复的语义拒绝(`renamed=false`,例如名称冲突)。 |
| `set_comment` | 在某个地址附加 / 替换 / 清除注释。支持 Ghidra 全部五种注释类型(pre / post / eol / plate / repeatable)。无操作的清除动作不会污染撤销栈。 |
修改操作在 Ghidra 的事件分发线程上的命名事务中执行;每一项都会在 Ghidra 的撤销栈中显示为一个单独、可读的条目。
不可信二进制文件的安全性:工具仅从 Ghidra 的符号表和列表中读取已解析的程序状态——在宿主进程中不会解释或执行任何二进制内容。
## 方法论
该项目使用两个核心约束文件:
- **`CLAUDE.md`** — 协同工作的项目规范(构建 / 运行、威胁背景、推送纪律)
- **`LOOM.md`** — 项目状态机制(`§1` 元数据,`§4` 规范,`§6` 规则,`§8` 当前阶段)
`LOOM.md §6` 中的几条关键规则:
- **R-013** — `git push` 属于破坏性操作。每次推送到每个远程仓库,都必须经过预推送清洗(检查路径、主机名、环境变量导出、带有密钥特征的令牌、测试二进制文件)。
- **R-014** — 许可证归属需随每个分发边界传递。在构建机器之外共享构建好的 zip 文件,会触发对打包的 jars 履行第三方 Apache 2.0 §4 规定的义务。
- **R-015** — 推送后审计检查的是访问者实际看到的内容(默认分支、继承的引用、根 URL 下的许可证),而不仅仅是推送了什么内容。
- **R-016** — 重写阶段需遵循净室规范:工具实现仅读取库内的行为规范和公开的 Ghidra / MCP API 文档。不查阅任何先前的实现。
- **R-017** — 规范优先:如果没有通过“每个 WHEN 都暗含一个 NOT-WHEN”以及退化用例检查的 `§4` 规范条目,就不能开始实现。
- **R-019** — 输入验证先于环境检查。调用者可以在不更改环境的情况下修复无效参数;错误信息应反映出这一点。
## 项目结构
```
src/main/java/io/sloptropy/ghidra/mcp/
├── GhidraMcpPlugin.java Ghidra ProgramPlugin entry point
├── api/
│ ├── McpTool.java tool contract
│ ├── ToolHelpers.java text/error wrappers, address parse/format
│ ├── JsonRender.java minimal JSON writer for tool responses
│ └── Mutation.java EDT bridge + transaction discipline
├── server/
│ ├── ProgramSource.java decouples tools from plugin state
│ ├── ToolRegistry.java ordered, freeze-at-boot registry
│ └── McpServerBootstrap.java Jetty 12 + MCP SDK transports
└── tools/
├── ListFunctionsTool.java
├── GetProgramInfoTool.java
├── GetFunctionInfoTool.java
├── RenameSymbolTool.java
└── SetCommentTool.java
```
`smoke/` 包含一个外部测试套件,用于在不对 `ProgramSource` 启动 Ghidra 的情况下启动服务器进行协议级冒烟测试。该部分不包含在扩展的 zip 包中。
## 配置
目前采用硬编码:
- 绑定地址:`127.0.0.1`
- 绑定端口:`8765`
- 传输方式:同时启用 SSE 和 streamable-HTTP
配置 UI 将在未来的迭代中推出。目前若要覆盖端口设置,请编辑 `GhidraMcpPlugin.DEFAULT_PORT` 并重新构建。
## 许可证
MIT — 请参阅 [`LICENSE`](LICENSE)。可自由使用,在副本中保留版权和许可证文本,并且本软件不提供任何担保。
## 状态
| Phase | Focus | State |
|---|---|---|
| 0 | 规范制定 + 构建测试环境 | 已完成 |
| 1 | 服务器引导程序 + 首个工具实现 | 已完成 |
| 2 | 剩余的 4 个工具实现 + 共享修改/json 基础设施 | 已完成 |
| 3 | (待定)附加工具、运行时优化、配置 UI | 开放中 |
这是一个单一作者的个人研究项目。暂无贡献指南;issues 和 PRs 可能会处于无人回复的状态。
标签:AI工具集成, Ghidra插件, JS文件枚举, 二进制分析, 云安全运维, 云资产清单, 后台面板检测, 固件分析, 域名枚举, 模型上下文协议(MCP), 逆向工程