rev-u3d-dump

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

rev-u3d-dump - Unity IL2CPP Symbol Dumper

rev-u3d-dump - Unity IL2CPP符号导出工具

Extract C# method names, addresses, and type definitions from Unity IL2CPP builds for IDA/Ghidra analysis.

从Unity IL2CPP构建包中提取C#方法名、地址及类型定义,用于IDA/Ghidra分析。

Overview

概述

Unity IL2CPP compiles C# to native code. The original class/method names are stripped from the binary but preserved in
global-metadata.dat
. This skill recovers the mapping between native function addresses and their original C# names.
Unity IL2CPP会将C#代码编译为原生代码。二进制文件中会剥离原始的类/方法名,但这些信息会保留在
global-metadata.dat
中。本技能可恢复原生函数地址与其原始C#名称之间的映射关系。

Key Files in Unity Build

Unity构建包中的关键文件

FileLocationPurpose
Native binaryiOS:
Frameworks/UnityFramework.framework/UnityFramework
<br>Android:
lib/{arch}/libil2cpp.so
Compiled C# code (Mach-O / ELF)
Metadata
Data/Managed/Metadata/global-metadata.dat
All type/method/string info

文件位置用途
原生二进制文件iOS:
Frameworks/UnityFramework.framework/UnityFramework
<br>Android:
lib/{arch}/libil2cpp.so
编译后的C#代码(Mach-O / ELF格式)
元数据
Data/Managed/Metadata/global-metadata.dat
包含所有类型、方法、字符串信息

Tool Selection

工具选择

Il2CppDumper (recommended for metadata v39+)

Il2CppDumper(推荐用于元数据v39+版本)

Use the v39 fork for Unity 6+ builds:
  • Repo:
    https://github.com/roytu/Il2CppDumper
    (branch:
    v39
    )
  • Supports metadata v24–v39
  • Outputs
    script.json
    with function addresses — ready for IDA/Ghidra import
The original Il2CppDumper (
https://github.com/Perfare/Il2CppDumper
) only supports up to v29.
针对Unity 6+构建包,请使用v39分支
  • 仓库地址:
    https://github.com/roytu/Il2CppDumper
    (分支:
    v39
  • 支持元数据v24–v39版本
  • 输出包含函数地址的
    script.json
    文件,可直接导入IDA/Ghidra
原版Il2CppDumper(
https://github.com/Perfare/Il2CppDumper
)仅支持最高v29版本。

Cpp2IL (alternative)

Cpp2IL(替代工具)

  • Repo:
    https://github.com/SamboyCoding/Cpp2IL
  • Supports metadata v39, but dummy DLLs lack
    [Address]
    attributes
  • Useful for C# source reconstruction, not ideal for IDA import

  • 仓库地址:
    https://github.com/SamboyCoding/Cpp2IL
  • 支持元数据v39版本,但生成的虚拟DLL缺少
    [Address]
    属性
  • 适用于C#源代码还原,但不适合导入IDA

Step-by-Step Workflow

分步操作流程

Step 1: Locate IL2CPP Files

步骤1:定位IL2CPP文件

iOS (IPA):
bash
undefined
iOS(IPA包):
bash
undefined

Unzip IPA

解压IPA包

unzip -o app.ipa -d .
unzip -o app.ipa -d .

Binary

二进制文件路径

BINARY="Payload/<AppName>.app/Frameworks/UnityFramework.framework/UnityFramework"
BINARY="Payload/<AppName>.app/Frameworks/UnityFramework.framework/UnityFramework"

Metadata

元数据文件路径

METADATA="Payload/<AppName>.app/Data/Managed/Metadata/global-metadata.dat"

**Android (APK):**
```bash
METADATA="Payload/<AppName>.app/Data/Managed/Metadata/global-metadata.dat"

**Android(APK包):**
```bash

Unzip APK

解压APK包

unzip -o app.apk -d .
unzip -o app.apk -d .

Binary (pick target arch)

二进制文件路径(选择目标架构)

BINARY="lib/arm64-v8a/libil2cpp.so"
BINARY="lib/arm64-v8a/libil2cpp.so"

Metadata

元数据文件路径

METADATA="assets/bin/Data/Managed/Metadata/global-metadata.dat"
undefined
METADATA="assets/bin/Data/Managed/Metadata/global-metadata.dat"
undefined

Step 2: Check Metadata Version

步骤2:检查元数据版本

bash
undefined
bash
undefined

First 8 bytes: magic (4) + version (4), little-endian

前8字节:魔数(4字节) + 版本(4字节),小端序

xxd -l 8 "$METADATA"
xxd -l 8 "$METADATA"

Expected: af1b b1fa 2700 0000 → magic OK, version = 0x27 = 39

示例输出:af1b b1fa 2700 0000 → 魔数验证通过,版本 = 0x27 = 39


| Version | Unity | Tool |
|---------|-------|------|
| ≤ 29 | Unity 2021 and earlier | Original Il2CppDumper |
| 31 | Unity 2022 | Original Il2CppDumper (partial) |
| 39 | Unity 6 (6000.x) | **roytu/Il2CppDumper v39 fork** |

| 版本 | 对应Unity版本 | 推荐工具 |
|---------|-------|------|
| ≤ 29 | Unity 2021及更早版本 | 原版Il2CppDumper |
| 31 | Unity 2022 | 原版Il2CppDumper(部分支持) |
| 39 | Unity 6 (6000.x) | **roytu/Il2CppDumper v39分支** |

Step 3: Build & Run Il2CppDumper (v39 fork)

步骤3:构建并运行Il2CppDumper(v39分支)

bash
undefined
bash
undefined

Clone v39 fork

克隆v39分支代码

Build

构建项目

cd Il2CppDumper DOTNET_ROLL_FORWARD=LatestMajor dotnet build -c Release
cd Il2CppDumper DOTNET_ROLL_FORWARD=LatestMajor dotnet build -c Release

Run (use net8.0 framework)

运行工具(使用net8.0框架)

DOTNET_ROLL_FORWARD=LatestMajor dotnet run
--project Il2CppDumper/Il2CppDumper.csproj
-c Release --framework net8.0
-- "$BINARY" "$METADATA" output_dir

**Notes:**
- `DOTNET_ROLL_FORWARD=LatestMajor` allows running on .NET 9/10 even though the project targets .NET 6/8
- Exit code 134 is normal in non-interactive mode (caused by `Console.ReadKey()` at the end)
- On macOS, if the binary gets SIGKILL'd, ad-hoc sign it: `codesign -s - <binary>`
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>`

Step 4: Verify Output

步骤4:验证输出结果

Successful run produces these files in the output directory:
FileSize (typical)Purpose
script.json
50–100 MBFunction addresses + names + signatures (IDA/Ghidra import)
dump.cs
10–30 MBC# class dump with RVA/VA addresses
il2cpp.h
50–100 MBC struct definitions for type import
ida_py3.py
~2 KBIDA Python import script
Check
script.json
format:
json
{
  "ScriptMethod": [
    {
      "Address": 40865744,
      "Name": "ClassName$$MethodName",
      "Signature": "ReturnType ClassName__MethodName (args...);",
      "TypeSignature": "viii"
    }
  ]
}
Check
dump.cs
format:
csharp
// RVA: 0x1A2B3C4 Offset: 0x1A2B3C4 VA: 0x1A2B3C4
public void MethodName() { }
运行成功后,输出目录中会生成以下文件:
文件典型大小用途
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 KBIDA Python导入脚本
检查
script.json
格式:
json
{
  "ScriptMethod": [
    {
      "Address": 40865744,
      "Name": "ClassName$$MethodName",
      "Signature": "ReturnType ClassName__MethodName (args...);",
      "TypeSignature": "viii"
    }
  ]
}
检查
dump.cs
格式:
csharp
// RVA: 0x1A2B3C4 Offset: 0x1A2B3C4 VA: 0x1A2B3C4
public void MethodName() { }

Step 5: Import into IDA

步骤5:导入至IDA

  1. Open the native binary in IDA (UnityFramework / libil2cpp.so)
  2. Place
    script.json
    and
    ida_py3.py
    in the same directory
  3. File → Script file...
    → select
    ida_py3.py
  4. The script reads
    script.json
    and renames all functions automatically
  5. Optional:
    File → Load file → Parse C header file...
    → select
    il2cpp.h
    for struct types
  1. 在IDA中打开原生二进制文件(UnityFramework / libil2cpp.so)
  2. script.json
    ida_py3.py
    放在同一目录下
  3. 点击
    文件 → 脚本文件...
    → 选择
    ida_py3.py
  4. 脚本会读取
    script.json
    并自动重命名所有函数
  5. 可选操作:
    文件 → 加载文件 → 解析C头文件...
    → 选择
    il2cpp.h
    导入结构体类型

Step 5 (alt): Import into Ghidra

步骤5(替代方案):导入至Ghidra

  1. Open the binary in Ghidra
  2. Use the
    ghidra.py
    or
    ghidra_with_struct.py
    script from Il2CppDumper
  3. Window → Script Manager → Run
    with
    script.json
    in the same directory

  1. 在Ghidra中打开二进制文件
  2. 使用Il2CppDumper提供的
    ghidra.py
    ghidra_with_struct.py
    脚本
  3. 点击
    窗口 → 脚本管理器 → 运行
    ,确保
    script.json
    在同一目录下

Troubleshooting

故障排除

ErrorCauseFix
not a supported version[39]
Using original Il2CppDumperSwitch to roytu/Il2CppDumper v39 fork
Exit code 137 (SIGKILL)macOS unsigned binary
codesign -s - <binary>
Cannot read keys
(exit 134)
Non-interactive consoleIgnore — dump completed successfully
DOTNET_ROLL_FORWARD
error
.NET version mismatchSet
DOTNET_ROLL_FORWARD=LatestMajor
Empty outputWrong binary/metadata pairVerify both files are from the same build

错误原因解决方法
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
输出内容为空二进制文件与元数据文件不匹配验证两个文件是否来自同一构建包

Output Usage Tips

输出文件使用技巧

  • dump.cs
    is the quickest reference — search for class/method names with RVA addresses
  • script.json
    Address values are decimal — convert to hex for IDA:
    hex(40865744)
    0x26F8FD0
  • Field offsets in
    dump.cs
    (e.g.,
    // 0x20
    ) are relative to object base, useful for memory inspection with Frida
  • dump.cs
    是最快捷的参考文件——可搜索带有RVA/VA地址的类/方法名
  • script.json
    中的Address值为十进制,需转换为十六进制后在IDA中使用:
    hex(40865744)
    0x26F8FD0
  • dump.cs
    中的字段偏移(如
    // 0x20
    )是相对于对象基地址的偏移量,可结合Frida用于内存检查