1.3 headless与PyGhidra


1.3 headless与PyGhidra

本节摘要:图形界面精读好用,批量无力。本节把 1.1 与 1.2 节的动作变成脚本。第一部分给三个必须无头的场景:样本批量、CI 流水线、无人值守。第二部分上手 analyzeHeadless:一条命令完成导入、分析、跑脚本、清理工程,参数逐个拆解。第三部分写第一个 Ghidra 脚本 export_functions.py,遍历函数管理器,把函数名、入口、大小导出成 JSON——这就是后续所有 AI 工具流的「备料」格式。第四部分换 PyGhidra:在普通 Python 里 start 后 open_program,把 Ghidra 当库用,适合与 pandas、模型调用同进程组合。最后划定边界:哪些事仍该回 GUI 做。

学习目标

  • 说出无头模式的三个典型场景。
  • 独立写出 analyzeHeadless 命令并解释 -import、-postScript、-scriptPath 的作用。
  • 编写并运行导出函数清单 JSON 的 Ghidra 脚本。
  • 用 PyGhidra 在 Python 里完成打开、分析、遍历函数三件事。
  • 判断一个任务该用 GUI、analyzeHeadless 还是 PyGhidra。

一、为什么要无头:三个场景

场景 痛点 无头方案
样本批量初筛:一百个待分析二进制 逐个双击导入要一天 analyzeHeadless 循环跑目录
流水线集成:新样本入库即自动出函数清单 人工触发不可持续 CI 任务定时执行脚本
无人值守:服务器上没有图形界面 GUI 根本起不来 命令行 + 脚本

无头模式复用的是同一套分析引擎与脚本接口——GUI 里能拿到的程序对象,脚本里一样拿得到。

二、analyzeHeadless:最小批处理

analyzeHeadless 是 Ghidra 自带的命令行入口,位于发行包 support 目录。最小可用命令:

# bash —— analyzeHeadless 单文件分析并导出(写法示意,以官方文档为准) GHIDRA=/opt/ghidra_12.1.4_PUBLIC "$GHIDRA/support/analyzeHeadless" /path/to/re-lab/ghidra_proj ReLab \ -import bin/demo_stripped \ -scriptPath scripts \ -postScript export_functions.py \ -deleteProject ​
参数 作用
ghidra_proj ReLab 工程目录与工程名
-import 文件 导入并自动分析该二进制
-scriptPath 目录 脚本搜索路径
-postScript 脚本 分析完成后执行(脚本里可带参数)
-deleteProject 用后即焚,不留工程残骸(需要留工程复看时去掉)

一个容易忽略的点:-import 每次都新建程序,重跑会重名冲突;批处理常用「先 -import 初次建库、再 -process 复用已有库」的两段式,参数细节以官方文档为准。

三、第一个脚本:导出函数清单 JSON

Ghidra 脚本运行在有上下文的环境里:currentProgram 直接就是当前程序对象。新建 scripts/export_functions.py:

# export_functions.py —— Ghidra 脚本:导出函数清单 JSON(API 以官方文档为准) import json OUT = "out/functions.json" rows = [] fm = currentProgram.getFunctionManager() for func in fm.getFunctions(True): rows.append({ "name": func.getName(), "entry": str(func.getEntryPoint()), "size": func.getBody().getNumAddresses(), }) with open(OUT, "w", encoding="utf-8") as fh: json.dump({"program": str(currentProgram.getName()), "functions": rows}, fh, ensure_ascii=False, indent=2) print("exported %d functions -> %s" % (len(rows), OUT)) ​

对 demo_stripped 跑完后,out/functions.json 形如:

# out/functions.json —— 导出结果示例(节选,示意) { "program": "demo_stripped", "functions": [ {"name": "FUN_00401160", "entry": "00401160", "size": 83}, {"name": "FUN_00401189", "entry": "00401189", "size": 76} ] } ​

这份 JSON 是全书的「通用货币」:第 02 章 r2pipe 导出同构数据,第 03 章模型列函数走同一条路,第 04 章的 RAG 索引以它为输入。把结构定稳定(name、entry、size),后面每章都省事。

四、PyGhidra:把 Ghidra 当 Python 库

analyzeHeadless 的脚本是「分析完成后被动执行」;PyGhidra(Ghidra 官方 Python 支持,随发行版提供,安装方式以官方文档为准)则让你在普通 Python 里主动驱动:

# bash —— PyGhidra 环境准备(写法示意,以官方文档为准) cd /opt/ghidra_12.1.4_PUBLIC ./support/pyghidraRun # 带界面的 Python 控制台 # 库模式使用:按官方文档安装附带的 pyghidra 包后,在任意虚拟环境 import ​
# pyghidra_demo.py —— 库模式:Python 主动打开并遍历函数(API 以官方文档为准) import pyghidra pyghidra.start() with pyghidra.open_program("bin/demo_stripped", analyze=True) as api: program = api.getCurrentProgram() fm = program.getFunctionManager() funcs = list(fm.getFunctions(True)) print("program:", program.getName()) print("functions:", len(funcs)) for func in funcs[:5]: print(func.getName(), func.getEntryPoint()) ​

库模式的价值在于「同进程组合」:函数清单可以直接进 pandas 统计、直接喂模型、直接写数据库,没有中间文件。第 03 章 GhidraMCP 的 headless 支持正是建立在 PyGhidra 上(要求 Python 3.10~3.13)。

两种方式的关系:analyzeHeadless 适合「一条命令跑完就退」的批处理;PyGhidra 适合「分析只是长流程中的一步」的编排。底层是同一套 API,脚本可平滑迁移。

五、边界与坑:什么时候回到 GUI

任务 推荐方式 原因
单个程序精读、手工重命名 GUI 交互反馈快,理解需要眼睛
批量导清单、批量初筛 analyzeHeadless 无人值守,循环友好
与模型 / 数据处理同流程 PyGhidra 同进程无中间态
大样本分析卡死 headless 分段 可控超时与重试

三个常见坑:其一,脚本里的路径是「Ghidra 进程的当前目录」,批处理前先统一工作目录;其二,-deleteProject 与「想保留重命名成果」冲突——要落库就不要删工程;其三,Python 版本:PyGhidra 相关链路对 Python 3.10~3.13 有要求,虚拟环境里先核对版本。

本节要点回顾

  • 无头三场景:批量、流水线、无人值守;与 GUI 共用同一套引擎与脚本接口。
  • analyzeHeadless 五个关键参数:工程、导入、脚本路径、后置脚本、清理。
  • export_functions.py 定下全书通用备料格式:name、entry、size 的 JSON。
  • PyGhidra 库模式让分析与模型调用同进程,GhidraMCP 的 headless 就建在它上面。
  • 选型:精读回 GUI,批处理走 headless,编排用 PyGhidra。

至此,Ghidra 地基完工:能装、能读、能脚本化导出。下一章换一件更轻的武器——radare2,看命令行哲学如何把同样的活儿干出「管道」的味道。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U