[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-75442":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":14,"forks30d":14,"starsTrendScore":18,"compositeScore":19,"rankGlobal":9,"rankLanguage":9,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":14,"starSnapshotCount":14,"syncStatus":15,"lastSyncTime":28,"discoverSource":29},75442,"libghidra","0xeb\u002Flibghidra","0xeb","SDK for automating Ghidra from Python, Rust, and C++. Decompile, rename, annotate, inspect symbols\u002Ftypes\u002Fxrefs, and manage project lifecycle programmatically - treat Ghidra like infrastructure, not just a GUI.",null,"C++",148,14,1,0,2,4,27,6,3.53,"Mozilla Public License 2.0",false,"main",true,[],"2026-06-12 02:03:34","# libghidra\n\nTyped API for Ghidra program databases. Query functions, types, memory, decompiler output, and more from C++, Python, or Rust -- without touching Java.\n\nCurrent release: `0.0.3` alpha. The API is usable, but still evolving.\n\n## Install with an AI agent (recommended)\n\nThe fastest way to stand up libghidra end-to-end is to point an AI\ncoding agent (Claude Code, Cursor, Codex, Aider, etc.) at the bundled\ninstaller prompt:\n\n> [`install-prompt.md`](install-prompt.md)\n\nIt is a self-contained runbook with explicit verification gates at\nevery step — preflight checks, Ghidra install, host extension install,\nPython wheel install, and a first live decompilation. Hand it to your\nagent and let it drive the install; intervene only if a gate reports a\nfailure.\n\nIf you would rather drive the install yourself, see **Get Running**\nbelow.\n\n## Get Running\n\n### Quickstart\n\nIf you are evaluating this release, the shortest successful path is:\n\n1. Install the `LibGhidraHost` extension into a Ghidra 12.0.4+ distribution.\n2. Start Ghidra, open a program, and start `Tools > libghidra Host > Start Server...`.\n3. Verify connectivity with the Python client first.\n4. Then layer the C++\u002FRust SDKs or your own tooling on top of the same host URL.\n\nThis path exercises the current release focus: live typed access, decompiler-backed reads,\nand structured annotation writes.\n\n### Prerequisites\n\n- [Ghidra](https:\u002F\u002Fghidra-sre.org\u002F) distribution (12.0.4+)\n- JDK 21 (e.g. [Eclipse Adoptium](https:\u002F\u002Fadoptium.net\u002F)) for building the Java extension\n- [Gradle](https:\u002F\u002Fgradle.org\u002F) for building the Java extension\n  - no standalone Gradle wrapper is checked into `libghidra\u002Fghidra-extension`\n  - if you have the local Ghidra source tree, you can also drive the extension build with `ghidra\u002Fgradlew.bat`\n- `protoc` is optional for normal extension builds; pre-generated Java protobuf stubs are included in-tree\n- C++20 compiler (Visual Studio 2022, GCC 12+, or Clang 15+) -- only if using the C++ SDK\n- CMake 3.20+ -- only if using the C++ SDK\n\n### 1. Install the libghidra host extension\n\nThis installs the Ghidra plugin that serves the typed libghidra RPC API over HTTP:\n\n`GHIDRA_INSTALL_DIR` must point at the Ghidra distribution root, the directory that contains `support\u002FbuildExtension.gradle`.\nFor example, if you unpack Ghidra under `C:\\ghidra_dist\\ghidra_12.1_DEV`, use that full inner path as the install dir.\n\nNormal extension builds do not require `protoc`; if it is missing, the build uses the shipped generated stubs.\n\n```bash\ncd ghidra-extension\ngradle installExtension -PGHIDRA_INSTALL_DIR=\u002Fpath\u002Fto\u002Fghidra_dist\n```\n\nIf you already have the local Ghidra source tree checked out, this wrapper-based variant works too:\n\n```bat\nC:\\path\\to\\ghidra\\gradlew.bat -p libghidra\\ghidra-extension installExtension -PGHIDRA_INSTALL_DIR=C:\\ghidra_dist\\ghidra_12.1_DEV\n```\n\nAfter install, the extension is unpacked under:\n\n```text\n\u002Fpath\u002Fto\u002Fghidra_dist\u002FGhidra\u002FExtensions\u002FLibGhidraHost\n```\n\n### 2. Start the API server\n\n**Option A -- From the Ghidra GUI:**\nStart Ghidra from the same distribution you installed into and open a program. Then:\n\n1. Go to `File > Configure` and enable `LibGhidraHost` if it is not already enabled.\n2. Use `Tools > libghidra Host > Start Server...`, then accept the default URL or enter a full `http:\u002F\u002Fhost:port` URL or plain `host:port`.\n3. Optionally check `Tools > libghidra Host > Status` to confirm the bound URL and active program.\n\nBy default, the start dialog is prefilled with `http:\u002F\u002F127.0.0.1:18080`.\n\nTo override the GUI bind\u002Fport, launch Ghidra with JVM properties via Ghidra's launcher environment variables:\n\n```bat\nset GHIDRA_GUI_JAVA_OPTIONS=-Dlibghidra.host.bind=127.0.0.1 -Dlibghidra.host.port=19090\nC:\\ghidra_dist\\ghidra_12.1_DEV\\ghidraRun.bat\n```\n\n**Option B -- Headless (no GUI):**\n```bash\n\u002Fpath\u002Fto\u002Fghidra_dist\u002Fsupport\u002FanalyzeHeadless \\\n  .\u002Fmyproject MyProject -import target.exe \\\n  -postScript LibGhidraHeadlessServer.java port=18080\n```\n\nThe headless command must also use the Ghidra distribution root that contains `support\u002FanalyzeHeadless`.\n\n### Project files and active-program switching\n\nA Ghidra project may contain many domain files and many programs, but a\nlibghidra host intentionally has one active `Program` at a time. Use the\nproject RPCs to list or import project contents, then switch the active program\nwith an explicit close\u002Fopen sequence:\n\n```python\nimport libghidra as ghidra\n\nwith ghidra.launch_headless(ghidra.HeadlessOptions(\n    ghidra_dir=\"C:\u002Fghidra_dist\u002Fghidra_12.1_DEV\",\n    project_dir=\"C:\u002Fwork\u002Fprojects\",\n    project_name=\"firmware\",\n    binary=\"C:\u002Fsamples\u002Floader.elf\",\n    binaries=[\"C:\u002Fsamples\u002Fpayload.elf\"],\n    initial_program=\"\u002Floader.elf\",\n    shutdown=\"save\",\n)) as host:\n    files = host.list_project_files(ghidra.ListProjectFilesRequest(programs_only=True))\n    for item in files.files:\n        print(item.path)\n\n    host.close_program(ghidra.ShutdownPolicy.SAVE)\n    host.open_program(ghidra.OpenRequest(\n        project_path=\"C:\u002Fwork\u002Fprojects\",\n        project_name=\"firmware\",\n        program_path=\"\u002Fpayload.elf\",\n    ))\n```\n\n`OpenProgramRequest.program_path` is a Ghidra domain path such as\n`\u002Fpayload.elf` or `\u002Ffirmware\u002Fpayload.elf` when `project_path` and\n`project_name` are set. Existing program-scoped APIs such as functions, memory,\ntypes, decompiler, and comments always read or mutate the active program only.\n\n### 3. Query the API\n\n**Python** (easiest):\n\nPre-built wheels (Python 3.12+) are attached to every [release](https:\u002F\u002Fgithub.com\u002F0xeb\u002Flibghidra\u002Freleases). Each native wheel bundles both the HTTP\u002FRPC client and the offline local backend — Ghidra's Sleigh decompiler engine is compiled in and Sleigh processor specs are embedded, so no Ghidra install or Java is needed at runtime.\n\n```bash\n# Linux x86_64 (RHEL 8+, Ubuntu 20.04+, Debian 11+, Fedora 29+)\npip install https:\u002F\u002Fgithub.com\u002F0xeb\u002Flibghidra\u002Freleases\u002Fdownload\u002Fv0.0.3\u002Flibghidra-0.0.3-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl\n\n# Linux aarch64 (Raspberry Pi 4\u002F5 on 64-bit OS, Ubuntu aarch64, Debian arm64)\npip install https:\u002F\u002Fgithub.com\u002F0xeb\u002Flibghidra\u002Freleases\u002Fdownload\u002Fv0.0.3\u002Flibghidra-0.0.3-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl\n\n# macOS Apple Silicon (M1\u002FM2\u002FM3\u002FM4)\npip install https:\u002F\u002Fgithub.com\u002F0xeb\u002Flibghidra\u002Freleases\u002Fdownload\u002Fv0.0.3\u002Flibghidra-0.0.3-cp312-abi3-macosx_15_0_arm64.whl\n\n# Windows x64\npip install https:\u002F\u002Fgithub.com\u002F0xeb\u002Flibghidra\u002Freleases\u002Fdownload\u002Fv0.0.3\u002Flibghidra-0.0.3-cp312-abi3-win_amd64.whl\n```\n\nNo wheel for your platform (Intel Mac, Windows on Arm, etc.)? Use the pure-Python fallback `libghidra-0.0.3-py3-none-any.whl` inside `libghidra-python-v0.0.3.zip` on the release page — it gives you the HTTP\u002FRPC client only; the local offline backend is unavailable.\n\nFor contributor \u002F editable installs from a clone:\n\n```bash\npip install -e python                       # HTTP\u002FRPC client only\npip install -e \"python[async]\"              # adds aiohttp for AsyncGhidraClient\npip install -e \"python[cli]\"                # adds pefile\u002Fcapstone for CLI offline helpers\npip install -e \"python[local]\"              # adds local ELF\u002FPE\u002FMach-O detection helpers\n```\n\nBuilding the offline local backend from source additionally needs CMake 3.24+, a C++20 compiler, and a local Ghidra source tree — see [Building the C++ SDK](#building-the-c-sdk).\n\nInstall `libghidra[local]` when using the native local backend from Python.\n`LocalClient` auto-detects ELF, PE, Mach-O, and raw data inputs and passes the\nmatching Ghidra `language_id` to the backend. Advanced users can still pass an\nexplicit `language_id` on `OpenProgramRequest`.\n\n```python\nimport libghidra as ghidra\n\nclient = ghidra.connect(\"http:\u002F\u002F127.0.0.1:18080\")\nstatus = client.get_status()\nprint(f\"Connected: {status.service_name}\")\n\nfuncs = client.list_functions()\nfor f in funcs.functions[:10]:\n    print(f\"  0x{f.entry_address:x}  {f.name}\")\n```\n\nThe Python package also installs a `libghidra` command for quick status checks,\nfunction listing, decompilation, and small offline binary helpers:\n\n```bash\nlibghidra status --url http:\u002F\u002F127.0.0.1:18080\nlibghidra functions --url http:\u002F\u002F127.0.0.1:18080 --limit 20\nlibghidra decompile --url http:\u002F\u002F127.0.0.1:18080 0x140001000\n```\n\n**C++:**\n```cpp\n#include \"libghidra\u002Fghidra.hpp\"\n\nauto client = ghidra::connect(\"http:\u002F\u002F127.0.0.1:18080\");\nauto funcs = client->ListFunctions(\u002F*min_addr=*\u002F0, \u002F*max_addr=*\u002FUINT64_MAX,\n                                   \u002F*limit=*\u002F10, \u002F*offset=*\u002F0);\nif (funcs.ok())\n    for (auto& f : funcs.value->functions)\n        printf(\"0x%llx  %s\\n\", f.entry_address, f.name.c_str());\n```\n\n**Rust:**\n\nJust like the Python wheel, the Rust crate ships both backends in one\npackage — and just like the Python wheel, it's **distributed from the\nGitHub Releases page, not crates.io**:\n\n```toml\n[dependencies]\n# Live (HTTP) only — pure Rust, no system deps\nlibghidra = { git = \"https:\u002F\u002Fgithub.com\u002F0xeb\u002Flibghidra\" }\n\n# Live + offline (cxx → C++ engine, prebuilt archive needed)\nlibghidra = { git = \"https:\u002F\u002Fgithub.com\u002F0xeb\u002Flibghidra\", features = [\"local\"] }\n```\n\n```bash\n# Or grab a prebuilt local archive from the Releases page:\ncargo binstall libghidra\n```\n\nSee [`rust\u002FREADME.md`](rust\u002FREADME.md) for the full story.\n\n```rust\nuse libghidra as ghidra;\n\n\u002F\u002F Live (HTTP) — needs a Ghidra Desktop with the LibGhidraHost extension\nlet client = ghidra::connect(\"http:\u002F\u002F127.0.0.1:18080\");\nlet funcs = client.list_functions(0, u64::MAX, 10, 0)?;\nfor f in &funcs.functions {\n    println!(\"0x{:x}  {}\", f.entry_address, f.name);\n}\n\n\u002F\u002F Offline — no Ghidra install required at runtime (feature = \"local\")\n# #[cfg(feature = \"local\")] {\nlet local = ghidra::local()?;\nlet _ = libghidra::format_detect::detect_and_open(&local, \"\u002Fusr\u002Fbin\u002Fls\", None)?;\nlet dec = local.get_decompilation(0xa000, 30_000)?;\nprintln!(\"{}\", dec.decompilation.unwrap().pseudocode);\n# }\n# Ok::\u003C(), libghidra::Error>(())\n```\n\n## Building the C++ SDK\n\n```bash\ncmake -B build -G \"Visual Studio 17 2022\"\ncmake --build build --config Release\n```\n\nOn Windows, prefer the Visual Studio generator. MinGW may work for the HTTP\nclient, but the local\u002Foffline backend is validated with MSVC.\n\nThis builds `libghidra_client` (HTTP client). The offline local backend is\nopt-in because it also needs a local Ghidra source checkout.\n\nTo also build the offline local backend:\n\n```bash\n# 1) Apply libghidra's patches to Ghidra's C++ decompiler source. CI does\n#    this automatically before every release build; if you skip it, some\n#    local\u002Foffline loads will fail or mis-detect architecture metadata.\ncd \u002Fpath\u002Fto\u002Fghidra-source\nfor p in \u002Fpath\u002Fto\u002Flibghidra\u002Fcpp\u002Fpatches\u002F*.patch; do patch -p1 \u003C \"$p\"; done\ncd -\n\n# 2) Overlay compiled Sleigh `.sla` grammars from the Ghidra release ZIP.\n#    The git source tree only ships `.slaspec` (grammar source) — without\n#    the compiled `.sla` files, the embedded-spec generator finds the\n#    architecture metadata but the decompiler has no grammar to use, so\n#    every disassembly returns `halt_baddata()`. Download the matching\n#    Ghidra release ZIP, extract, and copy:\n#       cp -R ghidra_*_PUBLIC\u002FGhidra\u002FProcessors\u002F*\u002Fdata\u002Flanguages\u002F*.sla \\\n#             \u002Fpath\u002Fto\u002Fghidra-source\u002FGhidra\u002FProcessors\u002F\u003Cproc>\u002Fdata\u002Flanguages\u002F\n#    (one .sla per processor; the ci.yml `Overlay compiled Sleigh .sla`\n#    step has the exact rsync invocation.)\n\n# 3) Configure + build.\ncmake -B build -G \"Visual Studio 17 2022\" \\\n  -DLIBGHIDRA_WITH_LOCAL=ON \\\n  -DGHIDRA_SOURCE_DIR=\u002Fpath\u002Fto\u002Fghidra-source\ncmake --build build --config Release\n```\n\n**Source-build only — `cargo binstall` \u002F `pip install` users skip all\nthis.** The published wheels and Rust prebuilt archives are produced by\nCI with both the patch step and the `.sla` overlay already applied.\n\nIf you re-source the same Ghidra tree after a `.sla` update, delete\n`build\u002Fcpp\u002Fembedded_specs.{cpp,h}` first — `embed_specs.py`'s mtime\nstaleness check trusts source mtimes, and rsync\u002Fcp preserve original\ntimestamps from the release ZIP, so a re-overlay can look \"older\" than\nthe cached output.\n\n### CMake targets\n\n| Target | Alias | What |\n|--------|-------|------|\n| `libghidra_client` | `libghidra::client` | IClient + HTTP backend + protobuf stubs |\n| `libghidra_local` | `libghidra::local` | Adds offline decompiler backend (no Java needed at runtime) |\n\n```cmake\ntarget_link_libraries(app PRIVATE libghidra::client)  # HTTP only\ntarget_link_libraries(app PRIVATE libghidra::local)   # HTTP + offline\n```\n\nInstalled-package consumption is supported too:\n\n```cmake\nfind_package(libghidra CONFIG REQUIRED)\ntarget_link_libraries(app PRIVATE libghidra::client)\n```\n\nAn install exports `libghidra::client` and `libghidra::local`, plus the generated\n`libghidra\u002F*.h` protobuf headers used by the current public C++ API.\n\nDependencies (auto-fetched via FetchContent): protobuf v29.3, cpp-httplib v0.16.3.\n\n## Offline \u002F Local Backend\n\nThe local backend embeds Ghidra's Sleigh decompiler engine directly -- no Java, no network, no running Ghidra instance. Processor specs are embedded at build time; at runtime it's fully self-contained.\n\n```cpp\n#include \"libghidra\u002Fghidra.hpp\"\n\nghidra::LocalOptions opts;\nopts.pool_size = 4;  \u002F\u002F parallel decompilation (default: 1)\nauto client = ghidra::local(opts);\n\nghidra::OpenRequest req;\nreq.program_path = \"\u002Fpath\u002Fto\u002Fbinary.exe\";\nreq.language_id = \"x86:LE:64:default\";  \u002F\u002F optional; Python LocalClient can auto-detect\nclient->OpenProgram(req);\n\nauto decomp = client->GetDecompilation(0x140001000, 30000);\nif (decomp.ok())\n    printf(\"%s\\n\", decomp.value->decompilation->pseudocode.c_str());\n```\n\nSee [`cpp\u002Fexamples\u002F`](cpp\u002Fexamples\u002F) for complete examples covering HTTP, headless, and local backends (memory, disassembly, comments, data items, symbols, types, structs, enums, signatures, CFG, session management, parallel headless analysis, and a complete headless cookbook).\n\nFor the full method-by-method reference, see the [C++ LocalClient API Reference](cpp\u002FREADME.md).\n\n## Architecture\n\n```\nIClient (composite interface, 88 domain methods)\n  |-- HttpClient   --> POST \u002Frpc (protobuf) --> libghidra host (Java, live Ghidra)\n  |-- LocalClient  --> standalone C++ decompiler engine (offline, no Java)\n```\n\nTwo backends, one interface. Every call returns `StatusOr\u003CT>` -- check `.ok()`, then use `.value`.\n\n| | **Remote** (HttpClient) | **Local** (LocalClient) |\n|---|---|---|\n| Runtime | Ghidra JVM + extension | None |\n| Capabilities | Live host API (read + write) | Offline subset: decompiler, functions, symbols, types, memory, listing, xrefs |\n| Use case | GUI automation, live analysis, writes | Offline batch decompilation, CI, tooling |\n\n## Directory Structure\n\n```\nlibghidra\u002F\n  proto\u002F                  Protobuf service contracts (source of truth)\n  cpp\u002F                    C++ SDK (two CMake targets from one directory)\n    include\u002Flibghidra\u002F    Public headers\n    src\u002F                  HTTP + local backend + decompiler engine\n    generated\u002F            Pre-generated protobuf stubs\n    examples\u002F             Complete examples (HTTP + local)\n  python\u002F                 Python SDK\n  rust\u002F                   Rust SDK\n  ghidra-extension\u002F       Java extension project (installed as `LibGhidraHost`)\n```\n\n## SDK Status\n\n| SDK | Status | Notes |\n|-----|--------|-------|\n| **C++ (HttpClient)** | Available | Broad live-host API coverage |\n| **C++ (LocalClient)** | Available | Offline subset; see [cpp\u002F](cpp\u002F) for supported and unsupported methods |\n| **Python** | Available | Sync + async HTTP, typed models, and CLI tooling. See [python\u002F](python\u002F) and [API Reference](python\u002Fdocs\u002Fapi_reference.md) |\n| **Rust** | Available | Sync HTTP client, typed models, and pagination helpers. See [rust\u002F](rust\u002F) and [API Reference](rust\u002Fdocs\u002Fapi_reference.md) |\n\n## Known Limitations\n\n- Method names and data models may still change before a compatibility promise.\n- The current public C++ API still exposes generated protobuf headers under `libghidra\u002F*`.\n- Structured local-variable mutation is supported, but callers should use the canonical `local_id`\n  returned by the API instead of guessing display-style names.\n- The primary validation path is the live host plus headless integration coverage; more expansive\n  clean-room packaging and installer coverage is still release hardening work.\n\n### Local backend (`LocalClient`) caveats\n\n- **Enumeration methods are out of scope in local mode.** `IClient` is the shared API across\n  two backends. `HttpClient` talks to a running Ghidra instance whose analysis pass populates a\n  full function\u002Fxref\u002Fstring database — `list_functions()`, `list_basic_blocks(addr)`,\n  `list_cfg_edges(addr)`, `list_xrefs(start, end)`, and `list_defined_strings()` work as you\n  would expect there. `LocalClient` wraps the standalone C++ decompiler engine, which does not\n  run an analysis pass; those same enumeration methods always return empty by design. Local\n  mode is for **address-driven** queries — `get_decompilation(addr)`,\n  `list_instructions(start, end)`, `read_bytes(addr, n)`, `rename_function(addr, name)`, and\n  the rest of the per-address API work as documented. If you need enumeration of everything in\n  the analyzed program, route through `HttpClient` against a Ghidra host.\n- **No macOS x86_64 \u002F Windows arm64 wheel** in the matrix — both fell out due to GitHub Actions\n  runner availability (macos-13 saturation) and `actions\u002Fsetup-python` not yet shipping arm64\n  Python for `windows-11-arm`. Both gaps will be revisited; in the meantime users on those\n  platforms can `pip install` the pure-Python wheel from the release ZIP for the HTTP client.\n- **After upgrading the wheel, clear the spec cache once.** The native module decompresses\n  Ghidra's Sleigh data into `~\u002F.ghidracpp\u002Fcache\u002Fsleigh\u002F\u003Ckey>\u002F` on first use; the key is now a\n  content hash of the embedded specs (rc8+), so an upgrade picks up new data automatically.\n  Older rc wheels (rc1–rc7) hashed the host process binary's mtime instead and could leave a\n  stale cache. If you upgraded from one of those, run `rm -rf ~\u002F.ghidracpp` once.\n\n## Proto Contracts\n\nTyped RPCs across 9 domain service areas, defined in [`proto\u002Flibghidra\u002F`](proto\u002Flibghidra\u002F). The current contracts define 88 domain RPCs plus one transport RPC. Transport is binary protobuf over `POST \u002Frpc` (not gRPC). See [proto\u002FREADME.md](proto\u002FREADME.md).\n\n## License\n\nThis project is licensed under the [Mozilla Public License 2.0](LICENSE).\n","libghidra 是一个用于通过 Python、Rust 和 C++ 自动化 Ghidra 的 SDK，支持反编译、重命名、注释、检查符号\u002F类型\u002F交叉引用以及项目生命周期管理。其核心功能包括提供类型安全的 API 访问 Ghidra 程序数据库，允许用户查询函数、类型、内存和反编译输出等信息，无需直接接触 Java 代码。该项目特别适合需要将 Ghidra 集成到自动化工作流中的场景，如大规模软件分析、逆向工程任务或开发自定义工具。当前版本为 0.0.3 alpha，API 已经可用但仍在发展中。","2026-06-11 03:52:46","CREATED_QUERY"]