3、Ghidra脚本入门:Python脚本基础、Ghidra Python API概览、第一个自动化脚本
说实话,很多人一听到「脚本」两个字就头大。觉得那是程序员才该碰的东西。我刚开始用Ghidra时也一样,点鼠标点得不亦乐乎。直到有一次,我需要分析一个固件里两百多个相似函数……嗯,从那以后,我老老实实学了脚本。
这一章,我们就来搞定Ghidra的Python脚本。别怕,真的不难。
3.1 Python脚本基础——你其实已经会了
Ghidra内置了Jython,也就是Java版的Python解释器。语法和标准Python几乎一样。你不需要精通Python,掌握下面几个就够了:
- 变量和类型:字符串、整数、列表、字典
- 条件判断:if / elif / else
- 循环:for 和 while
- 函数定义:def 关键字
举个例子,你在Ghidra里写脚本,经常要遍历函数列表。代码长这样:
# 获取当前程序的所有函数
functions = currentProgram.getFunctionManager().getFunctions(True)
for func in functions:
name = func.getName()
print("函数名: " + name)
你看,就是普通的Python循环。只不过currentProgram是Ghidra给你的一个「魔法变量」,代表当前打开的程序。
print("脚本开始")。不是炫技,是方便定位问题。脚本跑崩了,至少知道崩在哪一步。
3.2 Ghidra Python API概览——你只需要记住这几个
Ghidra的API很庞大,但常用的就那么几个。我帮你梳理一下,记牢它们,就能应付80%的场景。
| API对象 | 作用 | 常用方法举例 |
|---|---|---|
currentProgram |
当前分析的程序 | getFunctionManager(), getListing() |
getFunctionManager() |
管理所有函数 | getFunctions(True), getFunctionAt(addr) |
getListing() |
访问指令和数据 | getCodeUnitAt(addr), getInstructionAt(addr) |
getCurrentSelection() |
获取用户选中的区域 | getFirstRange(), getNumAddresses() |
getCurrentAddress() |
获取光标所在地址 | 直接返回Address对象 |
为什么会这样设计?说白了,Ghidra把逆向分析中所有「东西」都抽象成了对象。函数是对象,指令是对象,地址也是对象。你操作它们,就像操作Python里的列表一样自然。
currentProgram,再拿getListing(),最后调用getInstructionAt(addr)。一层层剥开,很清晰。
3.3 第一个自动化脚本——批量重命名函数
光说不练假把式。我们写一个真正有用的脚本:批量重命名函数。
场景是这样的:你分析一个固件,发现很多函数名是FUN_00123456这种默认名字。你想把它们改成sub_00123456,方便后续分析。手动改?两百个函数改到天亮。用脚本,一秒搞定。
# 批量重命名函数脚本
from ghidra.program.model.symbol import SourceType
# 获取函数管理器
fm = currentProgram.getFunctionManager()
functions = fm.getFunctions(True)
count = 0
for func in functions:
# 只处理默认名字的函数(以 FUN_ 开头)
name = func.getName()
if name.startswith("FUN_"):
# 新名字:sub_ + 原地址
addr = func.getEntryPoint().toString()
new_name = "sub_" + addr
func.setName(new_name, SourceType.USER_DEFINED)
count += 1
print("重命名完成,共处理 " + str(count) + " 个函数")
这段代码做了三件事:
- 遍历所有函数
- 判断名字是否以
FUN_开头 - 用地址构造新名字并重命名
你可能会问:SourceType.USER_DEFINED是什么?这是告诉Ghidra「这个新名字是我手动改的」,而不是分析自动生成的。这样以后你手动分析时,Ghidra不会覆盖你的命名。
SourceType.USER_DEFINED。结果Ghidra重新分析时,把我改的名字全覆盖了。嗯,从那以后我再也没忘过这个参数。
3.4 如何运行你的脚本
写好了脚本,怎么跑?两种方式:
- 方式一:Script Manager。点击菜单
Window → Script Manager,找到你的脚本,双击运行。 - 方式二:快捷键。我习惯用
Alt + Shift + R快速运行当前脚本。省时间。
我个人建议你把常用脚本放在一个文件夹里,然后在Ghidra里设置脚本路径。这样每次打开Ghidra,脚本都在,不用重新找。
3.5 本章知识体系
下面这张图,帮你把这一章的核心逻辑串起来:
你看,整个知识体系其实就三层:Python基础打底,Ghidra API提供能力,自动化脚本解决实际问题。每一层都不复杂,组合起来威力巨大。
好了,这一章的内容就到这里。脚本入门其实没那么玄乎,你想想看,不就是「拿到对象 → 调用方法 → 处理数据」这三板斧吗?以后遇到重复性工作,先想想能不能用脚本解决。相信我,你会爱上这种感觉的。