alexbevi/ghidra-manager

GitHub: alexbevi/ghidra-manager

一款跨平台的 Ghidra 命令行管理工具,用于自动化安装特定版本、管理兼容插件并启动 GhidraMCP 逆向分析项目。

Stars: 0 | Forks: 0

Ghidra Manager logo

# Ghidra 管理器 Ghidra Manager 是一个跨平台的 CLI,用于安装 Ghidra 并为特定版本编译经过审查的扩展集合。它跟踪稳定的 GitHub 发布版本,要求发布资产提供 GitHub 发布的 SHA-256 摘要,从不可变的发布提交构建插件,并保留当前活动的安装以及一个完整的回滚配对。 `ghidra-manager` Python 命令是 Windows、Linux 和 macOS 上唯一受支持的面向用户的入口点。 对于 Codex 工作流,此仓库还包含 [`ghidra-manager` skill](https://github.com/alexbevi/ghidra-manager/blob/main/skills/ghidra-manager/SKILL.md)。 调用 `$ghidra-manager` 以检查管理状态、选择已审查的插件、启动并验证项目、连接 bridge、定位项目内的特定程序、比较二进制文件,或开发 manager 本身。该 skill 遵循与 CLI 相同的安全规则:将 `instances` 作为运行时的事实来源,当打开多个程序时显式指定程序,并在执行写入操作前审查比较结果。该 skill 在源代码仓库中维护,不会通过 PyPI 包安装到 Codex 中。 ## 命令摘要 以下示例使用尖括号缩写了路径、进程 ID 和版本。不带子命令运行 `ghidra-manager` 等同于 `ghidra-manager sync`。 | 命令 | 选项 | 示例输出 | | --- | --- | --- | | `ghidra-manager help` | 全局: `-h`, `--help` | `usage: ghidra-manager ... {help,sync,status,...}` | | `ghidra-manager --version` | 无 | `ghidra-manager 0.1.0` | | `ghidra-manager sync` | `--dry-run` 解析但不改变状态 | `Active pair: Ghidra ; plugins ghidra-lx-loader, mcp.` | | `ghidra-manager status` | 无 | `Active Ghidra: ` | | `ghidra-manager doctor [PROJECT]` | `--program PROGRAM`, `--json`, `--base-port PORT` | `Doctor result: ready` | | `ghidra-manager rollback` | 无 | `Rolled back to Ghidra ; plugins mcp.` | | `ghidra-manager projects` | 无 | `Projects known to Ghidra :` | | `ghidra-manager plugins discover` | `--json` | `mcp` 显示为 `selected` 或 `available` | | `ghidra-manager plugins list` | `--json` | `Plugins for Ghidra :` | | `ghidra-manager plugins install PLUGIN` | `mcp` 或 `ghidra-lx-loader` | `Installed plugin mcp for Ghidra .` | | `ghidra-manager plugins remove PLUGIN` | `mcp` 或 `ghidra-lx-loader` | `Removed plugin mcp from Ghidra .` | | `ghidra-manager open PROJECT` | `--program PROGRAM`, `--timeout SECONDS`, `--base-port PORT` | `GhidraMCP instance ready:` | | `ghidra-manager launch [GHIDRA_ARGS...]` | 其余参数直接传递给 Ghidra | `Launching Ghidra with JDK 21...` | | `ghidra-manager launch-multi [PROJECT.gpr ...]` | `--count N`, `--timeout SECONDS`, `--base-port PORT` | `GhidraMCP instances ready:` | | `ghidra-manager bridge [BRIDGE_ARGS...]` | 其余参数直接传递给 bridge | `` | | `ghidra-manager compare SOURCE_PROJECT TARGET_PROJECT` | `--base-port PORT` | `Plan saved: /compare-plans/.json` | | `ghidra-manager compare --apply PLAN` | 无源或目标参数 | `Applied operations to .` | | `ghidra-manager instances` | `--base-port PORT` | `MCP port 8089` | `launch` 和 `bridge` 会刻意将其余参数直接传递,而不是自行解释。环境变量也可以设置 manager 主目录、MCP 基础端口、启动超时和 GitHub 身份验证;这些在下文的详细章节中有所描述。 ## 安装 安装 [`uv`](https://docs.astral.sh/uv/) 和 64 位 JDK 21。CLI 使用 uv 来配置 Python 3.13,因此不需要系统安装 Python。 在隔离的工具环境中安装已发布的 CLI: ``` uv tool install ghidra-manager ghidra-manager help ``` 独立于受管理的 Ghidra 安装和插件对其进行升级: ``` uv tool upgrade ghidra-manager ``` 从代码检出于开发环境进行安装: ``` uv sync --locked --group dev uv run ghidra-manager help ``` JDK 发现在每个平台上都会检查 `JAVA_HOME` 和 `PATH`。macOS 还会在可用时使用 `/usr/libexec/java_home` 和 Homebrew。 ## 安装、更新和回滚 解析并安装最新的稳定版 Ghidra 版本。全新安装不包含任何插件;随后的 sync 会为新 Ghidra 版本重新构建活动配对中选定的插件: ``` ghidra-manager sync ``` 预览发布选择而不更改管理状态: ``` ghidra-manager sync --dry-run ``` 显示当前活动的、保留的以及最新的上游版本: ``` ghidra-manager status ``` 代表性输出: ``` Active Ghidra: Active plugin: ghidra-lx-loader (installed) Active plugin: mcp (installed) Previous pair: Ghidra ; plugins mcp Upstream Ghidra: ``` 检查本地逆向工程就绪状态,而无需解析上游发布: ``` ghidra-manager doctor ghidra-manager doctor ripper --program RIPPER.LE ghidra-manager doctor ripper --program RIPPER.LE --json ``` `doctor` 会验证活动配对、受管理的安装和 MCP 插件、JDK 21、已记录的项目、响应的 MCP 身份和版本、预期的打开程序、endpoint 目录以及分析状态。错误会产生非零退出代码;警告仍然被视为成功,以便可以检查部分环境。 代表性的就绪输出: ``` OK active-pair: Ghidra ; plugins ghidra-lx-loader, mcp OK project: /projects/ripper.gpr OK instance: PID on http://127.0.0.1:8089 OK program: RIPPER.EXE is open OK analysis: RIPPER.EXE analyzed; 847 functions Doctor result: ready ``` 返回到保留的上一个配对: ``` ghidra-manager rollback ``` 在执行 sync 或回滚之前,请关闭受管理的 Ghidra 进程。回滚会在更改活动状态之前,重新安装保留配对的完整插件集,包括当两个配对共享同一个 Ghidra 版本时。 `GH_TOKEN` 或 `GITHUB_TOKEN` 可用于对 GitHub API 请求进行身份验证。 ## 管理插件 列出从 manager 内置注册表获取的已审查插件: ``` ghidra-manager plugins discover ghidra-manager plugins discover --json ghidra-manager plugins list ghidra-manager plugins list --json ``` 内置注册表是 [`src/ghidra_manager/plugin_registry.json`](https://github.com/alexbevi/ghidra-manager/blob/main/src/ghidra_manager/plugin_registry.json),而不是远程市场。其初始审查目录包含 `mcp` 和 `ghidra-lx-loader`。发现是只读的,并且在安装 Ghidra 之前就可以工作。在安装或更新插件时,插件版本是从稳定的 GitHub 发布中解析出来的,而不是在注册表中固定的。 `discover` 显示注册表成员资格以及每个插件是否在活动配对中被选中: ``` mcp | GhidraMCP | selected | bethington/ghidra-mcp ghidra-lx-loader | Ghidra LX Loader | selected | yetmorecode/ghidra-lx-loader ``` `list` 显示针对活动 Ghidra 版本解析出的制品: ``` Plugins for Ghidra : ghidra-lx-loader | | | mcp | | | ``` 为活动的 Ghidra 版本安装或更新一个插件: ``` ghidra-manager sync ghidra-manager plugins install mcp ghidra-manager plugins install ghidra-lx-loader ghidra-manager plugins remove ghidra-lx-loader ``` 插件安装需要一个活动的 Ghidra 安装,并且在有 manager 拥有的 Ghidra 进程运行时拒绝替换扩展。manager 将最新的稳定插件发布标签解析为其不可变的 commit,使用目标 Ghidra 发行版的 Gradle wrapper,验证生成的扩展 ZIP,然后以事务方式激活完整的选定集。 删除是幂等的,并会创建一个回滚配对,保留被删除的制品直到不再被引用为止。 在使用 `bridge`、`instances`、`open`、`launch-multi` 或 `compare` 之前,请安装 `mcp`。在导入 LE/LX 二进制文件(例如 DOS/4GW 或 OS/2 Linear Executables)之前,请安装 `ghidra-lx-loader`。 ## 管理状态 全新安装使用原生的用户数据目录: - Windows: `%LOCALAPPDATA%\ghidra-manager` - Linux: `${XDG_DATA_HOME:-~/.local/share}/ghidra-manager` - macOS: `~/Library/Application Support/ghidra-manager` 设置 `GHIDRA_MANAGER_HOME` 可覆盖此位置。 ``` / ├── ghidra// ├── plugins//// ├── pairs//metadata.json ├── state.json ├── gradle-cache/ ├── launch-logs/ ├── compare-plans/ ├── python/ └── uv-cache/ ``` `state.json` 记录当前和上一个配对 ID,而不需要符号链接。每个配对都记录其确切的 Ghidra 版本和已排序的插件清单。 下载、构建和扩展安装在原子状态替换之前都会进行验证。失败的扩展替换会恢复每个受影响的插件目录。 当首次从包含旧版 `.managed/` 布局的代码检出中运行时,CLI 会原地采用该目录,并将有效的 `current` 和 `previous` 配对元数据转换为版本化的 JSON。此后不再需要旧版符号链接。 现有的 GhidraMCP 配对在迁移时会选中 `mcp`,并保留其旧版制品路径,直到 current 或 previous 都不再引用它们。 ## 运行 Ghidra 和 GhidraMCP 如果尚未选中,请先安装 MCP 插件: ``` ghidra-manager plugins install mcp ``` 列出已记录的项目以解析确切的项目路径: ``` ghidra-manager projects ``` 代表性输出: ``` Projects known to Ghidra : ripper | ready | last-opened | active MCP port 8089 (PID ) | /projects/ripper.gpr harvester | ready | recent | inactive | /projects/harvester.gpr 2 recorded projects from /preferences ``` 通过名称或 `.gpr` 路径打开一个已记录的项目,并等待其 GhidraMCP endpoint: ``` ghidra-manager open ripper ghidra-manager open /path/to/ripper.gpr --program RIPPER.LE ``` `open` 会保留一份启动日志,拒绝已处于活动状态的项目,并且仅在新 endpoint 识别出预期的项目和可选程序后才报告成功。使用 `--timeout` 或 `--base-port` 可覆盖发现默认设置。 代表性输出: ``` Opening /projects/ripper.gpr with Ghidra and JDK 21... Launcher PID | log /launch-logs/.log Waiting up to 180 seconds for project ripper on ports 8089-8104... GhidraMCP instance ready: MCP port 8089 | PID | project ripper | http://127.0.0.1:8089 Open programs: RIPPER.LE ``` 启动活动的发行版,可选择通过其 `.gpr` 路径打开一个项目: ``` ghidra-manager launch ghidra-manager launch /path/to/project.gpr ``` `launch` 将所有剩余参数直接传递给 Ghidra。它不会将记录的名称(例如 `ripper`)解析为其项目路径,因此 `launch --help` 会被转发给 Ghidra,而不是作为 CLI 帮助处理。请使用 `ghidra-manager help` 获取 manager 命令摘要。 在首次启动新的 Ghidra 设置版本时: 1. 打开或创建一个项目并启动 CodeBrowser。 2. 选择 **File > Configure > Configure All Plugins** 并启用 **GhidraMCP**。 3. 选择 **Tools > GhidraMCP > Start MCP Server**。 该插件默认监听 `127.0.0.1:8089`,并可能依次回退到端口 8104。通过列出响应的实例来验证启动;启动器横幅或退出代码本身并不能证明 Ghidra 仍在运行: ``` ghidra-manager instances ``` 代表性输出: ``` MCP port 8089 | PID | project ripper | http://127.0.0.1:8089 ``` 为每个项目启动一个进程并等待新的 MCP endpoint: ``` ghidra-manager launch-multi \ /path/to/first-project.gpr \ /path/to/second-project.gpr ``` 不带路径时,`launch-multi` 默认打开两个实例。使用 `--count`、`--timeout` 或 `--base-port` 可覆盖启动行为。项目和项目名称必须不同,并且已处于活动状态的项目会被拒绝。分离的启动日志保留在 `launch-logs/` 下。 向 Codex 注册受管理的 stdio bridge: ``` codex mcp add ghidra -- ghidra-manager bridge ``` bridge 使用由 uv 管理的 Python 3.13 和上游保留的脚本: ``` ghidra-manager bridge --help ``` `GHIDRA_MCP_BASE_PORT` 更改发现基础端口。 `GHIDRA_MCP_LAUNCH_TIMEOUT` 更改多重启动超时。 ## 与 Codex 配合使用 内置的 [`ghidra-manager` skill](https://github.com/alexbevi/ghidra-manager/blob/main/skills/ghidra-manager/SKILL.md) 会向 Codex 传授 manager 的命令边界、插件生命周期、启动检查和比较保障措施。仓库目录是事实来源;请安装或链接 `skills/ghidra-manager` 为 `$CODEX_HOME/skills/ghidra-manager`,并启动一个新的 Codex 会话以使 `$ghidra-manager` 可用。一旦该 skill 和 bridge 可用,请求可以显式指定该 skill 的名称: ``` Use $ghidra-manager to inspect the active Ghidra pair, discover the reviewed plugins, open the ripper project, and confirm its MCP program before making any changes. ``` CLI 用于识别活动的项目;GhidraMCP 用于识别其中的程序。当打开多个程序时,请在 MCP 调用中使用它们完整的 Ghidra 项目路径,而不是依赖活动的标签页: ``` /RIPPER.LE /v1.05/RIPPER.EXE ``` `open` 和 `doctor` 上的 `--program` 是可选的。当就绪状态依赖于一个确切打开的程序时,请提供它。在 MCP 调用中,当打开多个程序时,请务必提供 `program`。 ## 端到端示例:将 RIPPER 与 v1.05 进行比较 本示例以一个名为 `ripper` 的已记录项目中已分析的 `/RIPPER.LE` 以及位于 `/path/to/Ripper/RIPPER/RIPPER.EXE` 的修补过的 DOS/4GW 可执行文件为起点。 ### 1. 安装审查过的运行时 安装 Ghidra,检查内置注册表,并在启动 Ghidra 之前添加这两个插件: ``` ghidra-manager sync ghidra-manager plugins discover ghidra-manager plugins install mcp ghidra-manager plugins install ghidra-lx-loader ghidra-manager plugins list ``` 插件安装会为活动的 Ghidra 版本编译每个稳定版本。在安装或更新插件之前,请关闭 manager 拥有的 Ghidra 进程。 ### 2. 注册 bridge 并验证项目 ``` codex mcp add ghidra -- ghidra-manager bridge ghidra-manager projects ghidra-manager open ripper --program RIPPER.LE ghidra-manager instances ghidra-manager doctor ripper --program RIPPER.LE ``` 此时,manager 已经证明了正在使用的是哪个 Ghidra、插件集、JDK、项目、进程、端口和程序。 ### 3. 通过 MCP 导入修补过的可执行文件 manager 不会复制 Ghidra 的导入 API。在验证启动后,要求 Codex 使用 GhidraMCP: ``` Use $ghidra-manager. In the ripper project, create the virtual folder /v1.05 and import /path/to/Ripper/RIPPER/RIPPER.EXE there with the LX loader. Keep /RIPPER.LE unchanged. Run analysis, save the new program, and verify its format, project path, and function count through MCP. ``` 重要的验证是 loader 的结果,而不仅仅是一次成功的导入: ``` name: RIPPER.EXE project path: /v1.05/RIPPER.EXE executable format: Linear Executable (LE-Style DOS) language: x86:LE:32:default analysis: complete ``` ### 4. 保守地进行比较和同步 二进制文件可以共享一个 MCP 实例,同时保持明确无误: ``` /RIPPER.LE original documentation source /v1.05/RIPPER.EXE patched v1.05 target ``` 对于一个项目中的程序,要求 Codex 使用这些完整路径查询 GhidraMCP。 仅针对唯一的、完全匹配的标准化代码传输函数文档,保留目标冲突,并分别审查更改过的函数。可移植的数据类型图(如结构体、枚举、数组、指针和函数签名)可以在等效性检查后从源复制到目标;不要在重建的二进制文件之间复制派生自地址的 `switchD_*` 命名空间。 为本教程提供参考的 RIPPER 运行产生了: ``` Original /RIPPER.LE: 1,682 functions, 561 data types Target /v1.05/RIPPER.EXE: 847 functions, 567 data types Unique exact matches: 675 functions Target documentation: 679/847 functions (80.2%) Copied source data types: 561/561 equivalent ``` 这些计数特定于此样本。可重用的价值在于这个受严密保护的工作流:可重现的插件、经过验证的运行时身份、显式的程序路径、精确匹配的传输、冲突保留以及保存后的健康检查。 完成后执行: ``` ghidra-manager doctor ripper --program RIPPER.EXE ghidra-manager instances ``` ## 跨实例比较二进制文件 将第一个响应的项目视为文档源,将第二个视为目标: ``` ghidra-manager compare source-project target-project ``` 比较是只读的。它首先汇总清单,然后仅当标准化的 opcode 哈希和指令计数在每个程序中唯一标识一个函数时才匹配函数。它会报告缺失的函数元数据、结构和枚举,而不会覆盖冲突的目标状态。 每次比较都会在 `compare-plans/` 下写入一个私有的版本化计划,并保留最新的十个。显式应用已审查的计划: ``` ghidra-manager compare --apply \ /path/to/compare-plans/-source-to-target.json ``` Apply 会重新检查目标项目、PID、函数哈希、文档和类型状态。它会在第一个被拒绝的操作时停止,并刻意将更改保留在 Ghidra 中不保存,以便进行审查或撤销。 `compare` 需要两个不同的、响应的项目实例。对于一个项目中的两个程序,请使用 RIPPER 示例中的完整路径 MCP 工作流,而不是尝试启动同一个项目两次。 ## 验证 ``` uv sync --locked --group dev uv run pytest uv run ruff check . uv run mypy uv build uv run ghidra-manager sync --dry-run git diff --check ``` Pull-request CI 在 Ubuntu x64、Windows x64、macOS ARM64 和 macOS x64 上运行。手动触发的工作流会在同一矩阵上执行实际的 sync、幂等 resync、状态检查和 bridge 冒烟测试。 ## 故障排除 - **未找到 JDK 21:** 设置 `JAVA_HOME` 或将 Java 21 放入 `PATH`。 - **GitHub 速率限制:** 设置 `GH_TOKEN` 或 `GITHUB_TOKEN`。 - **MCP 连接被拒绝:** 打开 CodeBrowser,启用 GhidraMCP,并从 **Tools > GhidraMCP** 启动其服务器。 - **MCP 插件未安装:** 关闭受管理的 Ghidra 进程,运行 `ghidra-manager plugins install mcp`,然后重新启动 Ghidra。 - **插件构建失败:** 检查报告的 Gradle 输出并继续使用未更改的活动配对;失败的构建永远不会被激活。 - **无效的项目:** 传递 `projects` 命令报告的 `.gpr` 路径,而不仅仅是其显示名称。 - **打开超时:** 完成打开 CodeBrowser,启用 GhidraMCP,并检查 `open` 报告的保留日志路径。 - **Doctor 未就绪:** 解决每个 `ERROR` 检查项,然后在开始写入工作流之前重新运行相同的项目和程序选择。 - **多重启动超时:** 在每个项目中完成打开 CodeBrowser,然后运行 `ghidra-manager instances`。 - **拒绝更新:** 关闭所有从受管理的 Ghidra 组件目录运行的进程。 - **比较目标已更改:** 生成一个新的计划,而不是应用陈旧的操作。 - **无项目注册表:** 启动一次 Ghidra,以便它创建平台设置并记录一个项目。
标签:后台面板检测, 逆向工具