Reverse-skills rev-u3d-dump
Dump Unity IL2CPP symbols from iOS/Android builds. Extract method names, addresses, and type info from IL2CPP binaries and global-metadata.dat, then generate IDA/Ghidra import scripts.
install
source · Clone the upstream repo
git clone https://github.com/P4nda0s/reverse-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/P4nda0s/reverse-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/rev-u3d-dump" ~/.claude/skills/p4nda0s-reverse-skills-rev-u3d-dump && rm -rf "$T"
manifest:
skills/rev-u3d-dump/SKILL.mdsource content
rev-u3d-dump - Unity IL2CPP Symbol Dumper
Extract C# method names, addresses, and type definitions from Unity IL2CPP builds for IDA/Ghidra analysis.
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.
Key Files in Unity Build
| File | Location | Purpose |
|---|---|---|
| Native binary | iOS: <br>Android: | Compiled C# code (Mach-O / ELF) |
| Metadata | | All type/method/string info |
Tool Selection
Il2CppDumper (recommended for metadata v39+)
Use the v39 fork for Unity 6+ builds:
- Repo:
(branch:https://github.com/roytu/Il2CppDumper
)v39 - Supports metadata v24–v39
- Outputs
with function addresses — ready for IDA/Ghidra importscript.json
The original Il2CppDumper (
https://github.com/Perfare/Il2CppDumper) only supports up to v29.
Cpp2IL (alternative)
- Repo:
https://github.com/SamboyCoding/Cpp2IL - Supports metadata v39, but dummy DLLs lack
attributes[Address] - Useful for C# source reconstruction, not ideal for IDA import
Step-by-Step Workflow
Step 1: Locate IL2CPP Files
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"
Step 2: Check Metadata Version
# First 8 bytes: magic (4) + version (4), little-endian xxd -l 8 "$METADATA" # Expected: af1b b1fa 2700 0000 → magic OK, version = 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 |
Step 3: Build & Run Il2CppDumper (v39 fork)
# 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
Notes:
allows running on .NET 9/10 even though the project targets .NET 6/8DOTNET_ROLL_FORWARD=LatestMajor- Exit code 134 is normal in non-interactive mode (caused by
at the end)Console.ReadKey() - On macOS, if the binary gets SIGKILL'd, ad-hoc sign it:
codesign -s - <binary>
Step 4: Verify Output
Successful run produces these files in the output directory:
| File | Size (typical) | Purpose |
|---|---|---|
| 50–100 MB | Function addresses + names + signatures (IDA/Ghidra import) |
| 10–30 MB | C# class dump with RVA/VA addresses |
| 50–100 MB | C struct definitions for type import |
| ~2 KB | IDA Python import script |
Check
script.json format:
{ "ScriptMethod": [ { "Address": 40865744, "Name": "ClassName$$MethodName", "Signature": "ReturnType ClassName__MethodName (args...);", "TypeSignature": "viii" } ] }
Check
dump.cs format:
// RVA: 0x1A2B3C4 Offset: 0x1A2B3C4 VA: 0x1A2B3C4 public void MethodName() { }
Step 5: Import into IDA
- Open the native binary in IDA (UnityFramework / libil2cpp.so)
- Place
andscript.json
in the same directoryida_py3.py
→ selectFile → Script file...ida_py3.py- The script reads
and renames all functions automaticallyscript.json - Optional:
→ selectFile → Load file → Parse C header file...
for struct typesil2cpp.h
Step 5 (alt): Import into Ghidra
- Open the binary in Ghidra
- Use the
orghidra.py
script from Il2CppDumperghidra_with_struct.py
withWindow → Script Manager → Run
in the same directoryscript.json
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| Using original Il2CppDumper | Switch to roytu/Il2CppDumper v39 fork |
| Exit code 137 (SIGKILL) | macOS unsigned binary | |
(exit 134) | Non-interactive console | Ignore — dump completed successfully |
error | .NET version mismatch | Set |
| Empty output | Wrong binary/metadata pair | Verify both files are from the same build |
Output Usage Tips
is the quickest reference — search for class/method names with RVA addressesdump.cs
Address values are decimal — convert to hex for IDA:script.json
→hex(40865744)0x26F8FD0- Field offsets in
(e.g.,dump.cs
) are relative to object base, useful for memory inspection with Frida// 0x20