AI辅助逆向工程工具

GhidraMCP是一个连接Ghidra和AI助手的桥梁,通过Model Context Protocol(MCP)实现全面的AI辅助逆向工程,提供高级程序分析、交互式逆向工程和完整的数据操作功能。

  • by MartijnvanPraag
  • Java
  • 本地部署
  • 4 星标
  • 更新于
在 GitHub 查看 MartijnvanPraag/GhidraMCP

使用说明

GhidraMCP v2.0

GhidraMCP是一个强大的桥梁,连接着 Ghidra(注:Ghidra是一个反汇编和反编译工具,由美国国家安全局开发,此处直接音译,若需具体功能或背景介绍,可另行说明) 以及能够通过(某种方式,原文未指明具体方式)实现全面人工智能辅助逆向工程的人工智能助手 模型上下文协议(MCP).

概述

GhidraMCP v2.0集成了三个关键组件:

  1. 模块化Ghidra插件通过HATEOAS驱动的REST API,展现Ghidra强大的逆向工程能力
  2. MCP桥一个将MCP请求转换为带有全面类型检查的API调用的Python脚本
  3. 多实例架构连接多个Ghidra实例以同时分析不同的二进制文件

这种架构使得像Claude这样的AI助手能够无缝地:

  • 反编译并分析二进制代码,支持自定义输出格式
  • 映射程序结构、函数关系以及复杂数据类型
  • 执行高级二进制分析(交叉引用、调用图、数据流等)
  • 对分析进行精确修改(重命名、注释、创建/删除/修改数据等)
  • 直接读取内存并以低级方式操作二进制数据
  • 通过可发现的HATEOAS链接导航资源

GhidraMCP 是基于 由Laurie Wired开发的GhidraMCP 但已发展成为一个全面的逆向工程平台,具备增强的多实例支持、广泛的数据处理能力以及一个强大的符合HATEOAS标准的API架构。

特点/特性

GhidraMCP 2.0版通过其基于HATEOAS的API,为AI助手提供了一套全面的逆向工程功能:

高级程序分析

  • 增强型反编译:

    • 将二进制函数转换为可读的C代码
    • 在简洁的C语言风格伪代码和原始反编译输出之间切换
    • 显示/隐藏语法树以进行详细分析
    • 针对不同分析方法的多种简化风格
  • 全面静态分析:

    • 交叉引用分析(查找调用者和被调用者)
    • 完整的调用图生成与遍历
    • 带有变量追踪的数据流分析
    • 类型传播与重构
    • 功能关系映射
  • 内存操作:

    • 使用十六进制和原始字节表示进行直接内存读取
    • 地址空间导航与映射
    • 内存段分析
  • 符号管理:

    • 查看并分析进出口数据
    • 识别库函数和依赖项
    • 符号表的探索与操作
    • 命名空间层次结构可视化

交互式逆向工程

  • 代码理解:

    • 探索富含上下文的函数代码
    • 分析数据结构和复杂类型
    • 查看与反编译代码链接的反汇编视图
    • 检查函数原型和签名
  • 全面注释:

    • 重命名函数、变量和数据
    • 添加多种评论类型(EOL、板块、前/后置)
    • 创建和修改数据类型
    • 设置并更新函数签名和原型

完整的数据操作

  • 数据创建与管理:

    • 创建具有指定类型的新数据项
    • 删除现有数据项
    • 对数据项进行重命名,并妥善处理作用域
    • 为现有项目设置和更新数据类型
    • 合并重命名和重新输入操作
    • 类型定义管理
  • 功能操控:

    • 为函数重命名以使用适当的范围
    • 更新函数签名,包含参数信息
    • 修改局部变量的名称和类型
    • 设置函数返回类型

多实例支持

  • 同时运行多个Ghidra实例
  • 并行分析不同的二进制文件
  • 使用端口号连接到特定实例
  • 自动发现正在运行的Ghidra实例
  • 包含项目和文件信息的实例元数据
  • 插件版本和API兼容性检查

节目导航与发现

  • 列出并搜索函数、类和命名空间
  • 查看内存段和布局
  • 按名称、模式或签名搜索
  • 通过HATEOAS链接进行资源发现
  • 处理大型结果集的分页功能
  • 对所有资源的过滤功能

安装

先决条件

Ghidra(注:Ghidra是美国国家安全局开发的一款逆向工程工具)

首先,下载最新版本 发布 从这个仓库中获取。"Complete"(完整)构件包含了压缩的Ghidra插件和Python MCP桥接器。先解压外层的存档,然后将插件添加到Ghidra中:

  1. 运行Ghidra
  2. 选择 File -> Install Extensions
  3. 点击 + 按钮
  4. 选择 GhidraMCP-2.0.0-beta.1.zip (或您选择的版本)来自下载的发布版
  5. 重启Ghidra
  6. 确保已启用GhidraMCP插件 File -> Configure -> Developer

注: 默认情况下,在Ghidra中打开的第一个CodeBrowser会使用端口8192,第二个使用8193,依此类推。您可以通过查看Ghidra主(项目)窗口中的控制台来检查正在使用的端口——点击右下角的计算机图标以“打开控制台”。查找类似以下的日志条目:

(HydraMCPPlugin) Plugin loaded on port 8193
(HydraMCPPlugin) HydraMCP HTTP server started on port 8193

GhidraMCP 现在支持自动发现正在运行的 Ghidra 实例,因此通常无需手动注册每个实例。MCP 桥会在启动时自动发现并注册实例,并定期检查是否有新实例。

视频安装指南:

这个网址(https://github.com/user-attachments/assets/75f0c176-6da1-48dc-ad96-c182eb4648c3)的中文表述可以是:“GitHub用户附件资源中的75f0c176-6da1-48dc-ad96-c182eb4648c3文件/资源”。不过,具体翻译可能会根据上下文或使用场景有所调整,因为“assets”在这里可能指的是某种特定类型的资源或文件集合,而“user-attachments”则表明这些资源或文件是用户上传的附件。因此,更通用的翻译是上述表述

MCP 客户端

理论上,任何MCP客户端都应该能与GhidraMCP兼容。以下是两个示例。

API 参考(已更新至 v2.0)

可用工具

程序分析:

  • list_functions列出所有函数(参数:偏移量,限制数)
  • list_classes列出所有类/命名空间(参数:偏移量,限制)
  • decompile_function获取反编译的C代码(参数:名称或地址)
  • get_function获取函数详细信息(参数:名称或地址)
  • get_callgraph获取函数调用图(参数:地址)
  • list_segments查看内存段(参数:偏移量,限制)
  • list_imports列出导入的符号(参数:偏移量,限制)
  • list_exports列出导出的函数(参数:偏移量,限制数量)
  • list_namespaces显示命名空间(参数:偏移量,限制)
  • list_data_items查看数据标签(参数:偏移量,限制数量)
  • list_strings列出所有定义的二进制字符串(参数:偏移量、限制、过滤器)
  • search_functions_by_name查找函数(参数:查询、偏移量、限制)

函数操作:

  • rename_function重命名函数(参数:name,new_name)
  • set_function_signature更新函数原型(参数:地址,签名)
  • set_comment添加评论(参数:地址,评论,评论类型)
  • remove_comment删除评论(参数:地址,评论类型)

内存操作:

  • read_memory从内存中读取字节(参数:地址,长度)
  • get_disassembly获取反汇编指令(参数:地址,长度)

数据操作:

  • create_data在地址处创建新数据(参数:地址,数据类型)
  • delete_data删除地址处的数据(参数:地址)
  • set_data_type更改地址处的数据类型(参数:地址,数据类型)
  • rename_data重命名地址处的数据(参数:地址,名称)
  • update_data更新名称和类型(参数:地址、名称、数据类型)

实例管理:

  • list_instances列出活动的Ghidra实例(无参数)
  • register_instance注册新实例(参数:端口,URL)
  • unregister_instance移除实例(参数:端口)
  • discover_instances自动发现运行中的实例(参数:主机 [可选])

示例用法:

# Program analysis
client.use_tool("ghydra", "decompile_function", {"name": "main"})
client.use_tool("ghydra", "get_function", {"address": "0x00401000"})
client.use_tool("ghydra", "get_callgraph", {"address": "0x00401000"})

# Memory and disassembly operations
client.use_tool("ghydra", "read_memory", {"address": "0x00401000", "length": 16})
client.use_tool("ghydra", "get_disassembly", {"address": "0x00401000", "length": 32})

# String analysis
client.use_tool("ghydra", "list_strings")  # List all strings in the binary
client.use_tool("ghydra", "list_strings", {"limit": 100, "offset": 0})  # Pagination
client.use_tool("ghydra", "list_strings", {"filter": "password"})  # Search for strings containing "password"

# Function operations
client.use_tool("ghydra", "set_function_signature", {"address": "0x00401000", "signature": "int main(int argc, char **argv)"})
client.use_tool("ghydra", "set_comment", {"address": "0x00401100", "comment": "This instruction initializes the counter", "comment_type": "plate"})

# Data manipulation
client.use_tool("ghydra", "create_data", {"address": "0x00401234", "data_type": "int"})
client.use_tool("ghydra", "set_data_type", {"address": "0x00401238", "data_type": "char *"})
client.use_tool("ghydra", "rename_data", {"address": "0x00401234", "name": "my_variable"})
client.use_tool("ghydra", "update_data", {"address": "0x00401238", "name": "ptr_var", "data_type": "char *"})
client.use_tool("ghydra", "delete_data", {"address": "0x0040123C"})

# Instance management  
client.use_tool("ghydra", "register_instance", {"port": 8192, "url": "http://localhost:8192/"})
client.use_tool("ghydra", "register_instance", {"port": 8193})

# Auto-discover instances
client.use_tool("ghydra", "discover_instances")  # Default host
client.use_tool("ghydra", "discover_instances", {"host": "192.168.1.10"})  # Custom host

客户端设置

Claude 桌面配置

{
  "mcpServers": {
    "ghydra": {
      "command": "uv",
      "args": [
        "run",
        "/ABSOLUTE_PATH_TO/ghidra_mcp_server.py"
      ],
      "env": {
        "GHIDRA_HYDRA_HOST": "localhost"  // Optional - defaults to localhost
      }
    }
  }
}

注: 你也可以使用 python 而不是 uv run,但之后你需要先手动安装好所需的依赖项,使用 pip install mcp requests。

5ire 配置

  1. 工具密钥:ghydra
  2. 名称:GhidraMCP
  3. 命令: uv run /ABSOLUTE_PATH_TO/ghidra_mcp_server.py

示例会话

以下是AI助手如何使用GhidraMCP与多个Ghidra实例进行交互的一个示例:

用户:

Check which Ghidra instances are currently running.

助理:

I'll check which Ghidra instances are currently running by discovering any active instances.

View result from discover_instances from ghydra (local)
{
  "found": 2,
  "instances": [
    {
      "port": 8192,
      "url": "http://localhost:8192",
      "result": "Registered instance on port 8192 at http://localhost:8192"
    },
    {
      "port": 8193,
      "url": "http://localhost:8193",
      "result": "Registered instance on port 8193 at http://localhost:8193"
    }
  ]
}

View result from list_instances from ghydra (local)
{
  "instances": [
    {
      "port": 8192,
      "url": "http://localhost:8192",
      "project": "TestProject",
      "file": "application.exe"
    },
    {
      "port": 8193,
      "url": "http://localhost:8193",
      "project": "FirmwareAnalysis",
      "file": "firmware.bin"
    }
  ]
}

I found two active Ghidra instances:
1. Port 8192: Analyzing "application.exe" in project "TestProject"
2. Port 8193: Analyzing "firmware.bin" in project "FirmwareAnalysis"

I'm ready to analyze these binaries. What would you like me to examine?

用户:

List the functions through ghydra for both instances and identify any related functionality.

助手:

I'll list the functions from both instances and analyze them.

View result from list_functions from ghydra (local){
  `port`: 8192
}
[Function list for application.exe...]

View result from list_functions from ghydra (local){
  `port`: 8193
}
[Function list for firmware.bin...]

I notice some interesting functions in both binaries. Let me decompile a few to understand their behavior.

View result from get_function from ghydra (local){
  `port`: 8192,
  `name`: "process_command"
}
[Decompiled code for process_command...]

View result from get_function from ghydra (local){
  `port`: 8193,
  `name`: "handle_message"
}
[Decompiled code for handle_message...]

Based on this analysis, I can see these binaries communicate using a simple protocol where...

JSON通信

GhidraMCP 使用结构化的 JSON 格式来处理 Python 桥接器和 Java 插件之间的所有通信。这确保了数据交换的一致性和可靠性。

API架构

GhidraMCP v2.0实现了一个全面的基于HATEOAS的REST API,遵循超媒体设计原则:

核心API设计

  • HATEOAS(超媒体作为应用状态表征)架构每个回复都包含用于资源发现的导航链接
  • 带版本控制的端点所有请求均针对API版本进行验证,以确保兼容性
  • 结构化回应标准化的JSON格式,字段命名一致
  • 正确的HTTP方法GET 用于检索,POST 用于创建,PATCH 用于更新,DELETE 用于删除
  • 适当的状态码使用标准的HTTP状态码进行清晰的错误处理

响应格式

所有响应均遵循这种由HATEOAS驱动的格式:

{
  "id": "req-123",
  "instance": "http://localhost:8192",
  "success": true,
  "result": "...",
  "timestamp": 1712159482123,
  "_links": {
    "self": {"href": "/endpoint/current"},
    "related": [
      {"href": "/endpoint/related1", "name": "Related Resource 1"},
      {"href": "/endpoint/related2", "name": "Related Resource 2"}
    ]
  }
}

对于列表响应,会包含分页信息:

{
  "id": "req-123",
  "instance": "http://localhost:8192",
  "success": true,
  "result": [ ... objects ... ],
  "size": 150,
  "offset": 0,
  "limit": 50,
  "_links": {
    "self": { "href": "/functions?offset=0&limit=50" },
    "next": { "href": "/functions?offset=50&limit=50" },
    "prev": { "href": "/functions?offset=0&limit=50" }
  }
}

错误响应包含详细信息:

{
  "id": "req-123",
  "instance": "http://localhost:8192",
  "success": false,
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Function 'main' not found in current program"
  },
  "status_code": 404,
  "timestamp": 1712159482123,
  "_links": {
    "self": {"href": "/functions/main"}
  }
}

这种HATEOAS(超媒体作为应用状态表征)方法支持资源发现和自文档化的API,使得集成和探索工作大大简化。

测试

GhidraMCP包含针对HTTP API和MCP桥接器的全面测试套件。参见 TESTING.md 翻译为中文是:“测试说明文件”或“测试文档” 有关运行测试的详细信息。

HTTP API 测试

测试Java插件暴露的HTTP端点:

  • 响应格式和结构
  • JSON结构一致性
  • 响应中的必填字段
  • 错误处理

MCP桥接测试

测试MCP桥接功能:

  • MCP协议通信
  • 工具的可用性和结构
  • 响应格式和结构
  • JSON结构一致性

从源代码构建

你可以使用 Maven 构建不同的工件:

构建所有内容(默认)

构建Ghidra插件和完整包:

mvn clean package

这产生了:

  • target/GhidraMCP-[version].zip - 仅Ghidra插件
  • target/GhidraMCP-Complete-[version].zip - 完整的软件包,包含插件和桥接脚本

仅构建Ghidra插件

如果你只需要Ghidra插件:

mvn clean package -P plugin-only

仅构建完整包

如果您只需要组合套餐:

mvn clean package -P complete-only

Ghidra 插件包含这些文件,以便 Ghidra 能够识别该扩展:

  • lib/GhidraMCP.jar
  • extension.properties 翻译成中文是“扩展属性文件”
  • Module.manifest(模块清单文件)