Ghidra AI逆向工程扩展

一个为Ghidra设计的扩展,通过Java反射提供对Ghidra API的完全访问,使AI代理能够远程控制Ghidra进行逆向工程分析。

  • by AuraFriday
  • Java
  • 本地部署
  • 8 星标
  • 更新于
在 GitHub 查看 AuraFriday/ghidra_mcp

使用说明

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)

📦 安装

先决条件

  1. 吉德拉12.0+ -下载自https://ghidra-sre.org/

  2. MCP链路服务器 -下载自https://github.com/AuraFriday/mcp-link-server/releases

  3. 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/

安装扩展

  1. 打开Ghidra
  2. 首选 File → 安装扩展
  3. 点击 + 按钮
  4. 从以下位置选择ZIP文件 mcp_link_ghidra/dist/
  5. 重新启动Ghidra
  6. 在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面板

运作原理

  1. 延伸载荷 在CodeBrowser中打开程序时
  2. 连接到MCP链路 通过本地消息发现
  3. 注册为“ghidra”工具 具有反射能力
  4. AI发送表情 → 通过反射进行解析和执行
  5. 返回结果 具有类型信息和字符串表示

🔗 内置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很重要:

您可以同时:

  1. 看看恶意脚本做了什么 -访问被污染的DOM、挂钩函数、修改状态
  2. 使用不间断的工具进行分析 -原始控制台、获取、计时器、事件处理程序

加:在中执行JavaScript 任何调试目标 -服务工作者、web工作者、扩展背景、iframe。非常适合分析复杂的web应用程序和浏览器扩展。


🔧 系统+终端:真正的可再生能源工作必不可少

这两个工具是 逆向工程工作流程的游戏规则改变者:

系统工具 -查看桌面并与之交互:

  • 截取正在运行的应用程序的屏幕截图
  • 通过100%准确的文本提取扫描UI元素(无需OCR)
  • 单击按钮,键入文本,自动化任何Windows应用程序
  • 非常适合:捕获调试器状态、自动化IDA/x64dbg、与目标程序交互

终端工具 -连接到任何东西:

  • 用于嵌入式设备调试的串行端口(ESP32、ARM、微控制器)
  • 用于网络设备分析的TCP/Telnet
  • SSH用于远程系统访问
  • 蓝牙/BLE用于无线设备RE
  • 用于浏览器调试协议的WebSocket(Chrome DevTools)
  • 用于IPC分析的命名管道

为什么这对RE很重要:

在分析恶意软件或固件时,您通常需要:

  1. 运行目标 在受控环境中
  2. 观察行为 -监视窗口、网络流量、串行输出
  3. 互动 -单击对话框、响应提示、注入输入
  4. 捕捉状态 -屏幕截图、内存转储、通信日志

借助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上打开一个问题。


这是人工智能驱动的逆向工程的未来。 🚀