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) + " 个函数")

这段代码做了三件事:

  1. 遍历所有函数
  2. 判断名字是否以FUN_开头
  3. 用地址构造新名字并重命名

你可能会问:SourceType.USER_DEFINED是什么?这是告诉Ghidra「这个新名字是我手动改的」,而不是分析自动生成的。这样以后你手动分析时,Ghidra不会覆盖你的命名。

⚠️ 我曾经踩过的坑:有一次我写脚本批量改名,忘了加SourceType.USER_DEFINED。结果Ghidra重新分析时,把我改的名字全覆盖了。嗯,从那以后我再也没忘过这个参数。

3.4 如何运行你的脚本

写好了脚本,怎么跑?两种方式:

  • 方式一:Script Manager。点击菜单 Window → Script Manager,找到你的脚本,双击运行。
  • 方式二:快捷键。我习惯用 Alt + Shift + R 快速运行当前脚本。省时间。

我个人建议你把常用脚本放在一个文件夹里,然后在Ghidra里设置脚本路径。这样每次打开Ghidra,脚本都在,不用重新找。

3.5 本章知识体系

下面这张图,帮你把这一章的核心逻辑串起来:

Ghidra脚本入门知识体系 Python基础 变量 / 循环 / 判断 函数定义 / 列表操作 Ghidra API currentProgram getFunctionManager() 自动化脚本 批量重命名 遍历 / 判断 / 修改 核心流程 获取对象 → 调用方法 → 处理数据 → 输出结果 💡 记住:脚本不是一次性工具。写一次,用一辈子。下次遇到类似问题,改两行代码就能复用。

你看,整个知识体系其实就三层:Python基础打底,Ghidra API提供能力,自动化脚本解决实际问题。每一层都不复杂,组合起来威力巨大。

🔧 我的建议:学完这一章,立刻打开Ghidra,写一个最简单的脚本——哪怕只是打印所有函数名。动手写一遍,比看十遍都管用。

好了,这一章的内容就到这里。脚本入门其实没那么玄乎,你想想看,不就是「拿到对象 → 调用方法 → 处理数据」这三板斧吗?以后遇到重复性工作,先想想能不能用脚本解决。相信我,你会爱上这种感觉的。

专注资料整理