使用说明
Ghidra的MCP链路
AI-带100%Ghidra API访问的反向工程
Ghidra扩展连接到Aura Friday MCP Link服务器,使Ghidra成为人工智能代理可以通过Java反射完全控制的远程工具。与操作有限的硬编码MCP工具不同,这为AI提供了 无限访问 每个Ghidra API。
🚀 是什么让这与众不同
传统MCP工具(有限)
AI → get_functions() → hardcoded list
AI → decompile_function(name) → hardcoded call
... maybe 10-40 hardcoded endpoints ...
Ghidra的MCP链接(无限制)
AI → eval("currentProgram.getFunctionManager().getFunctions(true)") → Full API
AI → eval("new DecompInterface().decompileFunction(func, 60, null)") → Any operation
AI → eval("memory.getByte(addr)") → Read raw bytes
AI → list_methods("currentProgram") → Discover 150+ methods
... 100% of Ghidra's Java API via reflection ...
AI可以调用任何方法,访问任何字段,实例化任何类。 没有限制,没有等待我们添加功能。
✨ 特性
🔬 完全Java反射执行
- 执行 任何表达 通过
eval操作 - 方法链:
obj.method1().method2().field - 对象实例化:
new ghidra.app.decompiler.DecompInterface() - 静态方法调用:
@ghidra.util.Msg.info(plugin, "Hello!") - 数组/列表访问:
list[0],map[key]
🔍 API反思
list_methods-发现任何对象上的所有方法list_fields-发现任何对象上的所有字段describe-获取具有类型层次结构的完整对象描述
📜 多行脚本执行
- 在调用过程中持续存在的变量分配
- 用于状态分析的会话管理
- 打印报表以捕获输出
🔗 MCP工具集成
- 调用其他MCP工具(SQLite、浏览器、用户弹出窗口、AI模型)
- 将分析结果存储在数据库中
- 显示交互式HTML弹出窗口
- 自动化跨工具工作流程
🎯 AI能做什么
二进制分析
// Get all functions
functionManager.getFunctions(true)
// Find functions by name pattern
symbolTable.getGlobalSymbols("crypt")
// Read memory bytes
memory.getByte(addr)
memory.getInt(addr)
反编译
// Create decompiler and get C code
decomp = new ghidra.app.decompiler.DecompInterface()
decomp.openProgram(currentProgram)
result = decomp.decompileFunction(func, 60, null)
print(result.getDecompiledFunction().getC())
符号分析
// Find all symbols
symbolTable.getAllSymbols(true)
// Get imports/exports
symbolTable.getExternalSymbols()
// Find cross-references
referenceManager.getReferencesTo(addr)
数据类型
// Access data type manager
dtm = currentProgram.getDataTypeManager()
// Find structures
dtm.getDataType("/MyStruct")
// Create new types
dtm.addDataType(newStruct, null)
📦 安装
先决条件
-
吉德拉12.0+ -下载自https://ghidra-sre.org/
-
MCP链路服务器 -下载自https://github.com/AuraFriday/mcp-link-server/releases
-
Java 21+ -建筑所需
构建和安装
# Clone the repository
git clone https://github.com/AuraFriday/ghidra_mcp.git
cd ghidra_mcp
# Set Ghidra installation path
# Windows PowerShell:
$env:GHIDRA_INSTALL_DIR = "C:\path\to\ghidra_12.0_PUBLIC"
# Linux/Mac:
export GHIDRA_INSTALL_DIR="/path/to/ghidra_12.0_PUBLIC"
# Build the extension
make build
# Or manually:
cd mcp_link_ghidra && ./gradlew buildExtension
# The extension ZIP is created in mcp_link_ghidra/dist/
安装扩展
- 打开Ghidra
- 首选 File → 安装扩展
- 点击 + 按钮
- 从以下位置选择ZIP文件
mcp_link_ghidra/dist/ - 重新启动Ghidra
- 在CodeBrowser中打开二进制文件-插件会自动连接!
🎬 快速入门示例
示例1:获取程序信息
{
"operation": "eval",
"expression": "currentProgram.getName()"
}
结果: "hello.exe"
示例2:计数函数
{
"operation": "eval",
"expression": "functionManager.getFunctionCount()"
}
结果: 42
示例3:分解条目函数
{
"operation": "script",
"script": "syms = symbolTable.getGlobalSymbols(\"entry\")\naddr = syms[0].getAddress()\nfunc = listing.getFunctionAt(addr)\ndecomp = new ghidra.app.decompiler.DecompInterface()\ndecomp.openProgram(currentProgram)\nresult = decomp.decompileFunction(func, 60, null)\nprint(result.getDecompiledFunction().getC())",
"session_id": "default"
}
结果:
void entry(void)
{
longlong lVar1;
undefined4 auStackX_8 [8];
auStackX_8[0] = 0;
lVar1 = GetStdHandle(0xfffffff5);
if (lVar1 != -1) {
WriteFile(lVar1,&DAT_140002020,0xf,auStackX_8,0);
}
ExitProcess(0);
...
}
示例4:发现可用方法
{
"operation": "list_methods",
"target": "currentProgram"
}
结果: 150多种方法,包括 getName(), getFunctionManager(), getMemory(), getSymbolTable()等等。
示例5:读取内存字节数
{
"operation": "script",
"script": "addr = currentAddress\nb0 = memory.getByte(addr)\nb1 = memory.getByte(addr.add(1))\nb2 = memory.getByte(addr.add(2))\nprint(b0)\nprint(b1)\nprint(b2)",
"session_id": "hex"
}
🔧 可用操作
| 操作 | 说明 | 示例 |
|---|---|---|
eval / execute_java |
执行单个表达式 | {"operation": "eval", "expression": "currentProgram.getName()"} |
script / execute_script |
带作业的多行脚本 | {"operation": "script", "script": "x = 1\ny = x + 1\nprint(y)"} |
list_methods |
列出对象上的所有方法 | {"operation": "list_methods", "target": "functionManager"} |
list_fields |
列出对象上的所有字段 | {"operation": "list_fields", "target": "currentProgram"} |
describe |
完整对象描述 | {"operation": "describe", "target": "memory"} |
call_tool |
调用其他MCP工具 | {"operation": "call_tool", "tool_name": "sqlite", ...} |
📋 内置变量
这些在每个表达式/脚本中都是自动可用的:
| 变量 | 类型 | 描述 |
|---|---|---|
currentProgram |
程序 | 当前打开的程序 |
currentAddress |
地址 | 当前光标位置 |
tool |
PluginTool | Ghidra工具实例 |
plugin |
MCPLinkGhidraPlugin | 此插件实例 |
flatApi |
FlatProgramAPI | 用于常见操作的简化API |
functionManager |
函数管理器 | 函数访问 |
symbolTable |
SymbolTable | 访问符号和标签 |
memory |
内存 | 原始内存访问 |
listing |
列表 | 说明和数据 |
addressFactory |
AddressFactory | 创建地址对象 |
🛠️ 表达式语法
方法涟
currentProgram.getFunctionManager().getFunctionCount()
symbolTable.getGlobalSymbols("main")[0].getAddress()
对象实例化
new ghidra.app.decompiler.DecompInterface()
new ghidra.program.model.address.GenericAddress(...)
静态方法调用(@前缀)
@ghidra.util.Msg.info(plugin, "Hello from AI!")
@java.lang.System.currentTimeMillis()
类引用($前缀)
$ghidra.app.decompiler.DecompInterface
$java.util.ArrayList
字面量
"string" // String
123 // Integer
45.67 // Double
0x1400 // Hex number
true / false // Boolean
null // Null
数组/列表访问
list[0] // First element
map["key"] // Map lookup
iterator[5] // 6th element (converts to list)
🏗️ 建筑
┌─────────────────┐ ┌─────────────────────────┐
│ AI Agent │ │ MCP-Link Server │
│ (Cursor/Claude) │◄───────►│ (Running on user's PC) │
└─────────────────┘ MCP └─────────────────────────┘
│
▼
┌──────────────────┐
│ Ghidra Extension │
│ (Remote Tool) │
└──────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Reflection │ │ Introspection│ │ MCP Bridge │
│ Executor │ │ (list_*) │ │ (call_tool) │
└──────────────┘ └──────────────┘ └──────────────┘
组件
- MCPLinkGhidraPlugin.java -主插件,生命周期管理
- MCPLinkConnection.java -SSE连接到MCP链路服务器
- MCPLink执行器.java -将操作路由到处理程序
- ReflectionExecutor.java -纯Java反射引擎(神奇!)
- MCPLinkProvider.java -连接状态UI面板
运作原理
- 延伸载荷 在CodeBrowser中打开程序时
- 连接到MCP链路 通过本地消息发现
- 注册为“ghidra”工具 具有反射能力
- AI发送表情 → 通过反射进行解析和执行
- 返回结果 具有类型信息和字符串表示
🔗 内置MCP工具
在使用MCP Link服务器运行时,可以使用以下工具:
| 工具 | 说明 |
|---|---|
| 🖥️ 系统 | Windows桌面自动化-屏幕截图、UI扫描、点击、打字、窗口管理 |
| 🔌 终端 | 通用传输-串行、TCP、SSH、Telnet、WebSocket、蓝牙、BLE、RFC2217、命名管道 |
| 🌐 Chrome 浏览器 | 唯一: 在原始的页面前加载环境中执行JS——这对web恶意软件分析至关重要 |
| 🧠 SQLite | 存储分析结果,带嵌入的语义搜索 |
| 💬 用户 | 显示HTML弹出窗口、表单,获取用户输入 |
| 🐍 python | 使用MCP工具访问本地Python执行 |
| 🤖 OpenRouter | 访问500多个AI模型 |
| 📚 背景7 | 实时库文档查找 |
🌐 Chrome浏览器:网络恶意软件分析超级大国
与任何其他浏览器自动化工具不同,我们的Chrome浏览器MCP提供了一些独特的东西: 原始的页面前加载JavaScript环境.
当您分析基于网络的恶意软件、混淆的JavaScript或恶意网页时,这些脚本通常:
- 以(权力)否决
console.log隐藏他们的活动 - 钩子
fetch和XMLHttpRequest拦截/修改网络流量 - 修改DOM方法以逃避检测
- 污染全局命名空间以破坏分析工具
我们的解决方案: 在执行任何页面脚本之前,我们注入 originalWindow -原始浏览器环境的冻结副本:
// In your analysis script (via run_script_in_page):
// Safe logging - works even if page redirected console.log to /dev/null
originalWindow.console.log('Malware did X, Y, Z');
// Bypass fetch hooks - make requests the malware can't intercept
const realData = await originalWindow.fetch('/api/secret');
// Access unmodified DOM - createElement that wasn't tampered with
const cleanDiv = originalWindow.document.createElement('div');
// See what the malware DID while having tools it COULDN'T break
const malwareState = document.body.innerHTML; // See malware's mess
originalWindow.console.log('Captured state:', malwareState); // Log safely
为什么这对RE很重要:
您可以同时:
- 看看恶意脚本做了什么 -访问被污染的DOM、挂钩函数、修改状态
- 使用不间断的工具进行分析 -原始控制台、获取、计时器、事件处理程序
加:在中执行JavaScript 任何调试目标 -服务工作者、web工作者、扩展背景、iframe。非常适合分析复杂的web应用程序和浏览器扩展。
🔧 系统+终端:真正的可再生能源工作必不可少
这两个工具是 逆向工程工作流程的游戏规则改变者:
系统工具 -查看桌面并与之交互:
- 截取正在运行的应用程序的屏幕截图
- 通过100%准确的文本提取扫描UI元素(无需OCR)
- 单击按钮,键入文本,自动化任何Windows应用程序
- 非常适合:捕获调试器状态、自动化IDA/x64dbg、与目标程序交互
终端工具 -连接到任何东西:
- 用于嵌入式设备调试的串行端口(ESP32、ARM、微控制器)
- 用于网络设备分析的TCP/Telnet
- SSH用于远程系统访问
- 蓝牙/BLE用于无线设备RE
- 用于浏览器调试协议的WebSocket(Chrome DevTools)
- 用于IPC分析的命名管道
为什么这对RE很重要:
在分析恶意软件或固件时,您通常需要:
- 运行目标 在受控环境中
- 观察行为 -监视窗口、网络流量、串行输出
- 互动 -单击对话框、响应提示、注入输入
- 捕捉状态 -屏幕截图、内存转储、通信日志
借助System+Terminal,AI可以自主完成所有这些工作。它可以运行一个示例,查看出现的窗口,截图,捕获网络流量,并将所有内容与Ghidra的静态分析相关联。
示例:在数据库中存储分析
{
"operation": "call_tool",
"tool_name": "sqlite",
"arguments": {
"input": {
"sql": "INSERT INTO functions (name, addr) VALUES (?, ?)",
"params": ["main", "0x140001000"]
}
}
}
示例:截取调试器的屏幕截图
{
"operation": "call_tool",
"tool_name": "system",
"arguments": {
"input": {
"operation": "take_screenshot",
"hwnd": "0x001234",
"tool_unlock_token": "..."
}
}
}
示例:监控嵌入式设备串行输出
{
"operation": "call_tool",
"tool_name": "terminal",
"arguments": {
"input": {
"operation": "open_session",
"endpoint": "COM3",
"baud_rate": 115200,
"tool_unlock_token": "..."
}
}
}
💡 用例
🔍 恶意软件分析
- 自动查找可疑功能
- 提取字符串和IOC
- 分解和分析加密例程
- 将结果存储在数据库中
🛡️ 脆弱性研究
- 查找危险的API调用
- 通过函数跟踪数据流
- 识别缓冲区溢出模式
- 自动记录调查结果
📚 文档生成
- 提取函数签名
- 生成API文档
- 创建调用图
- 构建符号数据库
🤖 自动化RE工作流程
- 批量分析二进制文件
- 比较功能相似性
- 跟踪版本之间的更改
- 生成报告
🔧 技术细节
线程安全
- 所有Ghidra API调用在需要时在Swing EDT上执行
- 后台SSE线程处理网络通信
- 并行分析的并发会话管理
表达式分析器
- 手写递归下降解析器
- 处理方法链、嵌套调用、字符串转义
- 类型感知参数转换
- 完全支持Java原语
会话保持
- 变量在会话中持续存在
- 多个会话用于并行工作
- 以编程方式清除会话
⚠️ 局限性
- 无循环构造 -使用带有变量赋值的脚本
- 无条件 -三元表达式有效,但if/else块无效
- 迭代器消耗 -迭代器在显示时被消耗
- 摇摆EDT -某些操作必须在主线程上运行
🤝 贡献
想贡献吗? PR欢迎!
对贡献者的想法
- 添加更多表达式语言功能(循环、条件)
- 为常见的RE任务创建示例脚本
- 改进错误消息和调试
- 构建与其他工具的集成
- 编写教程和文档
📄 许可证
Apache 2.0-有关详细信息,请参阅LICENSE文件
👤 作者
由...创建 奥拉星期五
🔗 链接
- MCP链路服务器: https://github.com/AuraFriday/mcp-link-server
- 模型上下文协议: https://modelcontextprotocol.io
- 吉德拉: https://ghidra-sre.org
- Ghidra GitHub: https://github.com/NationalSecurityAgency/ghidra
🛡️ 安全和环境假设
此插件专为 专业逆向工程工作流程.
它公开了对Ghidra Java API的反射式访问,其功能相当于编写和执行自定义Ghidra脚本。
与所有逆向工程工具一样,它假设您在一个适当隔离的环境中操作(例如:虚拟机、快照、非特权用户帐户)。
如果您的环境对于在Ghidra中分析不受信任的二进制文件是安全的,那么使用此插件也是安全的。
如果不是,这个插件就不是需要修复的东西。
❓ 常见问题解答
Q: 这适用于Ghidra 12.0吗?
A: 是的!使用Ghidra 12.0及更高版本进行测试。
Q: 我需要Python/Jython吗?
A: 不!纯Java反射-不需要Python。
Q: AI可以访问私有方法吗?
A: 是的! setAccessible(true) 允许访问任何成员。
Q: 这安全吗?
A: AI拥有完整的Ghidra API访问权限。仅与受信任的AI代理一起使用。
Q: 这个离线工作吗?
A: 是的!所有操作都是本地的。MCP Link服务器在您的计算机上运行。
Q: 我可以与Claude/ChatGPT/Cursor一起使用吗?
A: 适用于支持MCP协议的任何AI。
Q: 对性能有何影响?
A: 最小反射为每次调用增加了微秒级的开销。
🌟 明星这个项目!
如果你觉得这很有用,请在存储库中加星!
问题? 在GitHub上打开一个问题。
这是人工智能驱动的逆向工程的未来。 🚀