Ghidra
2026/5/29工具工具逆向工程Ghidra大约 6 分钟
Ghidra
链接
是什么
Ghidra 是由美国国家安全局(NSA)开发并开源的逆向工程工具套件。它提供了强大的反汇编和反编译功能,支持多种处理器架构和可执行文件格式。Ghidra 是 IDA Pro 的主要免费替代品,功能强大且完全免费开源。
核心功能:
- 反汇编:支持超过 30 种处理器架构
- 反编译:内置反编译器,可将汇编还原为类 C 伪代码
- 协作分析:支持多人协作分析同一项目
- 脚本开发:支持 Java 和 Python(Jython)脚本
- 版本追踪:支持二进制文件差异对比
- 扩展性:支持自定义加载器、处理器模块和插件
在 CTF 竞赛中,Ghidra 是 IDA Pro 的免费替代方案,特别适合学生和初学者使用。
安装与配置
环境要求
- Java 17 或更高版本(推荐 OpenJDK)
- 至少 4GB 内存(推荐 8GB+)
- 支持 Windows、Linux、macOS
安装方法
# 从官网下载
# https://ghidra-sre.org/
# Linux 安装
unzip ghidra_11.0_PUBLIC_20240130.zip
cd ghidra_11.0_PUBLIC
./ghidraRun
# Windows 安装
# 解压后运行 ghidraRun.bat
# macOS 安装
# 解压后运行 ghidraRun 或双击 Ghidra.app
# 使用包管理器(Linux)
# Arch Linux
yay -S ghidra
# 验证安装
java -version # 确认 Java 版本配置优化
编辑 support/launch.properties:
# 增加内存分配
VMARGS=-Dsun.java2d.d3d=false
VMARGS=-Xmx4G
VMARGS=-XX:MaxPermSize=256MPython 支持配置
Ghidra 使用 Jython(Java 实现的 Python 2.7):
# Ghidra 内置 Jython,无需额外安装
# 如需使用 Python 3 功能,可安装 Ghidrathon 插件基本用法
项目创建
1. 启动 Ghidra
2. File -> New Project
3. 选择项目类型(Shared 或 Non-Shared)
4. 设置项目名称和位置
5. 点击 Finish导入文件
1. File -> Import File
2. 选择要分析的二进制文件
3. Ghidra 会自动识别文件格式和架构
4. 确认导入设置后点击 OK
5. 双击导入的文件打开 CodeBrowser界面布局
Ghidra CodeBrowser 主要窗口:
- Listing:反汇编视图
- Decompiler:反编译视图(类 C 伪代码)
- Symbol Tree:符号树(函数、标签、类等)
- Data Type Manager:数据类型管理器
- Console:控制台输出
- Bytes:十六进制视图
常用快捷键
| 快捷键 | 功能 |
|---|---|
| L | 重命名符号 |
| Ctrl+E | 编辑函数签名 |
| ; | 添加注释 |
| : | 添加前注释 |
| Ctrl+D | 添加 EOL 注释 |
| G | 跳转到地址 |
| Ctrl+Shift+E | 反编译当前函数 |
| F | 创建函数 |
| D | 切换数据类型 |
| C | 转换为代码 |
| U | 清除代码/数据定义 |
| Ctrl+Shift+F | 全局文本搜索 |
| Z | 折叠/展开函数 |
| X | 查看交叉引用 |
| Ctrl+L | 清除高亮 |
反编译使用
1. 在 Listing 中选中一个函数
2. 右键 -> Decompile 或按 Ctrl+Shift+E
3. Decompiler 窗口显示类 C 伪代码
4. 可以在伪代码中直接重命名变量和函数
5. 右键变量或函数名 -> Rename 或按 L搜索功能
// 搜索字符串
Search -> For Strings
// 可设置最小长度、字符集等过滤条件
// 搜索内存
Search -> Memory
// 支持十六进制模式搜索
// 搜索指令
Search -> For Instructions函数分析
1. 在 Symbol Tree 中展开 Functions
2. 双击函数名跳转到函数实现
3. 在 Decompiler 窗口查看伪代码
4. 使用 X 键查看交叉引用
# 函数调用图
Window -> Function Call TreesCTF常用技巧
快速定位关键函数
# Ghidra Python 脚本:搜索关键字符串
from ghidra.program.util import DefinedDataIterator
from ghidra.util import Msg
program = getCurrentProgram()
for s in DefinedDataIterator.definedStrings(program):
s_val = s.getDefaultValueRepresentation()
if "flag" in s_val.lower() or "key" in s_val.lower():
print(f"String: {s_val} at {s.getAddress()}")批量重命名
# Ghidra Python 脚本:根据函数行为重命名
func = getGlobalFunctions("main")[0]
body = func.getBody()
listing = currentProgram.getListing()
for inst in listing.getInstructions(body, True):
if inst.getMnemonicString() == "CALL":
addr = inst.getAddress(0)
ref = getReferencesFrom(addr)
for r in ref:
func_name = getFunctionAt(r.getToAddress())
if func_name:
print(f"Call to: {func_name}")自动分析配置
Analysis -> Auto Analyze
推荐启用的分析器:
- Aggressive Instruction Search
- ASCII Strings
- Create Address Tables
- Create Function
- Data Reference
- Decompiler Parameter ID
- Demangler GNU
- ELF External Name
- Function ID
- PDB Universal
- Reference
- Subroutine References类型恢复
# Ghidra Jython 脚本:设置函数参数类型
from ghidra.app.decompiler import DecompInterface
program = getCurrentProgram()
decomp = DecompInterface()
decomp.openProgram(program)
func = getGlobalFunctions("check_flag")[0]
result = decomp.decompileFunction(func, 30, monitor)
if result.depiledFunction():
print(result.getDecompiledFunction().getC())结构体定义
# 在 Data Type Manager 中创建结构体
1. 右键 -> New -> Structure
2. 设置结构体名称
3. 添加成员和类型
4. 在代码中应用结构体类型
# 常见需要定义的结构体:
- 文件头结构
- 自定义数据结构
- 协议消息格式调用图分析
# 生成函数调用图
Window -> Function Call Trees
# 可视化函数之间的调用关系
# 生成控制流图
在 Decompiler 窗口中查看
# 或使用 Graph 选项Diff 版本对比
# 版本追踪功能
Tools -> Version Tracking
1. 创建新项目
2. 添加源程序和目标程序
3. 选择关联分析类型
4. 运行分析
5. 查看差异结果Ghidra 脚本开发
// Java 脚本示例:遍历所有函数
import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.*;
public class ListFunctions extends GhidraScript {
@Override
public void run() throws Exception {
FunctionManager fm = currentProgram.getFunctionManager();
for (Function func : fm.getFunctions(true)) {
println("Function: " + func.getName() + " at " + func.getEntryPoint());
}
}
}# Jython 脚本示例:搜索 XOR 指令
from ghidra.program.model.listing import CodeUnit
listing = currentProgram.getListing()
for func in currentProgram.getFunctionManager().getFunctions(True):
inst_iter = listing.getInstructions(func.getBody(), True)
while inst_iter.hasNext():
inst = inst_iter.next()
if inst.getMnemonicString() == "XOR":
print(f"XOR at {inst.getAddress()} in {func.getName()}")分析加密算法
# Ghidra 脚本:提取函数中的常量
func = getGlobalFunctions("encrypt")[0]
body = func.getBody()
listing = currentProgram.getListing()
constants = []
for inst in listing.getInstructions(body, True):
for i in range(inst.getNumOperands()):
for op in inst.getOpObjects(i):
if isinstance(op, ghidra.program.model.scalar.Scalar):
val = op.getValue()
if val > 255:
constants.append(hex(val))
print("Constants found:", constants)常见问题
Java 版本不兼容
解决:
# 确认 Java 版本
java -version
# 安装正确的 Java 版本
# Ubuntu
sudo apt install openjdk-17-jdk
# 设置 JAVA_HOME
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64分析速度慢
解决:
- 增加 JVM 内存分配(修改 launch.properties)
- 关闭不必要的分析器
- 使用 64 位 Java
- 分段分析大型文件
反编译结果不准确
解决:
- 手动修正函数签名
- 定义正确的数据类型
- 修正函数边界
- 添加缺失的函数调用
无法识别架构
解决:
- 安装对应的处理器模块(Processor Module)
- 使用社区开发的扩展
- 手动选择处理器类型
Python 脚本兼容性
说明:
- Ghidra 内置 Jython(Python 2.7)
- 不支持 Python 3 语法
- 可安装 Ghidrathon 插件支持 Python 3
- 无法直接使用标准 Python 库(如 requests)
中文显示乱码
解决:
- 在 Ghidra 启动参数中添加:
-Dfile.encoding=UTF-8 - 使用 Ghidra 的编码设置选项
对比 IDA Pro
| 特性 | Ghidra | IDA Pro |
|---|---|---|
| 价格 | 免费开源 | 商业(昂贵) |
| 反编译器 | 内置 | 需要额外购买(Hex-Rays) |
| 协作支持 | 原生支持 | 需要第三方工具 |
| 脚本语言 | Java / Jython | Python (IDAPython) |
| 插件生态 | 较新但在发展 | 成熟丰富 |
| 处理器架构 | 30+ | 50+ |
| 用户界面 | Java Swing | 原生 UI |
| 启动速度 | 较慢 | 较快 |
| 社区支持 | 活跃 | 成熟 |