# Reverse Engineering Malware With Ghidra

> 使用 NSA 的 Ghidra 反汇编器和反编译器对恶意软件二进制文件进行逆向工程，在汇编和伪 C 代码层面理解其内部逻辑、密码学例程、C2 协议和规避技术。适用于恶意软件逆向工程、反汇编分析、反编译、二进制分析或理解恶意软件内部机制等请求。

- Skill: `killvxk/reverse-engineering-malware-with-ghidra` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/reverse-engineering-malware-with-ghidra`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/reverse-engineering-malware-with-ghidra/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/reverse-engineering-malware-with-ghidra

---


# 使用 Ghidra 对恶意软件进行逆向工程

## 适用场景

- 静态和动态分析已发现可疑功能，需要更深入的代码级理解时
- 需要对 C2 通信协议、加密算法或自定义混淆进行逆向工程时
- 理解恶意软件样本所针对的确切漏洞利用机制或漏洞时
- 从编译代码中提取硬编码配置数据（C2 地址、加密密钥、活动 ID）时
- 根据唯一代码模式开发精确的 YARA 规则或检测签名时

**请勿使用**：对未知样本进行初步鉴别；请先使用 PEStudio 进行静态分析，使用 Cuckoo 进行行为分析。

## 前置条件

- Ghidra 11.x（从 https://ghidra-sre.org/ 下载）及 JDK 17+
- 与生产网络隔离的分析虚拟机（Windows 或 Linux 主机）
- 熟悉 x86/x64 汇编语言和 Windows API 调用约定
- Windows 系统 DLL 的 PDB 符号文件（提高反编译准确性）
- Ghidra 脚本仓库（ghidra_scripts），用于自动化分析任务
- 二级参考：IDA Free 或 Binary Ninja，用于交叉验证分析结果

## 工作流程

### 步骤 1：创建项目并导入二进制文件

创建 Ghidra 项目并导入恶意软件样本：

```
1. 启动 Ghidra: ghidraRun（Linux）或 ghidraRun.bat（Windows）
2. File -> New Project -> Non-Shared Project -> 选择目录
3. File -> Import File -> 选择恶意软件二进制文件
4. Ghidra 自动检测格式（PE、ELF、Mach-O）和架构
5. 接受默认导入选项（如已知则指定基地址）
6. 双击导入的文件在 CodeBrowser 中打开
7. 当提示时，运行启用默认分析器的 Auto Analysis
```

**无头模式（用于自动化）：**
```bash
# 使用反编译器运行 Ghidra 无头分析
/opt/ghidra/support/analyzeHeadless /tmp/ghidra_project MalwareProject \
  -import suspect.exe \
  -postScript ExportDecompilation.py \
  -scriptPath /opt/ghidra/scripts/ \
  -deleteProject
```

### 步骤 2：识别关键函数和入口点

在二进制文件中定位关键代码段：

```
导航策略:
━━━━━━━━━━━━━━━━━━━
1. 从入口点（OEP）开始，追踪 _start/WinMain 的执行流程
2. 检查 Symbol Tree 中的导入函数（Window -> Symbol Tree）
3. 搜索对可疑 API 的交叉引用（XREF）:
   - VirtualAlloc/VirtualAllocEx（注入用内存分配）
   - CreateRemoteThread（远程线程注入）
   - CryptEncrypt/CryptDecrypt（加密操作）
   - InternetOpen/HttpSendRequest（C2 通信）
   - RegSetValueEx（注册表持久化）
4. 使用 Search -> For Strings 查找嵌入的 URL、IP 和路径
5. 检查按大小排序的 Functions 窗口（较大的函数通常包含核心逻辑）
```

**Ghidra 高效导航快捷键：**
```
G         - 跳转到地址
Ctrl+E    - 搜索字符串
X         - 显示当前位置的交叉引用
Ctrl+Shift+F - 搜索字节模式
L         - 重命名标签/函数
;         - 添加注释
T         - 重新定义变量类型
Ctrl+L    - 重新定义返回值类型
```

### 步骤 3：分析反编译代码

使用 Ghidra 反编译器理解函数逻辑：

```c
// 示例：Ghidra 反编译器对解密例程的输出
// 分析人员重命名变量并添加类型以提高可读性

void decrypt_config(BYTE *encrypted_data, int data_len, BYTE *key, int key_len) {
    // XOR 解密，使用滚动密钥
    for (int i = 0; i < data_len; i++) {
        encrypted_data[i] = encrypted_data[i] ^ key[i % key_len];
    }
    return;
}

// Ghidra 中的分析人员操作:
// 1. 右键单击参数 -> Retype 设置正确类型（BYTE*、int）
// 2. 右键单击变量 -> Rename 设置有意义的名称
// 3. 添加注释解释算法
// 4. 设置函数签名以将类型传播给调用者
```

### 步骤 4：追踪 C2 通信逻辑

跟踪网络通信代码路径：

```
C2 协议逆向工程的分析步骤:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 找到 InternetOpenA/WinHttpOpen 调用 -> 追踪到封装函数
2. 跟踪从加密配置到 URL 构建的数据流
3. 识别 HTTP 方法（GET/POST）、请求头和请求体格式
4. 定位响应解析逻辑（JSON 解析、自定义二进制协议）
5. 绘制 C2 命令分发器（switch/case 或跳转表）
6. 记录命令集（下载、执行、外泄、更新、卸载）
```

**提取 C2 配置的 Ghidra 脚本：**
```python
# Ghidra Python 脚本: extract_c2_config.py
# 通过 Ghidra 的 Script Manager 运行

from ghidra.program.model.data import StringDataType
from ghidra.program.model.symbol import SourceType

# 搜索 XOR 解密模式
listing = currentProgram.getListing()
memory = currentProgram.getMemory()

# 查找对 InternetOpenA 的引用
symbol_table = currentProgram.getSymbolTable()
for symbol in symbol_table.getExternalSymbols():
    if "InternetOpen" in symbol.getName():
        refs = getReferencesTo(symbol.getAddress())
        for ref in refs:
            print("C2 初始化位于: {}".format(ref.getFromAddress()))
```

### 步骤 5：分析加密和混淆

识别并记录密码学例程：

```
常见恶意软件加密模式:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
XOR 加密:  带 XOR 操作的循环，通常为单字节或滚动密钥
RC4:       两个循环（KSA + PRGA），256 字节 S-box 初始化
AES:       查找 S-box 常量（0x63、0x7C、0x77...）或 CryptEncrypt 调用
Base64:    包含 A-Za-z0-9+/= 字符的查找表
自定义:    算术操作组合（ADD、SUB、ROL、ROR 与 XOR 混合）

识别技巧:
- 搜索常量: AES S-box、CRC32 表、MD5 初始值
- 查找对字节数组进行操作的循环结构
- 检查 Windows Crypto API 的使用（CryptAcquireContext -> CryptCreateHash -> CryptEncrypt）
- FindCrypt Ghidra 插件可自动识别加密常量
```

### 步骤 6：记录发现结果并创建检测签名

从逆向工程中产出可操作的威胁情报：

```bash
# 根据 Ghidra 中发现的唯一代码模式生成 YARA 规则
cat << 'EOF' > malware_family_x.yar
rule MalwareFamilyX_Decryptor {
    meta:
        description = "检测 MalwareX 解密例程"
        author = "analyst"
        date = "2025-09-15"
    strings:
        // 带硬编码密钥的 XOR 解密循环
        $decrypt = { 8A 04 0E 32 04 0F 88 04 0E 41 3B CA 7C F3 }
        // 解密后的 C2 URL 模式
        $c2_pattern = "/gate.php?id=" ascii
    condition:
        uint16(0) == 0x5A4D and $decrypt and $c2_pattern
}
EOF
```

## 核心概念

| 术语 | 定义 |
|------|------|
| **反汇编（Disassembly）** | 将机器码字节转换为可读汇编语言指令；Ghidra 的 Listing 视图显示反汇编代码 |
| **反编译（Decompilation）** | 将汇编代码提升为伪 C 表示以便于分析；Ghidra 的 Decompile 窗口提供此视图 |
| **交叉引用（XREF，Cross-Reference）** | 显示函数或数据地址被调用或使用位置的引用；对追踪代码执行流至关重要 |
| **控制流图（CFG，Control Flow Graph）** | 函数中所有可能执行路径的可视化表示；展示分支逻辑和循环结构 |
| **原始入口点（OEP，Original Entry Point）** | 解包后恶意软件代码的实际起始地址；加壳程序先通过解包桩重定向执行 |
| **函数签名（Function Signature）** | 函数的返回类型、名称和参数类型；应用正确的签名可提高反编译器输出质量 |
| **Ghidra 脚本（Ghidra Script）** | 在 Ghidra 内执行的 Python 或 Java 自动化脚本，用于批量分析、模式搜索或数据提取 |

## 工具与系统

- **Ghidra**：NSA 的开源软件逆向工程套件，支持多架构的反汇编器、反编译器和脚本功能
- **IDA Pro/Free**：行业标准交互式反汇编器；IDA Free 提供基于云的 x86/x64 反编译
- **Binary Ninja**：商业逆向工程平台，具有现代 UI 和用于插件开发的丰富 API
- **x64dbg**：开源 x64/x32 Windows 调试器，与 Ghidra 配合用于恶意软件的动态调试
- **FindCrypt（Ghidra 插件）**：在二进制代码中识别密码学常量和算法的插件

## 常见场景

### 场景：逆向自定义 C2 协议

**背景**：行为分析显示存在发往外部 IP 非标准端口的加密流量。由于协议为私有协议，网络签名无法检测变体。需要深入逆向工程来理解协议结构。

**分析方法**：
1. 将解包后的样本导入 Ghidra 并运行完整的 Auto Analysis
2. 定位 socket/WinHTTP API 调用，向上追溯到调用函数
3. 识别数据发送前调用的加密例程（从 send/HttpSendRequest 向前追踪数据流）
4. 逆向加密算法（XOR 密钥提取、RC4 密钥派生、AES 密钥定位）
5. 通过分析响应解析函数（对命令 ID 进行 switch/case）绘制命令结构
6. 记录协议格式（头部结构、命令字节、加密方法）
7. 为网络监控工具创建协议解码脚本

**常见陷阱**：
- 未运行完整 Auto Analysis 就开始手动分析（会遗漏函数边界和类型传播）
- 忽略通过函数指针或虚函数表的间接调用（使用 XREF 追踪保存函数地址的数据）
- 在 Ghidra 的 Function ID（FID）或 FLIRT 签名本应识别的库代码上浪费时间
- 未频繁保存 Ghidra 项目进度（崩溃后分析状态可能丢失）

## 输出格式

```
逆向工程分析报告
=====================================
样本:         unpacked_payload.exe
SHA-256:      abc123def456...
架构:         x86（32 位 PE）
Ghidra 项目:  MalwareX_Analysis

函数映射
0x00401000  main()              - 入口点，初始化配置
0x00401200  decrypt_config()    - 使用 16 字节密钥进行 XOR 解密
0x00401400  init_c2()           - WinHTTP 初始化，URL 构建
0x00401800  c2_beacon()         - 携带系统信息的 HTTP POST 心跳
0x00401C00  cmd_dispatcher()    - 对 12 个命令码进行 Switch 分发
0x00402000  inject_process()    - 进程空洞注入 svchost.exe
0x00402400  persist_registry()  - HKCU Run 键持久化
0x00402800  exfil_data()        - 文件收集和加密上传

C2 协议
方法:         HTTPS POST 到 /gate.php
加密:         RC4，密钥由 MD5(bot_id + campaign_key) 派生
Bot ID 格式:  MD5(hostname + username + volume_serial)
心跳间隔:     60 秒，带 10% 抖动
命令集:
  0x01 - 下载并执行文件
  0x02 - 执行 Shell 命令
  0x03 - 上传文件到 C2
  0x04 - 更新配置
  0x05 - 卸载并清除痕迹

加密详情
算法:         RC4
密钥派生:     MD5(bot_id + "campaign_2025_q3")
硬编码种子:   "campaign_2025_q3" 位于偏移量 0x00405A00

提取的 IOC
C2 URL:       hxxps://update.malicious[.]com/gate.php
              hxxps://backup.evil[.]net/gate.php（故障转移）
活动 ID:      campaign_2025_q3
RC4 密钥材料: [参见加密详情]
```

