# ghidra-cli A small, dependable command-line interface for read-only Ghidra analysis. The repository is named `ghidra-cli`; the installed executable is `ghidr`. Version 0.1 provides a synchronous Rust harness, strict Java headless adapter, content-addressed Analysis Store, Bubblewrap worker sandbox, reproducible native fixtures, and pinned x86-64 Linux Nix packaging. Usage: ```console ghidr doctor ghidr inspect ./sample ghidr functions ./sample --limit 100 ghidr decompile ./sample --name main ghidr clean ./sample --dry-run ``` Each command will identify the sample by its content, reuse compatible cached analysis, and produce versioned JSON by default. Human-readable presentation is available explicitly through `--format human`. Agents can discover the complete command surface without initializing Ghidra: ```console ghidr --help ghidr decompile --help ghidr --version ``` These discovery requests return plain text on stdout with exit status 0 and leave stderr empty. ## Documents - [PRD.md](./PRD.md) defines the product requirements and initial delivery scope. - [CONTEXT.md](./CONTEXT.md) defines the domain language used throughout the project. - [docs/adr/](./docs/adr/) records durable architectural decisions. - [docs/research/](./docs/research/) records cited prior-art investigations, including the Ghidra MCP comparison that informed protocol safeguards and the post-version-0.1 roadmap. ## Pinned package The flake fixes Ghidra at exactly 12.1.2 and uses JDK 21. It also closes over Rust, Bubblewrap, the Java adapter, deterministic Java/Nix formatters, `cargo-deny`, and `statix`: ```console nix run . -- doctor nix develop ``` The native fixtures are reproducible Nix outputs rather than committed opaque binaries: ```console nix build .#fixtures file result/elf-x86_64/known.elf result/pe32plus-x86_64/known.exe ``` ## Adapter boundary The Ghidra worker dispatches `doctor`, `inspect`, `functions`, and `decompile`. `inspect` is the import/analyze vertical slice: the trusted harness stages the Sample and invokes official `analyzeHeadless`; the post-script reads only the current imported Program and private request/response paths. `clean` is in the five-operation Rust registry but is intentionally rejected by Java because it is a trusted, atomic Analysis Store transaction. This boundary is enforced by `tests/adapter_contract.rs` and documented in `java/dispatch.txt`. The adapter accepts at most 1 MiB of request JSON before parsing, rejects missing/unknown fields, echoes protocol version/invocation/operation, and publishes at most 256 MiB through a temporary file plus same-filesystem atomic rename. It has no socket, network client, listener, script execution, mutation, or user-selected destination surface. ## Checks The complete pinned suite is: ```console cargo fmt --all --check cargo clippy --all-targets --all-features -- -D warnings cargo test --all-targets --all-features cargo deny check nix flake check --print-build-logs ``` `nix flake check` compiles Java with JDK 21 `-Xlint:all -Werror`, checks Google-style `clang-format`, `nixfmt`, and `statix`, builds both fixtures, runs the adapter against real Ghidra 12.1.2, and exercises `inspect`, `functions`, and `decompile` through the packaged `ghidr` path. Individual real-engine checks remain directly runnable as: ```console nix build .#checks.x86_64-linux.java-adapter-e2e --print-build-logs nix build .#checks.x86_64-linux.real-ghidra-e2e --print-build-logs ``` ## License Licensed under the [Apache License 2.0](./LICENSE). Development may use AI assistance. Maintainers remain responsible for reviewing the resulting design and code, verifying provenance, testing behavior, and ensuring dependency-license compatibility.