0xeb/libghidra

GitHub: 0xeb/libghidra

一个面向 Ghidra 的多语言自动化 SDK,提供 Python、Rust 和 C++ 的强类型 API,支持远程连接 Ghidra 实例和完全离线的嵌入式反编译后端,让逆向分析可以像基础设施一样被程序化调用。

Stars: 66 | Forks: 4

# libghidra 用于 Ghidra 程序数据库的强类型 API。从 C++、Python 或 Rust 查询函数、类型、内存、反编译器输出等内容——无需接触 Java。 当前版本:`0.0.2` alpha。API 已可用,但仍在不断演进中。 ## 使用 AI 智能体安装(推荐) 搭建 libghidra 端到端环境最快的方法是将 AI 编码智能体(Claude Code、Cursor、Codex、Aider 等)指向捆绑的 安装器提示词: 它是一个自包含的运行手册,在每个步骤都设有明确的验证关卡—— 预检、Ghidra 安装、主机扩展安装、 Python wheel 安装,以及首次实时反编译。将其交给您的 智能体并让其驱动安装;仅在关卡报告 失败时才进行干预。 如果您更愿意自己驱动安装,请参阅下面的**开始运行**。 ## 开始运行 ### 快速入门 如果您正在评估此版本,最简的成功路径是: 1. 将 `LibGhidraHost` 扩展安装到 Ghidra 12.0.4+ 发行版中。 2. 启动 Ghidra,打开一个程序,然后启动 `Tools > libghidra Host > Start Server...`。 3. 首先使用 Python 客户端验证连接性。 4. 然后在相同的主机 URL 之上叠加 C++/Rust SDK 或您自己的工具。 此路径演练了当前版本的重点:实时类型化访问、反编译器支持的读取, 以及结构化注释写入。 ### 前置条件 - [Ghidra](https://ghidra-sre.org/) 发行版 (12.0.4+) - 用于构建 Java 扩展的 JDK 21(例如 [Eclipse Adoptium](https://adoptium.net/)) - 用于构建 Java 扩展的 [Gradle](https://gradle.org/) - `libghidra/ghidra-extension` 中没有检入独立的 Gradle wrapper - 如果您拥有本地的 Ghidra 源码树,您也可以使用 `ghidra/gradlew.bat` 驱动扩展构建 - `protoc` 对于常规扩展构建是可选的;预生成的 Java protobuf 存根已包含在源码树中 - C++20 编译器 (Visual Studio 2022, GCC 12+, 或 Clang 15+) —— 仅在使用 C++ SDK 时需要 - CMake 3.20+ —— 仅在使用 C++ SDK 时需要 ### 1. 安装 libghidra 主机扩展 此步骤将安装通过 HTTP 提供强类型 libghidra RPC API 的 Ghidra 插件: `GHIDRA_INSTALL_DIR` 必须指向 Ghidra 发行版的根目录,即包含 `support/buildExtension.gradle` 的目录。 例如,如果您将 Ghidra 解压到 `C:\ghidra_dist\ghidra_12.1_DEV`,请使用该完整的内部路径作为安装目录。 常规扩展构建不需要 `protoc`;如果缺少它,构建将使用自带的生成存根。 ``` cd ghidra-extension gradle installExtension -PGHIDRA_INSTALL_DIR=/path/to/ghidra_dist ``` 如果您已经检出本地的 Ghidra 源码树,此基于 wrapper 的变体也可以工作: ``` C:\path\to\ghidra\gradlew.bat -p libghidra\ghidra-extension installExtension -PGHIDRA_INSTALL_DIR=C:\ghidra_dist\ghidra_12.1_DEV ``` 安装后,扩展将被解压到: ``` /path/to/ghidra_dist/Ghidra/Extensions/LibGhidraHost ``` ### 2. 启动 API 服务器 **选项 A —— 从 Ghidra GUI 启动:** 从您安装了扩展的同一发行版启动 Ghidra 并打开一个程序。然后: 1. 转到 `File > Configure` 并启用 `LibGhidraHost`(如果尚未启用)。 2. 使用 `Tools > libghidra Host > Start Server...`,然后接受默认 URL 或输入完整的 `http://host:port` URL 或纯 `host:port`。 3. 可选地检查 `Tools > libghidra Host > Status` 以确认绑定的 URL 和活动程序。 默认情况下,启动对话框预填充为 `http://127.0.0.1:18080`。 要覆盖 GUI 绑定/端口,请通过 Ghidra 的启动器环境变量使用 JVM 属性启动 Ghidra: ``` set GHIDRA_GUI_JAVA_OPTIONS=-Dlibghidra.host.bind=127.0.0.1 -Dlibghidra.host.port=19090 C:\ghidra_dist\ghidra_12.1_DEV\ghidraRun.bat ``` **选项 B —— Headless 模式(无 GUI):** ``` /path/to/ghidra_dist/support/analyzeHeadless \ ./myproject MyProject -import target.exe \ -postScript LibGhidraHeadlessServer.java port=18080 ``` headless 命令也必须使用包含 `support/analyzeHeadless` 的 Ghidra 发行版根目录。 ### 3. 查询 API **Python**(最简单): 预构建的 wheel 包(Python 3.12+)附在每次[发布](https://github.com/0xeb/libghidra/releases)中。每个原生 wheel 都捆绑了 HTTP/RPC 客户端和离线本地后端—— Ghidra 的 Sleigh 反编译引擎已被编译在内,并嵌入了 Sleigh 处理器规格,因此在运行时不需要安装 Ghidra 或 Java。 ``` # Linux x86_64 (RHEL 8+, Ubuntu 20.04+, Debian 11+, Fedora 29+) pip install https://github.com/0xeb/libghidra/releases/download/v0.0.2/libghidra-0.0.2-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl # Linux aarch64 (Raspberry Pi 4/5 on 64-bit OS, Ubuntu aarch64, Debian arm64) pip install https://github.com/0xeb/libghidra/releases/download/v0.0.2/libghidra-0.0.2-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl # macOS Apple Silicon (M1/M2/M3/M4) pip install https://github.com/0xeb/libghidra/releases/download/v0.0.2/libghidra-0.0.2-cp312-abi3-macosx_15_0_arm64.whl # Windows x64 pip install https://github.com/0xeb/libghidra/releases/download/v0.0.2/libghidra-0.0.2-cp312-abi3-win_amd64.whl ``` 没有适合您平台的 wheel(Intel Mac、Windows on Arm 等)?请使用发布页上 `libghidra-python-v0.0.2.zip` 中的纯 Python 备用 `libghidra-0.0.2-py3-none-any.whl`——它仅提供 HTTP/RPC 客户端;本地离线后端不可用。 对于从克隆仓库进行的贡献者/可编辑安装: ``` pip install -e python # HTTP/RPC client only pip install -e "python[async]" # adds aiohttp for AsyncGhidraClient pip install -e "python[cli]" # adds pefile/capstone for CLI offline helpers pip install -e "python[local]" # adds local ELF/PE/Mach-O detection helpers ``` 从源代码构建离线本地后端还需要 CMake 3.24+、C++20 编译器和本地 Ghidra 源码树——请参阅[构建 C++ SDK](#building-the-c-sdk)。 在 Python 中使用原生本地后端时,请安装 `libghidra[local]`。 `LocalClient` 会自动检测 ELF、PE、Mach-O 和原始数据输入,并将匹配的 Ghidra `language_id` 传递给后端。高级用户仍然可以在 `OpenProgramRequest` 上传递显式的 `language_id`。 ``` import libghidra as ghidra client = ghidra.connect("http://127.0.0.1:18080") status = client.get_status() print(f"Connected: {status.service_name}") funcs = client.list_functions() for f in funcs.functions[:10]: print(f" 0x{f.entry_address:x} {f.name}") ``` Python 包还安装了 `libghidra` 命令,用于快速状态检查、函数列表、反编译和小型离线二进制辅助工具: ``` libghidra status --url http://127.0.0.1:18080 libghidra functions --url http://127.0.0.1:18080 --limit 20 libghidra decompile --url http://127.0.0.1:18080 0x140001000 ``` **C++:** ``` #include "libghidra/ghidra.hpp" auto client = ghidra::connect("http://127.0.0.1:18080"); auto funcs = client->ListFunctions(/*min_addr=*/0, /*max_addr=*/UINT64_MAX, /*limit=*/10, /*offset=*/0); if (funcs.ok()) for (auto& f : funcs.value->functions) printf("0x%llx %s\n", f.entry_address, f.name.c_str()); ``` **Rust:** 就像 Python wheel 一样,Rust crate 在一个包中发布了两个后端——并且也像 Python wheel 一样,它**是从 GitHub Releases 页面分发的,而不是 crates.io**: ``` [dependencies] # Live (HTTP) only — pure Rust, no system deps libghidra = { git = "https://github.com/0xeb/libghidra" } # Live + offline (cxx → C++ engine, prebuilt archive needed) libghidra = { git = "https://github.com/0xeb/libghidra", features = ["local"] } ``` ``` # Or grab a prebuilt local archive from the Releases page: cargo binstall libghidra ``` 完整说明请参见 [`rust/README.md`](rust/README.md)。 ``` use libghidra as ghidra; // Live (HTTP) — needs a Ghidra Desktop with the LibGhidraHost extension let client = ghidra::connect("http://127.0.0.1:18080"); let funcs = client.list_functions(0, u64::MAX, 10, 0)?; for f in &funcs.functions { println!("0x{:x} {}", f.entry_address, f.name); } // Offline — no Ghidra install required at runtime (feature = "local") # #[cfg(feature = "local")] { let local = ghidra::local()?; let _ = libghidra::format_detect::detect_and_open(&local, "/usr/bin/ls", None)?; let dec = local.get_decompilation(0xa000, 30_000)?; println!("{}", dec.decompilation.unwrap().pseudocode); # } # Ok::<(), libghidra::Error>(()) ``` ## 构建 C++ SDK ``` cmake -B build -G "Visual Studio 17 2022" cmake --build build --config Release ``` 在 Windows 上,推荐使用 Visual Studio 生成器。MinGW 可能在构建 HTTP 客户端时有效,但本地/离线后端已使用 MSVC 进行了验证。 这会构建 `libghidra_client`(HTTP 客户端)。离线本地后端是可选的,因为它还需要本地的 Ghidra 源码检出。 要同时构建离线本地后端: ``` # 1) Apply libghidra's patches to Ghidra's C++ decompiler source. CI does # this automatically before every release build; if you skip it, ELF # binaries on non-x86 architectures (aarch64, ARM, RISC-V, …) will load # as x86 and disassemble as nonsense. cd /path/to/ghidra-source for p in /path/to/libghidra/cpp/patches/*.patch; do patch -p1 < "$p"; done cd - # 2) Overlay compiled Sleigh `.sla` grammars from the Ghidra release ZIP. # The git source tree only ships `.slaspec` (grammar source) — without # the compiled `.sla` files, the embedded-spec generator finds the # architecture metadata but the decompiler has no grammar to use, so # every disassembly returns `halt_baddata()`. Download the matching # Ghidra release ZIP, extract, and copy: # cp -R ghidra_*_PUBLIC/Ghidra/Processors/*/data/languages/*.sla \ # /path/to/ghidra-source/Ghidra/Processors//data/languages/ # (one .sla per processor; the ci.yml `Overlay compiled Sleigh .sla` # step has the exact rsync invocation.) # 3) Configure + build. cmake -B build -G "Visual Studio 17 2022" \ -DLIBGHIDRA_WITH_LOCAL=ON \ -DGHIDRA_SOURCE_DIR=/path/to/ghidra-source cmake --build build --config Release ``` **仅限源码构建 —— `cargo binstall` / `pip install` 用户请跳过 所有这些。** 发布的 wheel 和 Rust 预构建存档由 CI 生成,已应用了补丁步骤和 `.sla` 覆盖层。 如果在 `.sla` 更新后重新同步相同的 Ghidra 源码树,请先删除 `build/cpp/embedded_specs.{cpp,h}`——`embed_specs.py` 的 mtime 过期检查信任源码的 mtime,而 rsync/cp 会保留来自 发布 ZIP 的原始时间戳,因此重新覆盖可能看起来比缓存输出“更旧”。 ### CMake 目标 | 目标 | 别名 | 说明 | |--------|-------|------| | `libghidra_client` | `libghidra::client` | IClient + HTTP 后端 + protobuf 存根 | | `libghidra_local` | `libghidra::local` | 添加离线反编译器后端(运行时无需 Java) | ``` target_link_libraries(app PRIVATE libghidra::client) # HTTP only target_link_libraries(app PRIVATE libghidra::local) # HTTP + offline ``` 也支持已安装包的使用: ``` find_package(libghidra CONFIG REQUIRED) target_link_libraries(app PRIVATE libghidra::client) ``` 安装将导出 `libghidra::client` 和 `libghidra::local`,以及当前公共 C++ API 所使用的生成 `libghidra/*.h` protobuf 头文件。 依赖项(通过 FetchContent 自动获取):protobuf v29.3、cpp-httplib v0.16.3。 ## 离线 / 本地后端 本地后端直接嵌入了 Ghidra 的 Sleigh 反编译引擎——无需 Java、无需网络、无需运行 Ghidra 实例。处理器规格在构建时嵌入;在运行时它是完全自包含的。 ``` #include "libghidra/ghidra.hpp" ghidra::LocalOptions opts; opts.pool_size = 4; // parallel decompilation (default: 1) auto client = ghidra::local(opts); ghidra::OpenRequest req; req.program_path = "/path/to/binary.exe"; req.language_id = "x86:LE:64:default"; // optional; Python LocalClient can auto-detect client->OpenProgram(req); auto decomp = client->GetDecompilation(0x140001000, 30000); if (decomp.ok()) printf("%s\n", decomp.value->decompilation->pseudocode.c_str()); ``` 涵盖 HTTP、headless 和本地后端(内存、反汇编、注释、数据项、符号、类型、结构体、枚举、签名、CFG、会话管理、并行 headless 分析以及完整的 headless 实战手册)的完整示例,请参见 [`cpp/examples/`](cpp/examples/)。 有关逐个方法的完整参考,请参见 [C++ LocalClient API 参考](cpp/README.md)。 ## 架构 ``` IClient (composite interface, 88 domain methods) |-- HttpClient --> POST /rpc (protobuf) --> libghidra host (Java, live Ghidra) |-- LocalClient --> standalone C++ decompiler engine (offline, no Java) ``` 两个后端,一个接口。每次调用都返回 `StatusOr` —— 检查 `.ok()`,然后使用 `.value`。 | | **远程** (HttpClient) | **本地** (LocalClient) | |---|---|---| | 运行时 | Ghidra JVM + 扩展 | 无 | | 功能 | 实时主机 API(读写) | 离线子集:反编译器、函数、符号、类型、内存、列表、xref | | 用例 | GUI 自动化、实时分析、写入 | 离线批量反编译、CI、工具集成 | ## 目录结构 ``` libghidra/ proto/ Protobuf service contracts (source of truth) cpp/ C++ SDK (two CMake targets from one directory) include/libghidra/ Public headers src/ HTTP + local backend + decompiler engine generated/ Pre-generated protobuf stubs examples/ Complete examples (HTTP + local) python/ Python SDK rust/ Rust SDK ghidra-extension/ Java extension project (installed as `LibGhidraHost`) ``` ## SDK 状态 | SDK | 状态 | 说明 | |-----|--------|-------| | **C++ (HttpClient)** | 可用 | 广泛的实时主机 API 覆盖 | | **C++ (LocalClient)** | 可用 | 离线子集;有关支持和不支持的方法,请参见 [cpp/](cpp/) | | **Python** | 可用 | 同步 + 异步 HTTP、类型化模型和 CLI 工具。请参见 [python/](python/) 和 [API 参考](python/docs/api_reference.md) | | **Rust** | 可用 | 同步 HTTP 客户端、类型化模型和分页辅助工具。请参见 [rust/](rust/) 和 [API 参考](rust/docs/api_reference.md) | ## 已知限制 - 在做出兼容性承诺之前,方法名和数据模型可能仍会更改。 - 当前的公共 C++ API 仍会在 `libghidra/*` 下暴露生成的 protobuf 头文件。 - 支持结构化的局部变量修改,但调用者应使用 API 返回的规范 `local_id`,而不是猜测显示样式的名称。 - 主要验证路径是实时主机加 headless 集成覆盖;更广泛的 干净打包和安装程序覆盖仍是发布强化工作的一部分。 ### 本地后端(`LocalClient`)注意事项 - **枚举方法在本地模式下超出了范围。** `IClient` 是跨 两个后端的共享 API。`HttpClient` 与运行中的 Ghidra 实例通信,该实例的分析过程会填充一个 完整的函数/xref/字符串数据库—— `list_functions()`、`list_basic_blocks(addr)`、 `list_cfg_edges(addr)`、`list_xrefs(start, end)` 和 `list_defined_strings()` 在 那里会如您预期般工作。`LocalClient` 包装了独立的 C++ 反编译引擎,它不 运行分析过程;这些相同的枚举方法在设计上总是返回空。本地 模式用于**地址驱动**的查询—— `get_decompilation(addr)`、 `list_instructions(start, end)`、`read_bytes(addr, n)`、`rename_function(addr, name)` 以及 其余的按地址 API 都会按文档所述工作。如果您需要枚举已分析程序中的所有内容,请通过 `HttpClient` 路由到 Ghidra 主机。 - **矩阵中没有 macOS x86_64 / Windows arm64 wheel** —— 两者都因 GitHub Actions 运行器可用性(macos-13 饱和)和 `actions/setup-python` 尚未为 `windows-11-arm` 提供_arm64_ Python 而被放弃。这两个空白都将在日后重新评估;同时,这些 平台上的用户可以从发布 ZIP 中 `pip install` 纯 Python wheel 以使用 HTTP 客户端。 - **升级 wheel 后,请清除一次规格缓存。** 原生模块在 首次使用时将 Ghidra 的 Sleigh 数据解压到 `~/.ghidracpp/cache/sleigh//` 中;该 key 现在是 嵌入规格的内容哈希(rc8+),因此升级会自动获取新数据。 较旧的 rc wheel(rc1–rc7)哈希的是宿主进程二进制文件的 mtime,可能会留下 过期的缓存。如果您是从其中一个版本升级的,请运行一次 `rm -rf ~/.ghidracpp`。 ## Proto 契约 跨越 9 个领域服务区域的类型化 RPC,定义在 [`proto/libghid/`](proto/libghidra/) 中。当前的契约定义了 88 个领域 RPC 加上一个传输 RPC。传输是在 `POST /rpc` 上的二进制 protobuf(不是 gRPC)。请参见 [proto/README.md](proto/README.md)。 ## 许可证 本项目根据 [Mozilla Public License 2.0](LICENSE) 授权。
标签:AI编程助手, API, Bash脚本, C++, Claude, CMake, Cursor, CVE检测, Ghidra, Gradle, JARM, JS文件枚举, Protobuf, Python, Rust, TLS抓取, 二进制分析, 云安全运维, 云资产清单, 交叉引用, 代码注释, 内存分析, 反编译器, 可视化界面, 可配置连接, 后台面板检测, 基础设施化, 多语言绑定, 开发库, 数据擦除, 无后门, 漏洞测试, 程序分析, 符号检查, 类型查询, 网络流量审计, 网络调试, 自动化, 软件安全, 逆向工具, 逆向工程