关于 rev-u3d-dump
rev-u3d-dump 是用于 Unity IL2CPP 构建的符号转储技能,可提取 C# 方法名、地址和类型定义,供 IDA 或 Ghidra 分析。它以 global-metadata.dat 和原生二进制为输入,并介绍工具选择及导入流程。
主要功能
- 01提取方法名与函数地址
- 02转储 C# 类型定义
- 03检查元数据版本
- 04生成 IDA/Ghidra 导入文件
- 05说明 IL2CPP 文件定位流程
适用场景
- 01为 IDA 中的函数恢复名称
- 02将类型定义导入反汇编分析
- 03分析 Unity IL2CPP 构建
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ p4nda0s/ reverse-skills --skill rev-u3d-dump安装后在 Claude Code 中输入/rev-u3d-dump确认已加载。
详细介绍
rev-u3d-dump - Unity IL2CPP 符号转储工具
从 Unity IL2CPP 构建中提取 C# 方法名、地址和类型定义,用于 IDA/Ghidra 分析。
概述
Unity IL2CPP 会将 C# 编译为本机代码。二进制文件中原始的类名和方法名会被移除,但仍保存在 global-metadata.dat 中。此工具可恢复本机函数地址与原始 C# 名称之间的映射。
Unity 构建中的关键文件
| 文件 | 位置 | 用途 |
|---|---|---|
| 本机二进制文件 | iOS:Frameworks/UnityFramework.framework/UnityFrameworkAndroid: lib/{arch}/libil2cpp.so | 编译后的 C# 代码(Mach-O / ELF) |
| 元数据 | Data/Managed/Metadata/global-metadata.dat | 所有类型、方法和字符串信息 |
工具选择
Il2CppDumper(推荐用于元数据 v39+)
Unity 6+ 构建请使用 v39 分支:
- 仓库:
https://github.com/roytu/Il2CppDumper(分支:v39) - 支持元数据 v24–v39
- 输出包含函数地址的
script.json,可直接导入 IDA/Ghidra
原版 Il2CppDumper(https://github.com/Perfare/Il2CppDumper)最高仅支持 v29。
Cpp2IL(替代方案)
- 仓库:
https://github.com/SamboyCoding/Cpp2IL - 支持元数据 v39,但生成的虚拟 DLL 缺少
[Address]特性 - 适用于重建 C# 源码,不适合导入 IDA
分步工作流
第 1 步:查找 IL2CPP 文件
iOS(IPA):
# Unzip IPA
unzip -o app.ipa -d .
# Binary
BINARY="Payload/<AppName>.app/Frameworks/UnityFramework.framework/UnityFramework"
# Metadata
METADATA="Payload/<AppName>.app/Data/Managed/Metadata/global-metadata.dat"
Android(APK):
# Unzip APK
unzip -o app.apk -d .
# Binary (pick target arch)
BINARY="lib/arm64-v8a/libil2cpp.so"
# Metadata
METADATA="assets/bin/Data/Managed/Metadata/global-metadata.dat"
第 2 步:检查元数据版本
# First 8 bytes: magic (4) + version (4), little-endian
xxd -l 8 "$METADATA"
# Expected: af1b b1fa 2700 0000 → magic OK, version = 0x27 = 39
| 版本 | Unity | 工具 |
|---|---|---|
| ≤ 29 | Unity 2021 及更早版本 | 原版 Il2CppDumper |
| 31 | Unity 2022 | 原版 Il2CppDumper(部分支持) |
| 39 | Unity 6(6000.x) | roytu/Il2CppDumper v39 分支 |
第 3 步:构建并运行 Il2CppDumper(v39 分支)
# Clone v39 fork
git clone -b v39 https://github.com/roytu/Il2CppDumper.git
# Build
cd Il2CppDumper
DOTNET_ROLL_FORWARD=LatestMajor dotnet build -c Release
# Run (use net8.0 framework)
DOTNET_ROLL_FORWARD=LatestMajor dotnet run \
--project Il2CppDumper/Il2CppDumper.csproj \
-c Release --framework net8.0 \
-- "$BINARY" "$METADATA" output_dir
说明:
DOTNET_ROLL_FORWARD=LatestMajor可在 .NET 9/10 上运行,即使项目目标版本是 .NET 6/8- 在非交互模式下,退出代码 134 属正常情况(由末尾的
Console.ReadKey()导致) - 在 macOS 上,如果二进制文件被 SIGKILL 终止,可为其进行临时签名:
codesign -s - <binary>
第 4 步:验证输出
成功运行后,输出目录中会生成以下文件:
| 文件 | 大小(通常) | 用途 |
|---|---|---|
script.json | 50–100 MB | 函数地址、名称和签名(导入 IDA/Ghidra) |
dump.cs | 10–30 MB | 包含 RVA/VA 地址的 C# 类转储 |
il2cpp.h | 50–100 MB | 用于导入类型的 C 结构体定义 |
ida_py3.py | ~2 KB | IDA Python 导入脚本 |
检查 script.json 格式:
{
"ScriptMethod": [
{
"Address": 40865744,
"Name": "ClassName$$MethodName",
"Signature": "ReturnType ClassName__MethodName (args...);",
"TypeSignature": "viii"
}
]
}
检查 dump.cs 格式:
// RVA: 0x1A2B3C4 Offset: 0x1A2B3C4 VA: 0x1A2B3C4
public void MethodName() { }
第 5 步:导入 IDA
- 在 IDA 中打开本机二进制文件(UnityFramework / libil2cpp.so)
- 将
script.json和ida_py3.py放在同一目录中 File → Script file...→ 选择ida_py3.py- 脚本会读取
script.json并自动重命名所有函数 - 可选:
File → Load file → Parse C header file...→ 选择il2cpp.h以导入结构体类型
第 5 步(替代方案):导入 Ghidra
- 在 Ghidra 中打开二进制文件
- 使用 Il2CppDumper 中的
ghidra.py或ghidra_with_struct.py脚本 - 使用
Window → Script Manager → Run运行,并确保script.json位于同一目录中
故障排除
| 错误 | 原因 | 解决方法 |
|---|---|---|
not a supported version[39] | 使用了原版 Il2CppDumper | 切换到 roytu/Il2CppDumper v39 分支 |
| 退出代码 137(SIGKILL) | macOS 二进制文件未签名 | codesign -s - <binary> |
Cannot read keys(退出代码 134) | 非交互式控制台 | 忽略——转储已成功完成 |
DOTNET_ROLL_FORWARD 错误 | .NET 版本不匹配 | 设置 DOTNET_ROLL_FORWARD=LatestMajor |
| 输出为空 | 二进制文件与元数据不匹配 | 确认两个文件来自同一构建 |
输出使用提示
dump.cs是最快捷的参考资料 — 可搜索带有 RVA 地址的类名/方法名script.json中的 Address 值为十进制 — 转换为十六进制后即可用于 IDA:hex(40865744)→0x26F8FD0dump.cs中的字段偏移量(例如// 0x20)相对于对象基址,可用于通过 Frida 检查内存
评论
支持 Markdown