关于 ghidra-cli
ghidra-cli 是用于 Ghidra 二进制逆向分析的 Rust 命令行工具。它可导入并分析程序,再通过持久运行的 Java 桥接服务检查和修改程序数据。
主要功能
- 01导入并分析二进制文件
- 02反编译和反汇编函数
- 03搜索字符串、字节和函数
- 04管理符号、类型和标签
- 05检查引用和调用图
- 06修补字节并导出程序
适用场景
- 01分析导入的可执行文件
- 02追踪函数的调用和引用
- 03使用标签整理函数
- 04修补指令并导出程序
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ akiselev/ ghidra-cli --skill ghidra-cli安装后在 Claude Code 中输入/ghidra-cli确认已加载。
详细介绍
ghidra-cli Agent 参考
用于 Ghidra 逆向工程的 Rust 命令行工具。二进制文件名:ghidra。
架构
CLI (Rust/clap) ──TCP──► GhidraCliBridge.java (GhidraScript in Ghidra JVM)
- 直接桥接:没有守护进程。Java 桥接本身就是持久服务。
- 每个项目对应一个桥接,键为
~/.local/share/ghidra-cli/bridge-{md5}.port - 如果桥接未运行,导入、分析和查询命令会自动启动桥接
- 按顺序处理命令(Ghidra API 不是线程安全的)
全局标志
| 标志 | 作用 |
|---|---|
--json | 紧凑 JSON 输出(单行) |
--pretty | 美化 JSON 输出 |
--project P / --program PROG | 目标项目/程序;为全局标志,因此可以放在子命令之前 |
--projects-dir DIR | Ghidra 项目的存储位置(覆盖 ghidra_project_dir) |
--java-home PATH | Ghidra 使用的完整 JDK 路径(覆盖自动检测) |
-v / -vv / -vvv | 日志详细程度:警告 / 信息 / 调试 |
-q / --quiet | 禁止输出非必要的 stderr 信息 |
所有标志都是全局的,因此 ghidra --project P --program bin function list 与将它们放在子命令之后的效果相同。
格式自动检测:TTY → 紧凑易读格式;管道 → json-compact。可使用 --json、--pretty 或 -o FORMAT 覆盖。
Ghidra 12.1+ 不接受路径中包含点号开头的组件的项目目录(例如 ~/.cache);在 Linux 上,默认路径会回退到 ~/ghidra-cli-projects。使用 --projects-dir 可覆盖此设置。
快速开始
# Fastest path: import runs auto-analysis automatically; bridge starts on demand
ghidra import ./binary --project myproject
# All subsequent queries reuse the running bridge
ghidra function list --project myproject
ghidra decompile main --project myproject
命令参考
桥接生命周期
ghidra start [--project P] [--program PROG]
ghidra stop [--project P]
ghidra restart [--project P] [--program PROG]
ghidra status [--project P]
ghidra ping [--project P]
ghidra jobs [JOB_ID] [--project P] # bridge queue + recent jobs, or one job by ID
ghidra cancel [JOB_ID] [--project P] # cooperatively cancel active (or given) job
ping、status、jobs 和 cancel 会立即通过控制平面响应。程序作业按通道运行:read(开销较低的读取,可并发)、read-heavy(反编译/查找/图/统计/script run --read-only,可并发,但数量上限为池大小 − 1)以及 exclusive(写入、打开/关闭、分析、导入、普通 script run)。ghidra jobs 会显示每个作业的 lane、queue_position 和 blocked_by,以及 abandoned 作业(客户端已断开连接;已跳过或取消)。读取池大小由 GHIDRA_CLI_READ_THREADS 设置(默认值为 min(8, cores/2),0 = 全部使用 exclusive 通道)。CLI 不会自动重启桥接;如果桥接版本早于 CLI,请在没有其他客户端使用它时运行 ghidra restart。
项目管理
ghidra project create NAME
ghidra project list
ghidra project info [NAME]
ghidra project delete NAME
导入与分析
ghidra import BINARY [--project P] [--program PROG] [--no-analyze] [--detach]
ghidra analyze [--project P] [--program PROG] [--detach]
这两类命令都会自动启动桥接。ghidra import 默认会运行自动分析(并
持久化程序);传入 --no-analyze 可在不进行分析的情况下直接导入。
--detach 会立即返回。
程序管理
ghidra program list [--project P] # alias: prog, programs
ghidra program open --program PROG [--project P] # --program required by runtime
ghidra program close [--project P]
ghidra program delete --program PROG [--project P]
ghidra program info [--project P]
ghidra program export FORMAT [--project P] [-o OUTPUT] # FORMAT: json, xml, c/cpp, binary/bin, gzf, ascii/asm, hex, html
函数操作
ghidra function list [QUERY_OPTS] # aliases: fn, func, functions
ghidra function get TARGET [QUERY_OPTS] # TARGET = name or 0xADDRESS
ghidra function decompile TARGET [--with-vars] [--with-params] [QUERY_OPTS]
ghidra function disasm TARGET [QUERY_OPTS] # whole body; --limit N (default 1000, 0 = all); truncation warned on stderr
ghidra function calls TARGET [QUERY_OPTS] # outgoing calls
ghidra function xrefs TARGET [QUERY_OPTS] # incoming references
ghidra function rename OLD NEW [--project P] [--program PROG]
ghidra function create ADDRESS [NAME] [--project P] [--program PROG]
ghidra function delete TARGET [QUERY_OPTS]
ghidra function set-signature TARGET --signature "int foo(int x, char *y)" [--project P] [--program PROG]
ghidra function set-return-type TARGET --type TYPE [--project P] [--program PROG]
ghidra function set-calling-convention TARGET --convention CC [--project P] [--program PROG]
ghidra function set-var-type TARGET --var VARNAME --type TYPE [--project P] [--program PROG]
顶层快捷命令
ghidra decompile TARGET [--with-vars] [--with-params] [QUERY_OPTS] # aliases: decomp, dec
ghidra disasm TARGET [-n COUNT] [QUERY_OPTS] # TARGET = name or 0xADDRESS; aliases: disassemble, dis
--with-vars 会在响应中包含局部变量详细信息(名称、类型、存储位置)。
--with-params 会在响应中包含参数详细信息(名称、类型、存储位置)。
这两个标志都会在反编译后的 C 代码旁附带结构化数据;使用 --json 查看完整输出。
字符串操作
ghidra strings list [QUERY_OPTS] # aliases: string, str
ghidra strings refs STRING [QUERY_OPTS] # xrefs to string
符号操作
ghidra symbol list [QUERY_OPTS] # aliases: sym, symbols
ghidra symbol get NAME [QUERY_OPTS]
ghidra symbol create ADDRESS NAME [--project P] [--program PROG]
ghidra symbol delete NAME [QUERY_OPTS]
ghidra symbol rename OLD NEW [--project P] [--program PROG]
内存操作
ghidra memory map [QUERY_OPTS] # alias: mem
ghidra memory read ADDRESS SIZE [QUERY_OPTS]
ghidra memory write ADDRESS BYTES [--project P] [--program PROG]
ghidra memory search PATTERN [QUERY_OPTS]
交叉引用
ghidra x-ref to ADDRESS [QUERY_OPTS] # aliases: xref, xrefs, crossref
ghidra x-ref from ADDRESS [QUERY_OPTS]
ghidra x-ref list TARGET [QUERY_OPTS] # refs both to and from the target
x-ref list 接受一个目标(名称、0xADDR 或 FUN_<hex>),并返回两个方向的引用。如果目标是函数,“from”一侧会扫描整个函数体,而不仅仅是函数入口。
类型操作
ghidra type list [QUERY_OPTS] # alias: types (includes "kind" field: struct/union/enum/typedef/pointer/array/other)
ghidra type get NAME [QUERY_OPTS] # shows struct fields, enum members, typedef base type, kind
ghidra type create DEFINITION [--project P] [--program PROG] # create empty struct
ghidra type apply ADDRESS TYPE_NAME [--project P] [--program PROG]
ghidra type delete NAME [--project P] [--program PROG] # alias: rm
ghidra type rename OLD NEW [--project P] [--program PROG] # alias: mv
ghidra type create-enum NAME --values "A=0,B=1,C=2" [--size 4] [--project P] [--program PROG]
ghidra type typedef NAME BASE_TYPE [--project P] [--program PROG] # create type alias
ghidra type add-field STRUCT_NAME --name FIELD --type TYPE [--offset N] [--size N] [--project P] [--program PROG]
ghidra type del-field STRUCT_NAME --name FIELD [--project P] [--program PROG]
标签操作
函数标签用于组织大型代码库:带名称、作用于程序级别的标签,可附带注释,并可添加到任意数量的函数上。
ghidra tag list [--function TARGET] [QUERY_OPTS] # alias: tags — all tags (name, comment, use_count), or one function's tags
ghidra tag get NAME [QUERY_OPTS] # alias: show — member functions of a tag (rows: name, address)
ghidra tag create NAME [--comment TEXT] [--project P] [--program PROG]
ghidra tag delete NAME [--project P] [--program PROG] # alias: rm — detaches from ALL functions; reports use_count + functions_affected
ghidra tag rename OLD NEW [--project P] [--program PROG] # alias: mv — global; errors if NEW exists (no implicit merge)
ghidra tag set-comment NAME COMMENT [--project P] [--program PROG] # "" clears
ghidra tag add TARGET TAG... [--no-create] [--project P] [--program PROG] # auto-creates missing tags; reports added/created/already_present
ghidra tag remove TARGET TAG... [--project P] [--program PROG] # reports removed/not_present; idempotent
ghidra tag remove TARGET --all [--project P] [--program PROG] # detach every tag
ghidra function list --tag NAME [--tag NAME2] [QUERY_OPTS] # server-side filter; multiple --tag = AND
ghidra function list --untagged [QUERY_OPTS] # functions with no tags (triage complement)
Agent 应了解的语义:
- 标签名称区分大小写(
Crypto≠crypto)。未知标签错误会包含Did you mean ...?提示,并以非零状态退出——在尝试性循环中,请先检查ghidra tag list(或使用--filter)。--filter无匹配项时会以 0 状态退出并返回空输出;未知的--tag会以非零状态退出。 tag add/remove是幂等操作:已附加/不存在的标签会在响应中说明,不会报错——可以安全重试。- 函数行(
function list/get)包含排序后的tags数组(即使为空也会提供),因此--fields name,address,tags和--filter "tags ~ 'crypto'"均可使用。DSL 中的~/^/$/=~/in对标签执行不区分大小写的匹配;=/!=则执行精确匹配。在 CSV 输出中,标签数组以;连接。 - 标签名称不能为空,也不能包含
,或;(创建时会拒绝;在 Ghidra GUI 中创建的特殊名称仍可附加、移除或删除)。 - 标签名称可以包含空格,但不能用于
ghidra batch文件(使用空白字符分词,不支持引号)。 - 标签成员操作不处理外部函数:在 Ghidra GUI 中应用于外部函数的标签,可能会使
tag list中的use_count高于tag get的成员数量。
典型的 Agent 工作流:
# Define a taxonomy (comments document meaning for future sessions)
ghidra tag create crypto --comment "Key schedule, cipher rounds, RNG"
ghidra tag create reviewed --comment "Decompiled and understood"
# Triage and tag
ghidra tag add FUN_00401a20 crypto
ghidra tag add aes_key_expand crypto reviewed
# Bulk via batch (one process, one bridge connection; bare tag names only)
printf 'tag add FUN_00402000 network\ntag add parse_packet network reviewed\n' > triage.batch
ghidra batch triage.batch
# Drive the next pass off the taxonomy
ghidra tag list # names, comments, use counts
ghidra tag get network # member functions (rows)
ghidra function list --tag network --filter "size > 200" --fields name,address,tags
ghidra function list --untagged --limit 20 # what's left to triage
ghidra tag remove parse_packet wip
注释操作
ghidra comment list [QUERY_OPTS] # alias: comments
ghidra comment get ADDRESS [QUERY_OPTS]
ghidra comment set ADDRESS TEXT [--comment-type TYPE] [--project P] [--program PROG]
ghidra comment delete ADDRESS [QUERY_OPTS]
--comment-type 接受 EOL(默认值)、PRE、POST 或 PLATE。
搜索/查找
ghidra find string PATTERN [QUERY_OPTS] # alias: search
ghidra find bytes HEX [QUERY_OPTS]
ghidra find function PATTERN [QUERY_OPTS] # glob patterns
ghidra find calls FUNCTION [QUERY_OPTS]
ghidra find crypto [QUERY_OPTS] # detect AES/SHA/RSA constants
ghidra find interesting [QUERY_OPTS] # suspicious patterns
图/调用图
ghidra graph calls [QUERY_OPTS] # aliases: callgraph, cg
ghidra graph callers FUNCTION [--depth N] [QUERY_OPTS]
ghidra graph callees FUNCTION [--depth N] [QUERY_OPTS]
ghidra graph export FORMAT [QUERY_OPTS] # FORMAT: dot, json
差异
ghidra diff programs PROG1 PROG2 [--project P] [--format F]
ghidra diff functions FUNC1 FUNC2 [--project P] [--format F]
转储/导出
ghidra dump imports [QUERY_OPTS] # alias: export
ghidra dump exports [QUERY_OPTS]
ghidra dump functions [QUERY_OPTS]
ghidra dump strings [QUERY_OPTS]
补丁
ghidra patch bytes ADDRESS HEX [--project P] [--program PROG]
ghidra patch nop ADDRESS [--count N] [--project P] [--program PROG]
ghidra patch export -o OUTPUT [--project P] [--program PROG]
--count N 会从 ADDRESS 开始,逐条指令遍历,将连续的 N 条指令替换为 NOP(默认值为 1)。如果遍历范围内有任何地址没有指令,整个补丁都会回滚。
脚本执行
ghidra script run PATH [--read-only] [--expect PATH[:MIN_ROWS]]... [--allow-empty] [--project P] [--program PROG] [-- ARGS...]
ghidra script python CODE # NOT supported in bridge mode; use script run
ghidra script java CODE # NOT supported in bridge mode; use script run
ghidra script list
script run 会将 PATH 解析为绝对路径,并将 -- 后的参数作为实际的位置参数传递给脚本,同时在响应中捕获标准输出({script, path, stdout, args})。--expect PATH[:MIN_ROWS](可重复指定)会在工件缺失、为空或少于 MIN_ROWS 行时使作业失败;--allow-empty 允许预期工件存在但内容为空。脚本会独占运行,并且可取消(ghidra cancel)。--read-only 会使脚本与其他读取操作并发运行;如果程序的修改编号发生变化,脚本就会失败(read_only_violation)。编译错误会以 javac 诊断信息报告(script_compile_error)。
批处理
ghidra batch SCRIPT_FILE [--project P] [--program PROG]
批处理文件:每行一个子命令(不带 ghidra 前缀),支持 # 注释。
通用查询
ghidra query DATA_TYPE [QUERY_OPTS]
DATA_TYPE:functions、strings、imports、exports、memory。
统计与信息
ghidra summary [QUERY_OPTS] # alias: info
ghidra stats [QUERY_OPTS]
配置
ghidra init # create config
ghidra doctor # check installation
ghidra version
ghidra config list
ghidra config get KEY
ghidra config set KEY VALUE # keys: ghidra_install_dir, ghidra_project_dir, default_program, default_project, default_output_format, default_limit, launch_timeout_secs
ghidra config reset
ghidra set-default KIND VALUE # KIND: program, project
ghidra setup [--version V] [--dir D] [--force]
桥接等待控制项通过环境变量设置:普通命令使用
GHIDRA_CLI_READ_TIMEOUT,分析/导入使用
GHIDRA_CLI_OP_TIMEOUT,建立连接使用 GHIDRA_CLI_CONNECT_DEADLINE。加载旧文件时会忽略旧配置键
timeout,而 config set 会拒绝该键。
通用查询选项(QUERY_OPTS)
所有查询命令均接受以下选项:
| 选项 | 说明 |
|---|---|
--project P | 项目名称或路径 |
--program PROG | 项目中的程序 |
--filter EXPR | 过滤表达式 |
--fields LIST | 以逗号分隔的返回字段 |
-o FORMAT | 输出格式 |
--limit N | 最大结果数 |
--offset N | 跳过前 N 项 |
--sort FIELDS | 排序:以逗号分隔,前缀 - 表示降序 |
--count | 仅返回数量 |
--json | --format=json 的简写 |
输出格式
| 值 | 用途 |
|---|---|
compact | TTY 的默认格式。每项一行。 |
full | 多行标注块 |
json | 格式化 JSON |
json-compact | 管道的默认格式。单行 JSON。 |
json-stream / ndjson | 每行一个 JSON 对象 |
csv / tsv | 带表头的分隔格式 |
table | ASCII 方框表格 |
count | 仅显示数量 |
ids / minimal | 仅显示地址/名称,每行一个 |
tree | 缩进层级结构 |
hex | 十六进制转储 |
asm | 汇编代码 |
c | C 伪代码 |
筛选表达式
# Numeric
--filter "size > 100"
--filter "size >= 50"
# String
--filter "name ~ 'crypt'"
# Combined
--filter "size > 100 AND name ~ 'main'"
--filter "name != 'main'"
运算符:=、!=、>、>=、<、<=、~(包含)、^(以……开头)、$(以……结尾)、=~(正则表达式)、AND、OR、NOT、IN、EXISTS。
Agent 最佳实践
1. 先统计模式
获取结果前,始终先检查结果数量:
ghidra function list --count --project P
# If manageable:
ghidra function list --limit 50 --fields name,address,size --project P
2. 积极筛选
在服务端预先筛选,而非在客户端筛选:
# GOOD
ghidra function list --filter "size > 1000" --project P
# BAD
ghidra function list --project P # then filter in agent code
3. 选择字段
只请求所需字段:
ghidra function list --fields name,address --json --project P
4. 设置默认值
避免重复输入 --project 和 --program:
ghidra set-default project myproject
ghidra set-default program mybinary
# Now: ghidra function list (no flags needed)
.NET 警告
当输出看起来像 .NET 托管代码(例如 halt_baddata() 或 .NET CLR Managed Code 标记)时,ghidra decompile 会打印警告:
“这看起来是 .NET 托管代码。Ghidra 无法反编译 .NET IL 字节码。建议使用 .NET 反编译器(例如 ilspy-cli)以获得更好的结果。”
Ghidra 无法为 IL 生成有用的输出。请改用专用的 .NET 反编译器。ilspy-cli 是独立工具,不属于 ghidra-cli。
分析工作流
# 1. Import and analyze
ghidra import ./target.exe --project analysis
ghidra analyze --project analysis
# 2. Recon
ghidra summary --project analysis
ghidra function list --count --project analysis
ghidra function list --filter "NOT name ^ 'FUN_'" --fields name,address,size --limit 30 --project analysis
# 3. Investigate
ghidra decompile main --project analysis
ghidra decompile main --with-vars --with-params --json --project analysis # structured output
ghidra find crypto --project analysis
ghidra find string "password" --project analysis
# 4. Deep dive
ghidra graph callers suspicious_func --depth 3 --project analysis
ghidra x-ref to 0x401000 --project analysis
ghidra function disasm 0x401000 --project analysis
# 5. Type annotation (improves decompile output)
ghidra type create MyStruct --project analysis
ghidra type add-field MyStruct --name fd --type int --project analysis
ghidra type add-field MyStruct --name flags --type uint --project analysis
ghidra type create-enum ErrorCode --values "OK=0,ENOENT=2,EPERM=1" --project analysis
ghidra type typedef HANDLE void --project analysis
ghidra function set-return-type main --type int --project analysis
ghidra function set-signature parse_data --signature "int parse_data(char *buf, int len)" --project analysis
ghidra function set-var-type main --var local_10 --type "MyStruct *" --project analysis
ghidra decompile main --project analysis # re-decompile with new types applied
# 6. Patch
ghidra patch nop 0x401234 --count 3 --project analysis
ghidra patch export -o patched.exe --project analysis
环境变量
| 变量 | 用途 |
|---|---|
GHIDRA_INSTALL_DIR | Ghidra 安装路径 |
GHIDRA_PROJECT_DIR | 项目的基础目录 |
GHIDRA_CLI_JAVA_HOME | Ghidra 使用的完整 JDK(覆盖自动检测) |
GHIDRA_DEFAULT_PROJECT | ghidra query 的默认 --project |
GHIDRA_DEFAULT_PROGRAM | ghidra query 和程序自动选择的默认 --program |
GHIDRA_CLI_CONFIG | 覆盖配置路径 |
GHIDRA_CLI_LAUNCH_TIMEOUT | 桥接程序启动就绪的最长等待时间(默认 180s) |
GHIDRA_CLI_OP_TIMEOUT | 长时间运行的 analyze/import 操作的最长等待时间(默认不设上限) |
GHIDRA_CLI_DECOMPILE_TIMEOUT | Ghidra 端反编译器的时限,单位为秒;0 = 不设上限(默认不设上限) |
GHIDRA_CLI_READ_TIMEOUT | 每个请求的套接字读取超时;0 = 无限等待(默认 300s) |
GHIDRA_CLI_CONNECT_DEADLINE | 连接正在(重新)启动的桥接程序的重试时长(默认 60s) |
GHIDRA_CLI_SHUTDOWN_TIMEOUT | 强制终止前等待任务完成的宽限时间;0 = 无限等待(默认 300s) |
GHIDRA_CLI_READ_THREADS | 桥接程序读取线程池大小,在桥接程序启动时读取;0 = 所有任务均独占(默认 min(8, cores/2),至少为 2) |
文件位置
| 文件 | 用途 |
|---|---|
~/.local/share/ghidra-cli/bridge-{md5}.port | 运行中桥接程序的 TCP 端口 |
~/.local/share/ghidra-cli/bridge-{md5}.pid | 桥接程序进程 PID |
~/.config/ghidra-cli/config.yaml | 配置 |
~/.config/ghidra-cli/scripts/GhidraCliBridge.java | 生成的 Java 桥接脚本 |
~/.local/share/ghidra-cli/ghidra-cli.log | 调试日志 |
错误恢复
| 问题 | 解决方法 |
|---|---|
| “未指定项目” | 添加 --project NAME 或运行 ghidra set-default project NAME |
| “桥接程序未响应” | 运行 ghidra stop --project P,然后重试(会自动启动) |
| “未配置 Ghidra 安装” | 运行 ghidra setup 或设置 GHIDRA_INSTALL_DIR |
| 未找到函数 | 使用 ghidra find function "*pattern*" |
| 首次命令运行缓慢 | 正常:桥接程序启动和分析需要几秒钟 |