Ghidra——一款开源的逆向的尚方宝剑

一、常用工具与命令

(一)file命令

作用:检查文件类型的强大工具,不依赖文件扩展名,而是基于文件内容识别。

检查原理

  1. ASCII 编码的文本文件:识别特定的字符串特征。
  2. 非 ASCII 编码的二进制文件 :识别幻数(Magic Numbers)和特殊结构。

什么是幻数

文件格式要求的特殊标签值,通常位于文件头部。

  • MS-DOS 可执行文件MZ (Mark Zbikowski, MS-DOS 架构设计师姓名缩写)
  • Java Class 文件0xcafebabe (便于记忆的十六进制值)
  • Windows PE 可执行文件4D5A (即 ASCII 的 "MZ")
  • JPG 图片文件FFD8... 结尾通常包含 4A464946 (ASCII 的 "JFIF")

幻数定义文件位置/usr/share/file/magic/usr/share/misc/magic/etc/magic

(二)strip命令

作用:剥离二进制文件中的符号表(Symbol Table)和调试信息。

  • 影响:会导致无法进行源码级调试。
  • 优势:显著减小文件体积,常用于发布版本。

(三)nm命令

作用 :列出目标文件(如 ELF 可执行文件、.o 中间文件)中的符号表。

符号字母说明

  • 大小写含义 :大写字母表示全局 符号,小写字母表示局部符号。
  • 常见符号类型
    • U (Undefined):未定义的符号,通常引用自外部库或其他文件。
    • T / t (Text):代码段定义的符号。T 为全局函数,t 为静态函数(本地)。
    • D / d (Data):已初始化的数据段。D 为全局变量,d 为局部静态变量。
    • C (Common):未初始化的数据(通常在全局区)。
    • B / b (BSS):未初始化的数据段。

(四)查看动态库依赖

不同平台下查看可执行文件所需动态链接库的命令:

平台 工具/命令 使用示例 备注
Linux ldd ldd <可执行文件名> 最常用
Linux objdump / readelf readelf -d <文件名> 基于 libbfd,提供更底层信息
Windows dumpbin dumpbin /dependents <文件名> 需安装 Visual Studio
macOS otool otool -L <可执行文件名> macOS 原生工具

(五)c++filt命令

作用 :将 C++ 编译器生成的修饰名(Mangled Names)还原为可读的函数名。 典型用法 :配合 nm 使用,分析重载函数。

bash 复制代码
nm <文件名> | c++filt

(六)strings命令

作用 :从二进制文件中提取可打印的字符串序列。 典型用法

bash 复制代码
strings <文件名>

常用参数

  • -t [o|x|d]:打印字符串的偏移量(八进制、十六进制或十进制),便于定位。
  • -e [s|S|l|L|b|B|h|H]:指定字符编码(如 UTF-8, UTF-16 等),用于搜索宽字符。
  • -a:扫描整个文件,而不仅仅是数据段(默认只扫描已加载的数据区)。
  • -n <len>:设置最小字符串长度(默认为 4)。

二、平台特定工具与对抗技术

1. Windows 可执行文件分析工具

  • PE Tools:全面的 PE 文件查看器,可编辑节表、资源等。
  • PEiD:经典的查壳工具,用于识别打包器、编译器版本(注:较老,对新壳支持有限)。

2. Linux/通用反汇编工具

  • ndisasm (NASM 配套):简单的线性反汇编器。
  • distorm3:强大的轻量级反汇编引擎,常用于脚本集成。

3. 反逆向方案(保护技术)

用于增加逆向分析难度的加壳或混淆工具:

  • 压缩壳UPX (开源,主要压缩体积,易脱壳), ASPack
  • 加密/保护壳ASProtect, Themida, TELock, VMProtect (虚拟化保护,难度较高)。

4. 去混淆与脱壳方案

  • QuickUnpack
    • 原理:在内存中运行被保护的程序,利用其自身解压/解密机制,在内存中还原原始代码后提取(Dump)。
    • 建议 :由于涉及执行未知代码,务必在沙盒或隔离虚拟机环境中进行分析
  • 其他通用方法:OllyDbg/x64dbg 动态调试脱壳、Unpacker 插件、手动修复 IAT。

三、语言特性与底层结构

1. 堆栈(Stack)机制

  • 数据残留pop 操作通常只是移动栈顶指针(ESP/RSP),并不会立即清除内存中的数据。
  • 安全性:旧数据在被新数据覆盖(push)之前,理论上仍存在于内存中,可通过内存转储或调试手段恢复(可能导致信息泄露)。

2. Main 函数

  • 程序的入口点。在 C/C++ 中,实际入口往往是启动例程(如 _start -> __libc_start_main -> main)。
  • 逆向时需注意参数传递(argc, argv, envp)。

3. 函数重载与名称修饰

C++ 支持函数重载,编译器会将函数名、参数类型、命名空间等信息编码成唯一的符号名。

  • 示例函数void SubClass::vfunc1()
  • Microsoft (MSVC) 格式?vfunc1@SubClass@@UAEXXZ
    • ? 开头,@ 分隔符,包含类名、调用约定、返回类型等信息。
  • Intel/GNU (GCC/Clang) 格式_ZN8SubClass6vfunc1Ev
    • _Z 开头,N 表示命名空间/类,数字表示后续标识符长度,E 结束,v 表示 void。
  • 解析工具 :使用 c++filt 可相互转换。

四、Ghidra 逆向分析框架详解

(一)特殊前缀与数据类型

Ghidra 在反编译窗口中会对变量和地址添加前缀以区分类型:

前缀 含义 说明
param_ 参数 传递给函数的参数。
local_ 局部变量 函数栈帧内的局部变量。
undefined4 未知类型 编译器无法确定具体类型,长度为 4 字节的变量。
LAB_address 代码标签 自动生成的代码跳转目标地址。
DAT_address 数据标签 全局数据或静态数据地址。
FUN_address 函数标签 已识别的函数入口地址。
SUB_address 子程序标签 被调用但未被完全确认为标准函数的地址。
EXT_address 外部符号 外部导入的函数或变量。
OFF_address 偏移/中断 可能指向中断向量、数据偏移或错误处理。
UNK_address 未知 Ghidra 无法识别其属性或用途的地址。

注:address 代表具体的十六进制地址值。

(二)Language ID 规范

Ghidra 使用特定的字符串标识处理器架构和模式,格式如下: 处理器:端序:位宽:变体/模式:编译器

  • 处理器x86, x86_64, ARM, MIPS, AARCH64 等。
  • 端序
    • LE :小端序(Intel x86, ARM 默认)。
    • BE:大端序(部分 MIPS, 旧版 ARM)。
  • 架构大小16, 32, 64 (指寄存器宽度/地址总线宽度)。
  • 处理器变体或模式
    • x86:real (实模式), protected (保护模式), v86 (虚拟 8086)。
    • ARM:v4, v5, v7, v8, thumb (Thumb 指令集模式)。
  • 编译器gcc, borlandcpp, borlanddelphi, msvc 等,有助于优化反编译逻辑。

示例x86:LE:32:default:gcc

(三)协作分析

  • 优势:Ghidra 原生支持多人同时在一个项目中工作,适合团队逆向大型项目。相比 IDA Pro 的协作方案,Ghidra 更加开放且免费。
  • 设置 :需要搭建 Ghidra Server (基于 Java),配置数据库连接,团队成员通过客户端连接同一服务器项目进行实时同步。

(四)二次开发

  • 支持语言 :主要支持 Java (编写插件/模块) 和 Python/Jython (编写自动化脚本)。

  • 应用场景

    • 批量处理文件。
    • 自定义分析逻辑(如识别特定的加密算法)。
    • 自动化重命名函数和变量。
    • 导出特定格式的报告。
  • API:提供丰富的 API 访问反汇编列表、反编译伪代码、符号表等。

    用户界面交互
    方法签名 功能描述
    public void popup(final String message) 弹出提示框:在对话框中显示信息并要求用户选择。
    public String askString(String title, String message) 字符串输入框:带标题和提示信息的文本输入对话框。
    public boolean askYesNo(String title, String message) 确认对话框:询问是或否的问题。
    public Address askAddress(String title, String message) 地址输入框:解析用户输入的地址字符串。
    public int askInt(String title, String message) 整数输入框:获取用户输入的整数值。
    public File askFile(final String title, final String approveButtonText) 文件选择器:让用户选择文件。
    public File askDirectory(final String title, ...) 文件夹选择器:让用户选择目录。
    public void printf(String message, Object... args) 格式化输出:类似 C 语言的 printf,将格式化后的内容输出到控制台。
    public void println(String message) 普通输出:非入侵式地打印一行信息到控制台。
    核心数据接口
    1. 地址与符号
    接口 方法 功能描述
    地址 getOffset() 获取地址的长整型偏移值。
    符号 getAddress() 获取该符号所在的内存地址。
    符号 getName() 获取符号的名称字符串。
    2. 引用关系
    方法 功能描述
    getFromAddress() 获取引用的源地址
    getToAddress() 获取引用的目的地址
    getReferenceType() 获取引用的类型。
    GhidraScript 类成员与任务监控
    1. 预设数据成员
    变量名 类型 功能描述
    currentProgram Program 当前打开的程序:代表正在分析的二进制文件对象。
    currentAddress Address 当前光标地址:用户在反汇编窗口中光标所在的地址。
    currentLocation ProgramLocation 当前位置详情:包含地址及更具体的上下文信息。
    currentSelection ProgramSelection 当前选中范围:用户在 GUI 中高亮选中的地址区域。
    2. 任务监控
变量/方法 功能描述
monitor (TaskMonitor) 任务监视器:用于更新长时间运行任务的状态进度条。
monitor.isCancelled() 检查取消状态:判断用户是否点击了"取消"按钮。通常在循环中调用此方法以优雅地退出脚本。

(五)无头模式

  • 定义:在不启动图形用户界面 (GUI) 的情况下运行 Ghidra。

  • 工具analyzeHeadless 脚本。

  • 用途

    • CI/CD 集成:在自动化流水线中自动分析二进制文件。
    • 批量处理:一次性分析成百上千个样本。
    • 服务器部署:在资源受限或无显示环境的服务器上运行分析任务。
    • 脚本执行:直接调用 Python/Java 脚本对文件进行处理并输出结果。
  • 基本命令结构

    bash 复制代码
    analyzeHeadless <项目路径> <项目名称> -import <文件路径> -scriptPath <脚本目录> -postScript <脚本名>.py
  • 常用参数详解

参数 说明 示例
-import 导入文件,支持通配符 -import *.dll
-scriptPath 添加脚本搜索路径 -scriptPath /home/user/scripts
-postScript 分析后执行的脚本(可多次使用) -postScript dump_funcs.py
-scriptArgs 传递给脚本的参数 -scriptArgs output.txt
-deleteProject 处理完后删除项目目录 (无参数)
-projectBackup 是否备份项目 -projectBackup false
-log 指定日志文件 -log analysis.log
-help 显示帮助信息 -help
相关推荐
a1117766 小时前
纸张生成器(html开源)
前端·开源·html
猫头虎6 小时前
OpenClaw 常用操作命令完整速查手册:终端 CLI 操作指令详解|聊天斜杠指令详情
运维·git·容器·开源·github·aigc·ai编程
a1117767 小时前
网页魔方(html threeJS)
开源·html
醉颜凉8 小时前
夜莺-Nightingale-开源云原生监控分析系统部署 Prometheus 作为时序库使用(配置多数据源)
云原生·开源·prometheus·nightingale·夜莺监控
prince_zxill10 小时前
New API 详解:新一代开源大模型统一网关与 AI 资产管理系统(深度 6000 字指南)
人工智能·开源
组合缺一1 天前
Java 版 Claude Code CLI 来了!(国产开源项目)Solon Code CLI 发布
java·ai·开源·llm·solon·cli·claudecode
a1117761 天前
表情包制作(ai banana使用教程)
开源·ai生图