Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ghidra_svr_bridge — Binary Ninja 插件,通过 Java 桥接子进程与 Ghidra Server 仓库进行双向分析同步。 | Kitploit
工具/GitHubGitHub/gmh5225/ghidra_svr_bridge
静态分析代码分析逆向工程脚本与自动化实用工具与框架二进制分析
GitHubgmh5225/ghidra_svr_bridge

ghidra_svr_bridge

Binary Ninja 插件,通过 Java 桥接子进程与 Ghidra Server 仓库进行双向分析同步。

查看仓库
21个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

binja-ghidra

一个 Binary Ninja 插件,可连接到 Ghidra Server 仓库,并将其分析结果——符号、函数名和注释——直接导入到已打开的 Binary Ninja 二进制视图中。

功能说明

Ghidra 和 Binary Ninja 各有优势。本插件让你可以在同一个二进制文件上同时使用两者,而无需手动在它们之间复制名称或注释。连接到正在运行的 Ghidra Server,浏览其仓库,双击任意项目文件即可将其分析结果拉取到当前打开的 BN 视图中。

同步是双向的。

BN ← Ghidra(导入)BN → Ghidra(检入)
符号(标签、函数名)✓✓
注释(EOL/PRE/POST/PLATE/REP)✓✓
函数签名(返回类型、调用约定)✓✓
函数参数(重命名、重设类型、添加)✓✓
数据类型(struct/union/enum/typedef + 指针/数组)✓✓
等价常量(常量名 + 引用)✓✓
书签✓✓
类型化数据项✓✓
函数标志(thunk、no-return、inline)✓ 作为 BN 标签—
局部变量(存储感知)✓部分——寄存器存储映射尚未实现

架构

root@kitploit:~
Binary Ninja (C++ plugin)
    │  TCP / newline-delimited JSON
    ▼
ghidra-bridge-*.jar  (Java, runs as a subprocess)
    │  Java RMI / SSL
    ▼
Ghidra Server  (ghidraSvr, running on the network)

插件在加载时会启动一个 Java 子进程(即“bridge”)。bridge 持有与 Ghidra Server 的 RMI 连接,并通过本地 TCP 套接字与插件之间使用简单的 JSON 协议通信。这样可以将所有 Java/RMI 代码排除在 C++ 进程之外,并让 JVM 在 BN 完成加载的同时在后台启动。

bridge JVM 还会在启动时初始化 Ghidra 的 Application 框架,以便写入路径可以使用 Ghidra 的高层程序模型 API(ProgramDB、DataTypeManager、SymbolTable、FunctionManager),而不是原始的 db.Table.putRecord() 写入——请参阅下方的检入写入路径。

组件

路径语言角色
plugin/C++ / Qt6Binary Ninja 侧边栏插件
bridge/Java 17Ghidra RMI 客户端 + JSON 桥接服务器

插件(C++):

  • plugin.cpp — 注册设置和侧边栏控件;在加载时立即启动 bridge JVM
  • GhidraConnection.cpp — 单例;管理 bridge 生命周期及所有基于 RMI 的操作
  • BridgeProcess.cpp — 将 bridge JAR 作为子进程启动,带有 stdout/stderr 管道;读取 READY port=N 握手行
  • BridgeClient.cpp — TCP 客户端;发送 JSON 请求、接收响应、分发异步事件
  • SyncEngine.cpp — 将 GhidraDbExport 应用到 BinaryView(符号、注释、标志)
  • ui/ProjectPanel.cpp — 侧边栏控件:仓库树、连接对话框、活动日志
  • ui/ConnectDialog.cpp — 主机/端口/用户/密码对话框

Bridge(Java):

  • BridgeMain.java — 参数解析;初始化 UniversalIdGenerator 和 Ghidra Application 框架;启动 TCP 服务器;向 stdout 打印 READY port=N
  • BridgeServer.java — 接受一个 TCP 客户端连接,并为其分配一个 BridgeConnection
  • BridgeConnection.java — JSON 请求分发器;将 Ghidra API 响应序列化为 JSON;处理 opCheckin(在服务器上创建新的程序版本)
  • GhidraSession.java — 已认证的 RMI 会话;封装 RemoteRepositoryServerHandle
  • EventStreamer.java — 每个已打开仓库的后台线程;将 RepositoryChangeEvent 作为异步 JSON 事件推送到插件
  • DatabaseExporter.java — 读取路径:通过原始 访问,从 (Ghidra 的远程数据库缓冲区)中提取符号/注释/函数标志/数据类型/等价常量/书签表

检入写入路径

opCheckin 以写入模式打开程序的管理缓冲区文件,在其上构造一个 ProgramDB,并通过 Ghidra 的程序模型 API 应用 BN 侧的更改。避免使用原始的 db.Table.putRecord() 写入——它们是我们遇到过的所有检入损坏 bug 的根源:

ProgramApplier 没有这些陷阱,因为它通过 DataTypeManager.addDataType、SymbolTable.createLabel、Listing.setComment、Function.setReturnType 等 API 进行路由——这些 API 会自动维护 Ghidra 相互关联表的不变量。它还会在每次检入开始时运行 cleanupBadVariableSymbols 过程,以清除旧版 bridge 在数据库中留下的损坏。

server-package/CleanupBadVariableSymbols.java 是一个独立的 GhidraScript,它通过 analyzeHeadless 运行相同的清理——当文件损坏严重到无法在 Ghidra GUI 中打开时非常有用。

测试

root@kitploit:~
./test.sh          # macOS / Linux: tiers 0-3 (C++ unit + BN-headless + Java)
test.bat           # Windows equivalent
test.bat --parity  # cross-DB parity tier only (C++ BN tests + gradlew parityTest)
test.bat --e2e     # live Ghidra-server E2E (starts a local ghidraSvr)

测试套件分为五个层级。第 2–4 层存在的目的是证明一个性质: 相同的兼容数据最终同时存储在 .bndb 和 Ghidra 程序数据库中(即本 README 顶部的兼容性矩阵)。

一致性判据(第 3 层)。 双方独立地针对相同的已检入规范 JSON(bridge DatabaseExporter 形状)进行验证。导入方向:黄金文件加载到 ProgramDB(Java)中,并通过 SyncEngine(C++)加载到 BinaryView 中,每次重新导出都必须等于黄金文件。检入方向:脚本化的 BN 编辑必须精确产生 fixtures/checkin/*/expected-preview.json(C++),并且通过 ProgramApplier 应用该预览后必须重新导出为 expected-after.json(Java)。如果双方都与共享黄金文件匹配,则两个数据库通过传递性达成一致。字段比较模式和类型名规范化表位于 testdata/parity/RULES.md;测试二进制文件是 testdata/bin/parity_x64.bin(布局在 parity_x64.md 中)。

Java 侧长期存在的回归固定测试:

  • DataTypesRoundTripTest.struct_cloneSettings_doesNotThrow — 复合设置必须与头部保持一致(cloneAllComponentSettings 崩溃)
  • FunctionSignaturesRoundTripTest.returnType_doesNotCorruptStackPurge — IntField 截断
  • ParametersRoundTripTest.noParameterSymbol_endsUpAtRamAddress — VariableAddress 不变量

往返和一致性测试需要 Ghidra 安装(在运行时用于语言服务)。路径从 ghidra.home Gradle 系统属性或 GHIDRA_HOME 环境变量读取;build.gradle 默认传递 ghidraHome。第 2/3 层 C++ 测试还需要 binaryninjacore 可加载(脚本将 BN 安装目录添加到 PATH)。

先决条件

Qt 设置

插件链接到与 Binary Ninja 使用的相同 Qt 6 构建。你有两个选项:

选项 A — 使用现有的 Qt 安装(如果你已有 Qt,这是最快的方式)

将 Qt6_DIR 指向你的 Qt CMake 目录:

root@kitploit:~
Qt6_DIR=/path/to/Qt/6.x.y/clang_64/lib/cmake/Qt6 ./build.sh

在 macOS 上,如果 Qt 是通过 Qt 在线安装程序安装在 /usr/local/Qt* 下,构建脚本会自动检测 Qt。

选项 B — 从 qt-build 子模块构建 Qt(约 1-2 小时,每台机器一次)

qt-build 子模块(Vector35 的 Qt 构建脚本)使用 Binary Ninja 的补丁编译 Qt 6。它需要 Poetry 和 libclang 19(请参阅上方的先决条件和 qt-build/README.md)。

Qt 安装到仓库内的 qt/<version>/<compiler>/:

平台安装路径
macOSqt/6.10.1/clang_64/
Linux x86-64qt/6.10.1/gcc_64/
Windowsqt/6.10.1/msvc2022_64/
root@kitploit:~
# First time on a new machine:
./build.sh qt          # compiles Qt — takes 1-2 hours

# All subsequent builds (Qt cached in qt/, reused automatically):
./build.sh

qt 步骤只需执行一次。CMake 和构建脚本在后续每次运行时都会检测 qt/ 中已构建的 Qt,并完全跳过子模块。qt/ 目录已被 gitignore。

构建

全新检出

root@kitploit:~
git clone https://github.com/mutinylaboratories/ghidra_svr_bridge.git
cd ghidra_svr_bridge
git submodule update --init   # populates binaryninja-api and qt-build (~seconds)

然后按照上方的 Qt 设置(选项 A 或 B)操作,并运行:

root@kitploit:~
./build.sh install

macOS / Linux

root@kitploit:~
# Incremental build of both components
./build.sh

# Full clean rebuild + install into BN plugins folder
./build.sh clean install

# Build only the C++ plugin
./build.sh plugin

# Build only the Java bridge
./build.sh bridge

# Build Qt once on a machine without Qt installed
./build.sh qt

环境变量(全部可选——脚本会设置合理的默认值):

root@kitploit:~
BN_INSTALL=/Applications/Binary\ Ninja.app/Contents/MacOS
Qt6_DIR=/usr/local/Qt-6.7.2/lib/cmake/Qt6

Windows

首次使用前,编辑 build.bat 顶部的路径以匹配你的环境:

root@kitploit:~
set "JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-21.0.11.10-hotspot"
set "VSDEVCMD=C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\VsDevCmd.bat"
set "Qt6_DIR=C:\qt\v6.7.2\lib\cmake\Qt6"
set "BN_INSTALL=C:\Program Files\Vector35\BinaryNinja"
root@kitploit:~
rem Incremental build of both components
build.bat

rem Full clean rebuild + install into BN plugins folder
build.bat clean install

rem Build only the C++ plugin
build.bat plugin

rem Build only the Java bridge
build.bat bridge

rem Build Qt once on a machine without Qt installed
build.bat qt

C++ 构建使用 CMake FetchContent 在 api_REVISION.txt 中记录的精确提交处克隆 binaryninja-api,因此插件 ABI 始终与已安装的 BN 版本匹配。如果未设置 GHIDRA_HOME,CMake 会在首次配置时自动下载 Ghidra。

配置

安装后,在 Binary Ninja 的设置中设置以下内容(Edit → Preferences → Settings,搜索 "Ghidra"):

用法

  1. 在 Binary Ninja 中打开一个二进制文件。
  2. 打开 Ghidra 侧边栏(红色的 "G" 图标)。
  3. 点击 Connect… 并输入你的服务器凭据。
  4. 仓库树会填充。点击仓库上的展开箭头(▶)以显示其文件夹和项目文件。
  5. 项目文件显示为粗体蓝色。双击其中一个,将其分析结果导入到当前打开的二进制视图中。
  6. 活动日志显示导入进度以及已应用符号的地址范围。

步骤 5 的先决条件: 程序文件必须已提交到 Ghidra Server 仓库(而不仅仅是在 Ghidra 中本地打开)。在 Ghidra 中:右键单击 Project 窗口中的文件 → Version Control → Add to Version Control…。

Bridge 协议

插件和 bridge 通过本地 TCP 套接字使用换行分隔的 JSON 进行通信。每个请求都携带一个整数 id 和一个字符串 op;每个响应都会回显 id。异步事件(服务器端仓库更改)则携带一个 "event" 键。

在另一台机器上继续

仓库包含从头重新构建所需的一切。不在 git 中的每位开发者设置:

  1. 克隆 + 子模块:
    root@kitploit:~
    git clone https://github.com/mutinylaboratories/ghidra_svr_bridge.git
    cd ghidra_svr_bridge
    git submodule update --init --recursive
    
  2. 本地 Ghidra 路径:创建 bridge/gradle.properties:
    root@kitploit:~
    ghidraHome=C:/Users/<you>/ghidra/ghidra_12.0.4_PUBLIC
    
    (正斜杠在 Windows 上也可用——Gradle 更喜欢它们。)
  3. Ghidra + Binary Ninja 安装:与你的其他机器相同的设置。
  4. Qt:要么将 Qt6_DIR 指向现有安装,要么运行一次 ./build.sh qt(Windows:build.bat qt)。
  5. Binary Ninja 发布通道:插件的 ABI 必须与你运行的 BN 匹配。构建时选择通道;脚本从 GitHub 获取匹配的 binaryninja-api 提交:
    root@kitploit:~
    ./build.sh --channel stable    # default — latest stable release (from GitHub)
    ./build.sh --channel dev        # latest dev (dev branch head, from GitHub)
    ./build.sh --bn-api <commit>   # explicit commit, no GitHub lookup (escape hatch)
    
    --channel 和 互斥;两者都不指定时,使用 通道。 会查询 GitHub(最新的 发布版,或 分支头),因此需要网络访问。如果你安装的 BN 落后于最新发布版,请传递 并附上该安装的 中的精确 SHA。

当打开一个新的 Claude Code 会话时,最好的入门指引是本 README 加上 dev 上的当前状态:

  • 架构和写入路径不变量:本文件
  • 生产写入路径:bridge/src/main/java/com/ghidra_svr/bridge/ProgramApplier.java
  • 测试框架:bridge/src/test/java/com/ghidra_svr/bridge/ProgramTestBase.java
  • 往返测试套件:bridge/src/test/java/com/ghidra_svr/bridge/*RoundTripTest.java
  • 最近的提交:git log --oneline — 每个主题行都说明了更改了什么以及为什么

已知限制 / 待完成工作

  • 局部变量存储:ProgramApplier 跳过 is_local 参数条目,因为将 BN 寄存器索引映射到 Ghidra 存储需要按架构的寄存器表转换。参数可以工作;局部变量尚未同步。
  • 身份验证:仅支持用户名 + 密码。PKI 和 SSH 密钥回调尚未处理。
  • 单一地址空间:DatabaseExporter 假设单一 RAM 地址空间。覆盖空间或哈佛架构可能会产生不正确的地址。
  • 变更集合并:bridge 写入一个空的 DBChangeSet 以保持检出正常工作。因此 Ghidra 的检出时合并机制无法自动解决 BN 和 Ghidra 用户之间的并发编辑——最后写入者获胜。
下载工具
db.jar
ManagedBufferFileHandle
  • ProgramApplier.java — 写入路径:将缓冲区文件作为真正的 ProgramDB 打开,并通过 Ghidra 的高层 API 应用所有 BN 侧的更改(请参阅下方的检入写入路径)
  • DatabaseImporter.java — 仅作为测试接缝保留的旧式原始写入辅助工具;生产环境的 apply(...) 委托给 ProgramApplier
  • 错误层级的写入失败模式
    在 Function Data 表上调用 setIntValue(col, longTypeId)IntField.setLongValue 会静默地 l2i 截断 → 每次签名更新时 StackPurge 损坏
    在 V5V6 Composite Data Types 上调用 setByteValue(col, isUnion)在 Ghidra 12.x 中该列是 BooleanField → IllegalFieldAccessException(“Illegal field access”)
    在 V2 Typedef Flags 列上调用 setIntValue(col, 0)该列是 ShortField → 同样的崩溃,不同的 schema
    写入复合头但没有组件设置行在 Ghidra 中打开结构体时,CompositeEditorModel.cloneAllComponentSettings 抛出 ArrayIndexOutOfBoundsException
    写入 PARAMETER 符号时 SYM_ADDR_COL = RAM 地址任何函数访问时,FunctionDB.loadSymbolBasedVariables 抛出 Address is not a VariableAddress
    向 DBHandle.save() 传递 null DBChangeSet服务器写入 0 字节的变更数据文件 → 下次检出时在 ProgramContentHandler.loadProgramChangeSet 中因 EOFException 失败
    层级内容位置门槛
    0纯单元测试plugin/test/*.cpp(binja-ghidra-tests)、bridge *Test.java始终运行
    1Ghidra-DB 往返bridge *RoundTripTest.java(ProgramApplier 针对真实的 ProgramDB)需要 ghidra.home / GHIDRA_HOME
    2BN BinaryView/.bndb 往返plugin/test/bn/(binja-ghidra-bn-tests;headless binaryninjacore)在没有支持 headless 的 BN 许可证时干净地 SKIP(遵循 BN_LICENSE 环境变量)
    3跨数据库一致性CanonicalParityTest(C++ 和 Java)针对 testdata/parity/fixtures/ 中的共享黄金文件与第 1+2 层一起
    4实时服务器 E2Ebridge LiveServerE2ETest — 在临时目录中启动真实的 ghidraSvr,通过 analyzeHeadless 播种,通过 RMI 驱动检出 → 导出 → 检入 → 重新导出test.bat --e2e(设置 GHIDRA_E2E=1)
    依赖项说明
    Binary Ninja(商业版)针对与 BN 安装中 api_REVISION.txt 匹配的版本进行测试
    Ghidra Server使用 Ghidra 12.0.4 测试。必须正在运行并可通过 RMI/SSL 访问
    Java 17+ JDK推荐 Eclipse Adoptium JDK 21
    CMake 3.24+
    Ninja
    C++ 编译器Windows 上为 MSVC 2022+;macOS 上为 clang;Linux 上为 gcc/clang
    Qt 6.7+请参阅下方的 Qt 设置;构建时 qmake 必须在 PATH 上
    Gradle(通过 wrapper)bridge 使用 Gradle wrapper——无需单独安装
    Poetry (仅 Qt 构建)仅当从 qt-build 子模块构建 Qt 时需要。使用 pip install poetry 或 pipx install poetry 安装。
    libclang 19 (仅 Qt 构建)Qt 构建系统需要。下载说明请参阅 qt-build/README.md。
    设置描述
    ghidra.javaExejava.exe 的完整路径
    ghidra.ghidraHomeGhidra 安装的根目录(包含 Ghidra/Framework/…)
    ghidra.trustAllCerts如果你的 Ghidra Server 使用自签名证书,请设置为 true
    ghidra.defaultHost预填充连接对话框
    ghidra.defaultPort默认值:13100
    ghidra.defaultUser预填充连接对话框
    Op方向用途
    ping、status、connect、disconnect请求/响应会话生命周期
    list_repos、open_repo、close_repo请求/响应仓库枚举
    list_items、get_subfolders请求/响应仓库浏览
    get_versions、get_checkouts请求/响应版本控制状态
    checkout、terminate_checkout请求/响应独占写锁
    open_db请求/响应读取完整 Ghidra DB → JSON(重量级)
    checkin请求/响应应用 BN 侧更改 → 新仓库版本(重量级,通过 ProgramApplier)
    download_binary、upload_binary请求/响应移入/移出原始二进制文件
    delete_item请求/响应从仓库中删除文件
    repo_changed事件(异步)服务器端 RepositoryChangeEvent 推送
    --bn-api
    stable
    --channel
    Vector35/binaryninja-api
    stable/*
    dev
    --bn-api
    api_REVISION.txt