analyzing-packed-malware-with-upx-unpacker
识别并解包 UPX 加壳及其他加壳恶意软件样本,以暴露原始可执行代码供静态分析使用。 涵盖标准 UPX 解包及处理阻止自动解压缩的修改版 UPX 头部。 适用于恶意软件解包、UPX 解压缩、去除加壳保护或为分析准备加壳样本等请求。
Best use case
analyzing-packed-malware-with-upx-unpacker is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
识别并解包 UPX 加壳及其他加壳恶意软件样本,以暴露原始可执行代码供静态分析使用。 涵盖标准 UPX 解包及处理阻止自动解压缩的修改版 UPX 头部。 适用于恶意软件解包、UPX 解压缩、去除加壳保护或为分析准备加壳样本等请求。
Teams using analyzing-packed-malware-with-upx-unpacker should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/analyzing-packed-malware-with-upx-unpacker/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How analyzing-packed-malware-with-upx-unpacker Compares
| Feature / Agent | analyzing-packed-malware-with-upx-unpacker | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
识别并解包 UPX 加壳及其他加壳恶意软件样本,以暴露原始可执行代码供静态分析使用。 涵盖标准 UPX 解包及处理阻止自动解压缩的修改版 UPX 头部。 适用于恶意软件解包、UPX 解压缩、去除加壳保护或为分析准备加壳样本等请求。
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# 使用 UPX Unpacker 分析加壳恶意软件
## 适用场景
- 静态分析显示高熵节和极少的导入函数,表明二进制文件已加壳
- PEiD、Detect It Easy 或 PEStudio 识别出 UPX 或其他已知加壳工具
- 导入表仅包含 LoadLibrary 和 GetProcAddress(加壳二进制文件典型的运行时导入解析方式)
- 需要恢复原始二进制文件以在 Ghidra 或 IDA 中进行正常反汇编和反编译
- 因恶意软件作者修改了 UPX 魔数或头部导致自动 UPX 解压缩失败
**不适用于**处理自定义加壳、基于 VM 的保护器(Themida、VMProtect),或通过调试进行动态解包更合适的样本。
## 前置条件
- 已安装 UPX(Ultimate Packer for eXecutables)(`apt install upx-ucl` 或从 https://upx.github.io/ 下载)
- Detect It Easy (DIE),用于加壳识别
- Python 3.8+,安装 `pefile` 库用于手动修复头部
- x64dbg 或 x32dbg,用于自动化工具失败时的手动解包
- PE-bear 或 CFF Explorer,用于 PE 头部检查和修复
- 隔离的分析虚拟机(无网络连接)
## 工作流程
### 步骤 1:识别加壳工具
确认样本是否加壳并识别加壳工具:
```bash
# 使用 Detect It Easy 检查
diec suspect.exe
# 使用 UPX 检查(仅测试,不解包)
upx -t suspect.exe
# 基于 Python 的熵值和加壳检测
python3 << 'PYEOF'
import pefile
import math
pe = pefile.PE("suspect.exe")
print("节分析:")
for section in pe.sections:
name = section.Name.decode().rstrip('\x00')
entropy = section.get_entropy()
raw = section.SizeOfRawData
virtual = section.Misc_VirtualSize
print(f" {name:8s} 熵值:{entropy:.2f} 原始大小:{raw:>8} 虚拟大小:{virtual:>8}")
# 检查 UPX 节名称
section_names = [s.Name.decode().rstrip('\x00') for s in pe.sections]
if 'UPX0' in section_names or 'UPX1' in section_names:
print("\n[!] 检测到 UPX 节名称")
elif '.upx' in [s.lower() for s in section_names]:
print("\n[!] 检测到 UPX 变体节名称")
# 检查导入数量(加壳二进制文件导入极少)
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
total_imports = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
print(f"\n总导入数:{total_imports}")
if total_imports < 10:
print("[!] 导入函数极少——可能已加壳")
else:
print("\n[!] 无导入目录——高度加壳")
PYEOF
```
### 步骤 2:尝试标准 UPX 解压缩
尝试使用内置 UPX 解压功能:
```bash
# 标准 UPX 解压缩
upx -d suspect.exe -o unpacked.exe
# 如果 UPX 报 "not packed by UPX" 错误,说明头部可能已被修改
# 用详细输出进行调试
upx -d suspect.exe -o unpacked.exe -v 2>&1
# 验证解包后的文件
file unpacked.exe
diec unpacked.exe
```
### 步骤 3:修复被篡改的 UPX 头部
如果标准解压缩失败,修复被篡改的魔数:
```python
# 修复被篡改的 UPX 头部
import struct
with open("suspect.exe", "rb") as f:
data = bytearray(f.read())
# UPX 魔数:"UPX!"(0x55505821)
# 恶意软件作者通常会修改这些字节以阻止自动解包
# 搜索被修改的 UPX 签名
upx_magic = b"UPX!"
modified_patterns = [b"UPX0", b"UPX\x00", b"\x00PX!", b"UPx!"]
# 查找并还原节名称
pe_offset = struct.unpack_from("<I", data, 0x3C)[0]
num_sections = struct.unpack_from("<H", data, pe_offset + 6)[0]
section_table_offset = pe_offset + 0x18 + struct.unpack_from("<H", data, pe_offset + 0x14)[0]
print(f"PE 偏移:0x{pe_offset:X}")
print(f"节数量:{num_sections}")
print(f"节表偏移:0x{section_table_offset:X}")
for i in range(num_sections):
offset = section_table_offset + (i * 40)
name = data[offset:offset+8]
print(f"节 {i}:{name}")
# 还原二进制文件中的 UPX 魔数
# 搜索 UPX 头部签名位置(通常在加壳数据末尾附近)
for i in range(len(data) - 4):
if data[i:i+3] == b"UPX" and data[i+3] != ord("!"):
print(f"在偏移 0x{i:X} 处发现被修改的 UPX 魔数:{data[i:i+4]}")
data[i:i+4] = b"UPX!"
print(f"已还原为:UPX!")
# 如果节名称被修改也一并还原
for i in range(num_sections):
offset = section_table_offset + (i * 40)
name = data[offset:offset+8].rstrip(b'\x00')
if name in [b"UPX0", b"UPX1", b"UPX2"]:
continue # 已正确
# 检查常见的修改方式
if name.startswith(b"UP") or name.startswith(b"ux"):
original = f"UPX{i}".encode().ljust(8, b'\x00')
data[offset:offset+8] = original
print(f"在 0x{offset:X} 处还原节名称为 {original}")
with open("suspect_fixed.exe", "wb") as f:
f.write(data)
print("\n已写入修复文件。重试:upx -d suspect_fixed.exe -o unpacked.exe")
```
### 步骤 4:使用调试器手动解包
当自动解包完全失败时,使用动态解包:
```
使用 x64dbg 手动 UPX 解包:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 在 x64dbg 中加载加壳样本
2. 运行到入口点(系统断点后按 F9)
3. UPX 解包桩模式:
a. PUSHAD(保存所有寄存器)
b. 解压缩循环(处理加壳的节)
c. 解析导入(LoadLibrary/GetProcAddress 调用)
d. POPAD(恢复寄存器)
e. JMP 到 OEP(原始入口点)
4. 在 PUSHAD 后对 ESP 设置硬件断点:
- PUSHAD 后,在寄存器中右键点击 ESP -> 在内存中跟随
- 在 [ESP] 地址处设置访问硬件断点
- 运行(F9)——在 POPAD 前跳转到 OEP 时中断
5. 单步执行(F7/F8)直到到达 JMP 到 OEP
6. 在 OEP 处:使用 Scylla 插件转储并修复导入:
- 插件 -> Scylla -> OEP = 当前 EIP
- 点击"IAT Autosearch" -> "Get Imports"
- 点击"Dump"保存解包后的二进制文件
- 点击"Fix Dump"修复导入表
```
### 步骤 5:验证解包后的二进制文件
验证解包样本的有效性和完整性:
```bash
# 验证解包后的 PE 文件是否有效
python3 << 'PYEOF'
import pefile
pe = pefile.PE("unpacked.exe")
# 检查节是否正常
print("解包后节分析:")
for section in pe.sections:
name = section.Name.decode().rstrip('\x00')
entropy = section.get_entropy()
print(f" {name:8s} 熵值:{entropy:.2f}")
# 验证导入已解析
print(f"\n导入数量:")
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll = entry.dll.decode()
count = len(entry.imports)
print(f" {dll}:{count} 个函数")
total = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
print(f" 总计:{total} 个导入")
# 比较文件大小
import os
packed_size = os.path.getsize("suspect.exe")
unpacked_size = os.path.getsize("unpacked.exe")
print(f"\n加壳: {packed_size:>10} 字节")
print(f"解包后:{unpacked_size:>10} 字节")
print(f"比率: {unpacked_size/packed_size:.1f}x")
PYEOF
```
## 核心概念
| 术语 | 定义 |
|------|------|
| **加壳(Packing)** | 压缩或加密可执行代码以减小文件大小并阻碍静态分析;二进制文件包含在运行时恢复代码的解包桩 |
| **UPX** | Ultimate Packer for eXecutables;开源可执行文件加壳工具,因免费且有效而常被恶意软件作者滥用 |
| **原始入口点(OEP)** | 加壳前恶意软件代码的真实起始地址;解包桩解压代码后跳转到 OEP |
| **导入重建(Import Reconstruction)** | 使用 Scylla 或 ImpRec 等工具,在从内存转储解包进程后重建导入地址表的过程 |
| **PUSHAD/POPAD** | 保存/恢复所有通用寄存器的 x86 指令;UPX 使用此模式在解包过程中保留寄存器状态 |
| **节熵(Section Entropy)** | PE 节数据的随机性度量;加壳节熵值 > 7.0,而正常代码节平均为 5.0-6.5 |
| **魔数(Magic Bytes)** | 文件中用于标识格式的签名字节;UPX 使用"UPX!",恶意软件作者会修改这些字节以阻止自动解压缩 |
## 工具与系统
- **UPX**:开源可执行文件加壳工具,具有对正常加壳文件进行内置解压缩的能力
- **Detect It Easy (DIE)**:加壳工具、编译器和链接器检测工具,可识别 PE、ELF 和 Mach-O 文件上的保护措施
- **x64dbg/x32dbg**:开源 Windows 调试器,用于通过动态执行和基于断点的 OEP 查找进行手动解包
- **Scylla**:与 x64dbg 集成的导入重建工具,用于内存转储后重建 IAT
- **PE-bear**:PE 文件查看器和编辑器,用于解包后检查和修复 PE 头部
## 常见场景
### 场景:解包带有修改版 UPX 头部的恶意软件
**场景背景**:一个恶意软件样本通过节名称(UPX0、UPX1)被识别为 UPX 加壳,但 `upx -d` 失败并报"CantUnpackException: header corrupted"。恶意软件作者修改了 UPX 魔数以阻止自动解压缩。
**方法**:
1. 在十六进制编辑器中打开二进制文件,搜索 UPX 头部区域(通常在加壳数据末尾)
2. 识别被修改的魔数(如"UPX!"被改为"UPX\x00"或完全清零)
3. 使用 Python 修复脚本还原"UPX!"魔数并修正节名称
4. 在修复后的二进制文件上重试 `upx -d`
5. 如果修复失败,回退到使用 x64dbg 手动解包(PUSHAD -> ESP 硬件断点 -> POPAD -> JMP OEP)
6. 验证解包后的二进制文件具有正常的导入和合理的熵值
7. 导入 Ghidra 或 IDA 进行完整静态分析
**常见陷阱**:
- 假设 UPX 是唯一的加壳工具;二进制文件可能是双重加壳(UPX + 自定义层)
- 在原始加壳样本上操作而不是在副本上工作
- 手动内存转储后未重建导入(未修复 IAT 的转储二进制文件会崩溃)
- 忘记检查附加在 UPX 加壳 PE 节之后的 overlay 数据
## 输出格式
```
解包分析报告
===========================
样本: suspect.exe
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
加壳工具: UPX 3.96(修改版头部)
加壳二进制文件
节: UPX0(熵值:0.00)UPX1(熵值:7.89).rsrc(熵值:3.45)
导入: 2 个(kernel32.dll:LoadLibraryA、GetProcAddress)
文件大小: 98,304 字节
解包方法
方法: 头部修复 + UPX -d
头部修复: 在偏移 0x1F000 处还原 UPX! 魔数
命令: upx -d suspect_fixed.exe -o unpacked.exe
结果: 成功
解包后二进制文件
节: .text(熵值:6.21).rdata(熵值:4.56).data(熵值:3.12).rsrc(熵值:3.45)
导入: 147 个(kernel32、user32、advapi32、wininet、ws2_32)
文件大小: 245,760 字节(扩展 2.5 倍)
OEP: 0x00401000
验证
PE 有效: 是
导入已解析: 是(8 个 DLL 共 147 个函数)
可执行: 是(在沙箱中运行不崩溃)
后续步骤
- 将 unpacked.exe 导入 Ghidra 进行完整反汇编
- 对解包后的二进制文件运行 YARA 规则
- 将解包后的二进制文件提交 VirusTotal 以获得更好的检测率
```Related Skills
reverse-engineering-rust-malware
使用 IDA Pro 和 Ghidra 对 Rust 编译的恶意软件进行逆向工程,掌握处理非空终止字符串、提取 crate 依赖项和 Rust 特有控制流分析的专项技术。
reverse-engineering-malware-with-ghidra
使用 NSA 的 Ghidra 反汇编器和反编译器对恶意软件二进制文件进行逆向工程,在汇编和伪 C 代码层面理解其内部逻辑、密码学例程、C2 协议和规避技术。适用于恶意软件逆向工程、反汇编分析、反编译、二进制分析或理解恶意软件内部机制等请求。
reverse-engineering-dotnet-malware-with-dnspy
使用 dnSpy 反编译器和调试器对 .NET 恶意软件进行逆向工程,分析 C#/VB.NET 源代码,识别混淆技术,提取配置信息,理解包括信息窃取器、远程访问木马(RAT)和加载器在内的恶意功能。适用于 .NET 恶意软件分析、C# 恶意软件反编译、托管代码逆向工程或 .NET 混淆分析等请求。
reverse-engineering-android-malware-with-jadx
使用 JADX 反编译器对恶意 Android APK 文件进行逆向工程,分析 Java/Kotlin 源代码,识别包括数据窃取、C2 通信、权限提升和覆盖攻击在内的恶意功能。检查 Manifest 权限、Receiver、Service 及原生库。适用于 Android 恶意软件分析、APK 逆向工程、移动端恶意软件调查或 Android 威胁分析等请求。
performing-static-malware-analysis-with-pe-studio
使用 PEStudio 对 Windows PE(可移植可执行文件)恶意软件样本进行静态分析, 检查文件头、导入表、字符串、资源和指标,无需执行二进制文件。 识别可疑特征,包括加壳、反分析技术和恶意导入。适用于静态恶意软件分析、 PE 文件检查、Windows 可执行文件分析或执行前恶意软件分级等请求场景。
performing-malware-triage-with-yara
使用 YARA 规则对文件模式、字符串、字节序列和结构特征进行匹配,快速分级和分类恶意软件样本, 识别已知恶意软件家族及可疑指标。涵盖规则编写、扫描和与分析流程的集成。适用于 YARA 规则创建、 恶意软件分类、模式匹配、样本分级或基于签名的检测等请求场景。
performing-malware-persistence-investigation
系统性地调查 Windows 和 Linux 系统上的所有持久化机制,以识别恶意软件如何在重启后存活并维持访问。
performing-malware-ioc-extraction
恶意软件 IOC(失陷指标)提取是指通过分析恶意软件,识别可操作的失陷指标,包括文件哈希、网络指标(C2 域名、IP 地址、URL)、注册表修改、互斥体名称、嵌入字符串和行为产物。
performing-malware-hash-enrichment-with-virustotal
使用 VirusTotal API 富化恶意软件文件哈希,获取检测率、行为分析、YARA 匹配和上下文威胁情报,用于事件分类和 IOC 验证。
performing-firmware-malware-analysis
分析固件镜像中嵌入的恶意软件、后门和未授权修改,目标包括路由器、IoT 设备、UEFI/BIOS 和嵌入式系统。涵盖固件提取、文件系统分析、二进制逆向工程和 Bootkit 检测。适用于固件安全 分析、IoT 恶意软件调查、UEFI Rootkit 检测或嵌入式设备入侵评估等请求场景。
performing-automated-malware-analysis-with-cape
部署和操作 CAPEv2 沙箱,进行自动化恶意软件分析,具备行为监控、载荷提取、配置解析和反规避能力。
extracting-iocs-from-malware-samples
从恶意软件样本中提取攻陷指标(IoC),包括文件哈希、网络指标(IP、域名、URL)、 主机痕迹(文件路径、注册表键、互斥锁)以及行为模式,用于威胁情报共享和检测规则创建。 适用于 IoC 提取、威胁指标采集、恶意软件指标收集或从样本构建检测内容等请求场景。