symgraph/GhidrAssistMCP
GitHub: symgraph/GhidrAssistMCP
一款为 Ghidra 构建 MCP 服务器的扩展插件,让 AI 助手能通过标准化接口直接调用 Ghidra 的逆向分析能力。
Stars: 526 | Forks: 38
# GhidrAssistMCP
一个强大的 Ghidra 扩展,它提供了一个 MCP (Model Context Protocol) 服务器,使 AI 助手和其他工具能够通过标准化的 API 与 Ghidra 的逆向工程功能进行交互。
## 概述
GhidrAssistMCP 弥合了 AI 驱动的分析工具与 Ghidra 全面的逆向工程平台之间的差距。通过实现 Model Context Protocol,此扩展允许外部 AI 助手、自动化分析工具和自定义脚本与 Ghidra 的分析能力无缝交互。
### 主要功能
- **MCP Server 集成**:使用官方 SDK 实现的完整 Model Context Protocol 服务器
- **双重 HTTP 传输**:支持 SSE 和 Streamable HTTP 传输,以最大限度地提高客户端兼容性
- **35 个内置工具**:包含全面的分析工具集,采用基于操作的整合方式以提供更简洁的 API
- **6 个 MCP 资源**:用于程序信息、函数、字符串、导入、导出和段的静态数据资源
- **7 个 MCP 提示词**:用于常见逆向工程任务的预构建分析提示词
- **结果缓存**:智能缓存系统,用于提高重复查询的性能
- **异步任务支持**:长时间运行的操作通过任务管理异步执行
- **多程序支持**:使用 `program_name` 参数同时处理多个打开的程序
- **多窗口支持**:单个 MCP 服务器在所有 CodeBrowser 窗口间共享,具有智能焦点跟踪功能
- **活动上下文感知**:自动检测哪个二进制窗口处于焦点状态,并在所有工具响应中提供上下文提示
- **可配置 UI**:易于使用的界面,用于管理工具和监控活动
- **实时日志记录**:通过详细日志记录跟踪所有 MCP 请求和响应
- **动态工具管理**:单独启用/禁用工具,设置可持久保存
## 客户端
无耻的自推:[GhidrAssist](https://github.com/jtang613/GhidrAssist) 开箱即支持 GhidrAssistMCP。
## 截图


## 安装
### 前置条件
- **Ghidra 11.4+**(已在 Ghidra 12.0 Public 版本上测试)
- **一个 MCP 客户端(如 GhidrAssist)**
### 二进制发布版(推荐)
1. **下载最新版本**:
- 前往 [Releases 页面](https://github.com/jtang613/GhidrAssistMCP/releases)
- 下载最新的 `.zip` 文件(例如 `GhidrAssistMCP-v1.0.0.zip`)
2. **安装扩展**:
- 在 Ghidra 中:**File → Install Extensions → Add Extension**
- 选择下载的 ZIP 文件
- 出现提示时重启 Ghidra
3. **启用插件**:
- **File → Configure → Configure Plugins**
- 搜索 "GhidrAssistMCP"
- 勾选复选框以启用插件
### 从源码构建
1. **克隆仓库**:
git clone
cd GhidrAssistMCP
2. **将 Gradle 指向你的 Ghidra 安装路径**:
- 设置 `GHIDRA_INSTALL_DIR`(环境变量),或者在运行 Gradle 时传递 `-PGHIDRA_INSTALL_DIR=`。
3. **构建 + 安装**:
确保 Ghidra 未运行,然后执行:
gradle installExtension
这会将构建的 ZIP 复制到你的 Ghidra 安装目录(`[GHIDRA_INSTALL_DIR]/Extensions/Ghidra`)并解压到你的 Ghidra **用户** Extensions 文件夹(替换任何现有的解压副本)。
如果需要覆盖该位置,请传递 `-PGHIDRA_USER_EXTENSIONS_DIR=`。
4. **重启 / 验证**:
- 重启 Ghidra。
- 如果插件未出现,请通过 **File → Configure → Configure Plugins** 启用它(搜索 "GhidrAssistMCP")。
## 配置
### 初始设置
1. **打开控制面板**:
- Window → GhidrAssistMCP(或使用工具栏图标)
2. **配置服务器设置**:
- **Host**:默认为 `localhost`
- **Port**:默认为 `8080`
- **Enable/Disable**:开启/关闭 MCP 服务器
### 工具管理
Configuration(配置)选项卡允许你:
- **查看所有可用工具**(共 35 个)
- **使用复选框启用/禁用单个工具**
- **保存配置**以便在会话间持久化
- **实时监控工具状态**
## 可用工具
GhidrAssistMCP 提供了按类别组织的 35 个工具。一些工具采用基于操作的 API 模式,其中单个工具提供多个相关操作。
### 二进制与程序管理
| 工具 | 描述 |
| ---- | ----------- |
| `get_binary_info` | 获取基本程序信息(名称、架构、编译器等) |
| `list_binaries` | 列出所有 CodeBrowser 窗口中打开的所有程序 |
### 函数发现与分析
| 工具 | 描述 |
| ---- | ----------- |
| `get_functions` | 列出函数,支持可选的模式过滤和分页 |
| `search_functions_by_name` | 按名称模式查找函数 |
| `get_function_statistics` | 所有函数的综合统计信息 |
| `analyze_function` | 获取详细的函数信息(签名、变量等) |
| `get_current_function` | 获取当前光标位置的函数 |
| `get_function_stack_layout` | 获取带有变量偏移量的栈帧布局 |
| `get_basic_blocks` | 获取函数的基本块信息 |
### 二进制信息
| 工具 | 描述 |
| ---- | ----------- |
| `get_imports` | 列出导入的函数/符号 |
| `get_exports` | 列出导出的函数/符号 |
| `get_strings` | 列出字符串引用,支持可选过滤 |
| `search_strings` | 按模式搜索字符串 |
| `get_segments` | 列出内存段 |
| `get_namespaces` | 列出程序中的命名空间 |
| `get_relocations` | 列出重定位条目 |
| `get_entry_points` | 列出所有二进制入口点 |
### 数据分析
| 工具 | 描述 |
| ---- | ----------- |
| `get_data_vars` | 列出程序中的数据定义 |
| `get_data_at` | 获取特定地址的十六进制转储/数据 |
| `create_data_var` | 在地址处定义数据变量 |
| `get_current_address` | 获取当前光标地址 |
### 整合工具
这些工具将相关操作打包在一个鉴别器参数(例如 `action`、`target`、`target_type` 或 `format`)之后。
#### `get_code` - 代码检索工具
| 参数 | 值 | 描述 |
| --------- | ------ | ----------- |
| `format` | `decompiler`, `disassembly`, `pcode` | 输出格式 |
| `raw` | boolean | 仅影响 `format: "pcode"`(原始 pcode 操作码与按基本块分组) |
#### `classes` - 类操作工具
| 操作 | 描述 |
| ------ | ----------- |
| `list` | 列出类,支持可选的模式过滤和分页 |
| `get_info` | 获取详细的类信息(方法、字段、vtable、虚函数) |
#### `xrefs` - 交叉引用工具
| 参数 | 描述 |
| --------- | ----------- |
| `address` | 查找指向/来自特定地址的所有引用 |
| `function` | 查找函数的所有交叉引用 |
| `include_calls` | 包含调用者/被调用者(取代了单独的调用图工具) |
#### `struct` - 结构操作工具
| 操作 | 描述 |
| ------ | ----------- |
| `create` | 从 C 定义或空创建新结构 |
| `modify` | 使用新的 C 定义修改现有结构 |
| `merge` | 将 C 定义中的字段合并(覆盖)到现有结构上,而不删除现有字段 |
| `set_field` | 在特定偏移量处设置/插入单个字段,无需完整的 C 结构体(使用 `field_name` 命名) |
| `name_gap` | 将偏移量/长度处的未定义字节转换为命名的类似 `byte[]` 的字段(用于“命名间隙”;使用 `field_name`) |
| `auto_create` | 根据变量使用模式自动创建结构 |
| `rename_field` | 重命名结构中的字段 |
| `field_xrefs` | 查找特定结构体字段的交叉引用 |
#### `rename_symbol` - 符号重命名工具
| 参数 | 值 | 描述 |
| --------- | ------ | ----------- |
| `target_type` | `function`, `data`, `variable` | 要重命名的符号类型 |
#### `batch_rename` - 批量符号重命名工具
在一次操作中重命名多个符号。
#### `comments` - 注释管理工具
| 操作 | 描述 |
| ------ | ----------- |
| `get` | 获取地址处的注释 |
| `set` | 在地址处或函数上设置注释 |
| `list` | 列出所有注释 |
| `remove` | 删除注释 |
#### `variables` - 变量管理工具
| 操作 | 描述 |
| ------ | ----------- |
| `list` | 列出函数的局部变量 |
| `rename` | 重命名局部变量 |
| `set_type` | 设置局部变量的数据类型 |
| `set_prototype` | 设置函数签名/原型 |
#### `types` - 类型管理工具
| 操作 | 描述 |
| ------ | ----------- |
| `list` | 列出所有可用的数据类型 |
| `get_info` | 获取详细的数据类型信息和结构定义 |
| `set` | 在特定地址设置数据类型 |
| `delete` | 按名称删除数据类型(可选择通过 `category` 限定范围) |
#### `bookmarks` - 书签管理工具
| 操作 | 描述 |
| ------ | ----------- |
| `list` | 列出所有书签 |
| `set` | 设置新书签 |
| `remove` | 删除书签 |
### 搜索工具
| 工具 | 描述 |
| ----- | ----------- |
| `search_bytes` | 在内存中搜索字节模式 |
### 异步任务管理
长时间运行的操作(反编译、结构分析、字段交叉引用)异步执行:
| 工具 | 描述 |
| ---- | ----------- |
| `get_task_status` | 检查异步任务的状态并检索结果 |
| `cancel_task` | 取消正在运行的异步任务 |
| `list_tasks` | 列出所有待处理/运行中/已完成的任务 |
## MCP 资源
GhidrAssistMCP 暴露了 6 个可供 MCP 客户端读取的静态资源:
| 资源 URI | 描述 |
| ------------ | ----------- |
| `ghidra://program/{name}/info` | 基本程序信息 |
| `ghidra://program/{name}/functions` | 所有函数的列表 |
| `ghidra://program/{name}/strings` | 字符串引用 |
| `ghidra://program/{name}/imports` | 导入符号 |
| `ghidra://program/{name}/exports` | 导出符号 |
| `ghidra://program/{name}/segments` | 内存段 |
## MCP 提示词
用于常见分析任务的预构建提示词:
| 提示词 | 描述 |
| ------ | ----------- |
| `analyze_function` | 综合函数分析提示词 |
| `identify_vulnerability` | 安全漏洞识别 |
| `document_function` | 生成函数文档 |
| `trace_data_flow` | 数据流分析提示词 |
| `trace_network_data` | 跟踪网络发送/接收调用栈,用于协议分析和网络漏洞识别 |
| `compare_functions` | 对比两个函数进行相似性分析 |
| `reverse_engineer_struct` | 从使用模式恢复结构定义 |
## 使用示例
### 基本程序信息
```
{
"method": "tools/call",
"params": {
"name": "get_binary_info"
}
}
```
### 列出带有模式过滤的函数
```
{
"method": "tools/call",
"params": {
"name": "get_functions",
"arguments": {
"pattern": "init",
"case_sensitive": false,
"limit": 50
}
}
}
```
### 反编译函数 (`get_code`)
```
{
"method": "tools/call",
"params": {
"name": "get_code",
"arguments": {
"function": "main",
"format": "decompiler"
}
}
}
```
### 获取类信息(基于操作)
```
{
"method": "tools/call",
"params": {
"name": "classes",
"arguments": {
"action": "get_info",
"class_name": "MyClass"
}
}
}
```
### 搜索类(基于操作)
```
{
"method": "tools/call",
"params": {
"name": "classes",
"arguments": {
"action": "list",
"pattern": "Socket",
"case_sensitive": false
}
}
}
```
### 自动创建结构(基于操作)
```
{
"method": "tools/call",
"params": {
"name": "struct",
"arguments": {
"action": "auto_create",
"function_identifier": "0x00401000",
"variable_name": "ctx"
}
}
}
```
### 查找结构体字段交叉引用(基于操作)
```
{
"method": "tools/call",
"params": {
"name": "struct",
"arguments": {
"action": "field_xrefs",
"structure_name": "Host",
"field_name": "port"
}
}
}
```
### 删除数据类型
如果多个类型在不同类别中共享相同的名称,请传递 `category`(或在 `name` 中传递以 `/` 开头的完整路径)。
```
{
"method": "tools/call",
"params": {
"name": "types",
"arguments": {
"action": "delete",
"name": "MyStruct",
"category": "/mytypes"
}
}
}
```
### 重命名函数(基于操作)
```
{
"method": "tools/call",
"params": {
"name": "rename_symbol",
"arguments": {
"action": "function",
"address": "0x00401000",
"new_name": "decrypt_buffer"
}
}
}
```
### 多程序支持
处理多个打开的程序时,首先列出它们:
```
{
"method": "tools/call",
"params": {
"name": "list_binaries"
}
}
```
然后使用 `program_name` 指定目标程序:
```
{
"method": "tools/call",
"params": {
"name": "get_functions",
"arguments": {
"program_name": "target_binary.exe",
"limit": 10
}
}
}
```
## 多窗口支持与活动上下文感知
GhidrAssistMCP 采用单例架构支持跨多个 CodeBrowser 窗口的无缝操作:
### 工作原理
1. **单一共享服务器**:一个 MCP 服务器(端口 8080)为所有 CodeBrowser 窗口服务
2. **焦点跟踪**:自动检测当前哪个 CodeBrowser 窗口处于活动状态
3. **上下文提示**:所有工具响应都包含上下文信息,帮助 AI 了解当前焦点所在的二进制文件
### 响应中的上下文信息
每个工具响应都包含一个上下文头:
```
[Context] Operating on: malware.exe | Active window: malware.exe
```
或者当目标是不同的程序时:
```
[Context] Operating on: lib.so | Active window: main.exe | Total open programs: 3
```
### 对 AI 助手的好处
- **智能默认值**:当未指定 `program_name` 时,工具会自动使用活动窗口中的程序
- **上下文感知**:AI 知道用户当前正在查看哪个二进制文件
- **防止混淆**:在操作的二进制文件与活动窗口中的不同时给出清晰指示
- **多任务处理**:无需不断指定目标即可处理多个二进制文件
## 架构
### 核心组件
```
GhidrAssistMCP/
├── GhidrAssistMCPManager # Singleton coordinator for multi-window support
│ ├── Tracks all CodeBrowser windows
│ ├── Manages focus tracking
│ └── Owns shared server and backend
├── GhidrAssistMCPPlugin # Plugin instance (one per CodeBrowser window)
│ └── Registers with singleton manager
├── GhidrAssistMCPServer # HTTP MCP server (SSE + Streamable)
│ └── Single shared instance on port 8080
├── GhidrAssistMCPBackend # Tool management and execution
│ ├── Tool registry with enable/disable states
│ ├── Result caching system
│ ├── Async task management
│ └── Resource and prompt registries
├── GhidrAssistMCPProvider # UI component provider
│ └── First registered instance provides UI
├── cache/ # Caching infrastructure
│ ├── McpCache.java
│ └── CacheEntry.java
├── tasks/ # Async task management
│ ├── McpTaskManager.java
│ └── McpTask.java
├── resources/ # MCP Resources (6 total)
│ ├── ProgramInfoResource.java
│ ├── FunctionListResource.java
│ ├── StringsResource.java
│ ├── ImportsResource.java
│ ├── ExportsResource.java
│ └── SegmentsResource.java
├── prompts/ # MCP Prompts (7 total)
│ ├── AnalyzeFunctionPrompt.java
│ ├── IdentifyVulnerabilityPrompt.java
│ ├── DocumentFunctionPrompt.java
│ ├── TraceDataFlowPrompt.java
│ ├── TraceNetworkDataPrompt.java
│ ├── CompareFunctionsPrompt.java
│ └── ReverseEngineerStructPrompt.java
└── tools/ # MCP Tools (35 total)
├── Consolidated action-based tools
├── Analysis tools
├── Modification tools
└── Navigation tools
```
### 工具设计模式
**整合工具**:相关操作被整合到带有鉴别器参数的单个工具中:
- `get_code`: `format: decompiler|disassembly|pcode`
- `classes`: `action: list|get_info`
- `struct`: `action: create|modify|merge|set_field|name_gap|auto_create|rename_field|field_xrefs`
- `rename_symbol`: `target_type: function|data|variable`
- `comments`: `action: get|set|list|remove`
- `variables`: `action: list|rename|set_type|set_prototype`
- `types`: `action: list|get_info|set|delete`
- `bookmarks`: `action: list|set|remove`
- `xrefs`: `address|function` 及 `include_calls` 参数
**工具接口方法**:
- `isReadOnly()`: 指示工具是否修改程序状态
- `isLongRunning()`: 触发带有任务管理的异步执行
- `isCacheable()`: 为重复查询启用结果缓存
- `isDestructive()`: 标记潜在危险的操作
- `isIdempotent()`: 指示重复调用是否产生相同结果
### MCP 协议实现
- **传输方式**:
- HTTP with Server-Sent Events (SSE)
- Streamable HTTP
- **端点**:
- `GET /sse` - 用于双向通信的 SSE 连接
- `POST /message` - 消息交换端点
- `GET /mcp` - 接收 Streamable HTTP 事件
- `POST /mcp` - 初始化 Streamable HTTP 会话
- `DELETE /mcp` - 终止 Streamable HTTP 会话
- **能力**: Tools, Resources, Prompts
## 开发
### 项目结构
```
src/main/java/ghidrassistmcp/
├── GhidrAssistMCPPlugin.java # Main plugin class
├── GhidrAssistMCPManager.java # Singleton coordinator
├── GhidrAssistMCPProvider.java # UI provider with tabs
├── GhidrAssistMCPServer.java # MCP server implementation
├── GhidrAssistMCPBackend.java # Backend tool/resource/prompt management
├── McpBackend.java # Backend interface
├── McpTool.java # Tool interface
├── McpEventListener.java # Event notification interface
├── cache/ # Caching system
├── tasks/ # Async task system
├── resources/ # MCP resources
├── prompts/ # MCP prompts
└── tools/ # Tool implementations (35 files)
```
### 添加新工具
1. **实现 McpTool 接口**:
public class MyCustomTool implements McpTool {
@Override
public String getName() { return "my_custom_tool"; }
@Override
public String getDescription() { return "Description"; }
@Override
public boolean isReadOnly() { return true; }
@Override
public boolean isLongRunning() { return false; }
@Override
public boolean isCacheable() { return true; }
@Override
public McpSchema.JsonSchema getInputSchema() { /* ... */ }
@Override
public McpSchema.CallToolResult execute(Map arguments, Program program) {
// Implementation
}
}
2. **在 backend 中注册**:
// In GhidrAssistMCPBackend constructor
registerTool(new MyCustomTool());
### 构建命令
```
# Clean 构建
gradle clean
# Build extension zip (写入 dist/)
gradle buildExtension
# Install (解压) extension 到 Ghidra 用户 Extensions 目录
gradle installExtension
# Uninstall (删除 Ghidra 用户 Extensions 目录中解压的目录)
gradle uninstallExtension
# Build/install 使用特定 Ghidra 路径 (如果未设置 GHIDRA_INSTALL_DIR 则需要)
gradle -PGHIDRA_INSTALL_DIR=/path/to/ghidra installExtension
# Debug 构建
gradle buildExtension --debug
```
### 依赖项
- **MCP SDK**: `io.modelcontextprotocol.sdk:mcp:0.17.1`
- **Jetty Server**: `11.0.20` (HTTP/SSE transport)
- **Jackson**: `2.18.3` (JSON processing)
- **Ghidra API**: Bundled with Ghidra installation
## 日志记录
### UI 日志记录
**Log** 选项卡提供实时监控:
- **会话事件**:服务器启动/停止,程序更改
- **工具请求**:`REQ: tool_name {parameters...}`
- **工具响应**:`RES: tool_name {response...}`
- **错误消息**:失败的操作和诊断信息
- **缓存命中**:返回缓存结果时
### 控制台日志记录
Ghidra 控制台中的详细日志记录:
- 工具注册和初始化
- MCP 服务器生命周期事件
- 异步任务执行和完成
- 缓存统计信息
- 数据库事务操作
- 错误堆栈跟踪和调试信息
## 故障排除
### 常见问题
#### 服务器无法启动
- 检查端口 8080 是否可用
- 验证 Ghidra 安装路径
- 检查控制台日志中的错误
#### 工具未出现
- 确保插件已启用
- 检查 Configuration 选项卡中的工具状态
- 验证日志中的 backend 初始化
#### MCP 客户端连接问题
- 确认服务器正在运行(检查 GhidrAssistMCP 窗口)
- 测试连接:`curl http://localhost:8080/sse`
- 检查防火墙设置
#### 工具执行失败
- 验证程序是否已在 Ghidra 中加载
- 检查工具参数是否正确
- 查看 Log 选项卡中的错误消息
#### 异步任务问题
- 使用 `get_task_status` 检查任务状态
- 使用 `list_tasks` 查看所有任务
- 如果任务卡住,使用 `cancel_task`
### 调试模式
通过添加到 Ghidra 启动参数来启用调试日志记录:
```
-Dlog4j.logger.ghidrassistmcp=DEBUG
```
## 贡献
1. **Fork 本仓库**
2. **创建功能分支**:`git checkout -b feature-name`
3. **进行更改**并编写适当的测试
4. **遵循代码风格**:使用现有的模式和约定
5. **提交 Pull Request**并附带详细描述
### 代码标准
- 在适当的地方使用 **Java 21+ 特性**
- **适当的异常处理**并附带有意义的消息
- 所有数据库操作的**事务安全**
- UI 操作的**线程安全**
- 公共 API 的**全面文档**
- 相关工具操作的**基于操作的整合**
## 许可证
本项目根据 MIT 许可证授权 - 详见 [LICENSE](LICENSE) 文件。
## 致谢
- **NSA/Ghidra 团队**,感谢他们出色的逆向工程平台
- **Anthropic**,感谢 Model Context Protocol 规范
**有问题或疑虑?**
请在项目仓库中提交 issue,用于错误报告、功能请求或有关使用和开发的问题。
标签:API 接口, CodeBrowser, Ghidra, JS文件枚举, LLM 集成, MCP, SSE, 二进制分析, 云安全监控, 云安全运维, 云资产清单, 人工智能辅助分析, 恶意代码分析, 插件, 服务器, 模型上下文协议, 网络调试, 自动化, 自动化分析, 跨站脚本, 逆向工程, 配置文件, 静态分析