Python client for the libghidra typed RPC layer. Communicates with a
running LibGhidraHost extension via binary protobuf over POST /rpc.
Includes both sync (requests) and async (aiohttp) variants.
Looking for the Rust client? The companion crate at
rust/ships the same dual-mode story (live+local) in one package.cargo add libghidrais the Rust equivalent ofpip install libghidra. Seerust/README.md.
Just want a working wheel? Pre-built per-platform wheels (Linux x86_64 / aarch64, macOS arm64, Windows x64) are attached to every GitHub Release. The top-level README has the per-platform
pip install <release-url>commands. The instructions below are for editable installs from a clone (contributors).
pip install -e libghidra/python # sync only
pip install -e "libghidra/python[async]" # sync + async
pip install -e "libghidra/python[cli]" # adds CLI binary helpers
pip install -e "libghidra/python[local]" # local ELF/PE/Mach-O detection helpers
pip install -e "libghidra/python[async,cli]"Requires Python 3.12+ and a running LibGhidraHost instance (for the
HTTP/RPC client; the local extra plus a built native wheel let you
skip the host entirely).
The local extra is only needed for offline/native workflows; HTTP-only
installs do not pull in binary parser packages.
import libghidra as ghidra
client = ghidra.connect("http://127.0.0.1:18080")
# Check host health
status = client.get_status()
print(f"Connected: {status.service_name} v{status.service_version}")
# Open a program
resp = client.open_program(ghidra.OpenProgramRequest(
project_path="C:/ghidra_projects",
project_name="MyProject",
program_path="binary.exe",
analyze=True,
))
print(f"Opened: {resp.program_name}")
# List functions
funcs = client.list_functions(limit=10)
for f in funcs.functions:
print(f" {f.name} @ 0x{f.entry_address:x}")
# Decompile
dec = client.get_decompilation(funcs.functions[0].entry_address)
print(dec.decompilation.pseudocode)
# Clean up
client.close_program()Live/headless hosts expose Ghidra project contents separately from the active program. A project can contain many programs, while the normal query/mutation methods operate on exactly one active program. Import and analyze with Ghidra, open one project program, query it, close it, then open the next.
import libghidra as ghidra
with ghidra.launch_headless_project(ghidra.HeadlessProjectOptions(
ghidra_dir="C:/ghidra_dist/ghidra_12.1_DEV",
project_dir="C:/work/projects",
project_name="firmware",
)) as host:
loader = host.import_program(ghidra.ImportProgramRequest(
source_path="C:/samples/loader.elf",
overwrite=True,
analyze=True,
))
host.import_program(ghidra.ImportProgramRequest(
source_path="C:/samples/payload.elf",
overwrite=True,
analyze=True,
))
host.open_program(ghidra.OpenProgramRequest(
project_path="C:/work/projects",
project_name="firmware",
program_path=loader.primary_program_path,
))
files = host.list_project_files(ghidra.ListProjectFilesRequest(programs_only=True))
for item in files.files:
print(item.path)
host.close_program(ghidra.ShutdownPolicy.SAVE)
host.open_program(ghidra.OpenProgramRequest(
project_path="C:/work/projects",
project_name="firmware",
program_path="/payload.elf",
))Use absolute Ghidra domain paths (/folder/name) for project programs. Closing
the host with save enabled persists the project; a later Python, C++, Rust, GUI,
or ghidrasql session can reopen the project and select saved programs by domain
path. See examples/project_files.py for a compact
listing/switching example and
examples/multi_program_strings.py for a
variadic live example that imports multiple binaries, counts strings, saves, and
shuts headless down.
import asyncio
from libghidra.async_client import AsyncGhidraClient
from libghidra import ConnectOptions
async def main():
async with AsyncGhidraClient(ConnectOptions()) as client:
status = await client.get_status()
funcs = await client.list_functions(limit=5)
for f in funcs.functions:
print(f"{f.name} @ 0x{f.entry_address:x}")
asyncio.run(main())The package installs a libghidra command for quick checks and shell-friendly
workflows. Connected commands talk to a running LibGhidraHost:
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 0x140001000The CLI also includes small offline binary helpers:
libghidra info sample.exe --sections --imports
libghidra strings sample.exe --min-length 6
libghidra disasm sample.exe entry --count 30If the native local backend is available, functions and decompile can run
without a Ghidra host:
libghidra functions --local sample.exe
libghidra decompile --local sample.exe 0x401000LocalClient auto-detects ELF, PE, Mach-O, and raw data inputs. You can still
pass language_id explicitly on OpenProgramRequest for unusual targets.
Use --format json or --format csv on supported commands for scripting.
- Broad sync API coverage across the host service areas
- Async client coverage for the core read/write, decompiler, listing, memory, session, symbols, xrefs, and type flows
- Binary protobuf transport (same as C++ and Rust clients)
libghidracommand for status checks, function listing, decompilation, binary info, strings, and disassembly- Retry with exponential backoff and jitter
- Typed dataclass models (decoupled from protobuf)
- Semantic error codes matching the RPC protocol
- Async context manager support (
async with)
See examples/ for the full set of Python scripts.
| Example | Coverage |
|---|---|
quickstart.py |
Connect, list functions, decompile one |
explore_binary.py |
Survey all areas (memory, types, xrefs, strings) |
annotate_and_export.py |
Create types, rename functions, batch decompile |
memory_ops.py |
Memory blocks, read/write/patch bytes |
disassemble.py |
Instructions and disassembly listing |
comments.py |
Comment CRUD (EOL, PRE, POST, PLATE, REPEATABLE) |
data_items.py |
Apply data types, rename/delete data items |
symbols.py |
Symbol query, rename, delete |
type_system.py |
Type overview: structs, aliases, enums, unions |
struct_builder.py |
Struct member add/rename/retype/delete |
enum_builder.py |
Enum member add/rename/revalue/delete |
function_signatures.py |
Signatures, parameter mutation, prototype override |
cfg_analysis.py |
Basic blocks and CFG edges |
session_lifecycle.py |
Status, capabilities, revision, save/discard |
project_files.py |
List project programs and switch active program |
multi_program_strings.py |
Import/analyze multiple binaries, count strings per program, save project |
async_explore.py |
AsyncGhidraClient with asyncio |
decompile_tokens.py |
Pseudocode token records and local metadata |
end_to_end.py |
Launch headless Ghidra, analyze, enumerate functions/blocks/decompilation, save, shutdown |
function_tags.py |
Function tag CRUD and mappings |
parse_declarations.py |
Parse C declarations into data types |
structural_analysis.py |
Switch tables, dominators, post-dominators, and loops |
For the full method-by-method reference, see the API Reference.
This table describes the synchronous client. The async client mirrors the core host operations but does not expose every newer helper method yet.
| Area | Methods |
|---|---|
| Health | get_status, get_capabilities |
| Session | open_project, close_project, list_project_files, import_program, open_program, close_program, save_program, discard_program, get_revision, shutdown |
| Memory | read_bytes, write_bytes, patch_bytes_batch, list_memory_blocks |
| Functions | get_function, list_functions, rename_function, list_basic_blocks, list_cfg_edges, list_switch_tables, list_dominators, list_post_dominators, list_loops, list_function_tags, create_function_tag, delete_function_tag, list_function_tag_mappings, tag_function, untag_function |
| Symbols | get_symbol, list_symbols, rename_symbol, delete_symbol |
| Xrefs | list_xrefs |
| Types | get_type, list_types, list_type_aliases, list_type_unions, list_type_enums, list_type_enum_members, list_type_members, get_function_signature, list_function_signatures, set_function_signature, rename_function_parameter, set_function_parameter_type, rename_function_local, set_function_local_type, apply_data_type, create_type, delete_type, rename_type, create_type_alias, delete_type_alias, set_type_alias_target, create_type_enum, delete_type_enum, add_type_enum_member, delete_type_enum_member, rename_type_enum_member, set_type_enum_member_value, add_type_member, delete_type_member, rename_type_member, set_type_member_type, parse_declarations |
| Decompiler | get_decompilation, list_decompilations |
| Listing | get_instruction, list_instructions, get_comments, set_comment, delete_comment, rename_data_item, delete_data_item, list_data_items, list_bookmarks, add_bookmark, delete_bookmark, list_breakpoints, add_breakpoint, set_breakpoint_enabled, set_breakpoint_kind, set_breakpoint_size, set_breakpoint_condition, set_breakpoint_group, delete_breakpoint, list_defined_strings |