从二进制迷雾到代码结构:Il2CppDumper与REHex的可视化逆向工程实践
引言:Unity逆向工程的双重挑战
你是否曾面对Unity游戏的二进制文件感到无从下手?当global-metadata.dat与libil2cpp.so摆在面前,如何将这些字节流转化为可理解的C#代码结构?传统静态分析工具往往止步于十六进制转储,而单纯的反编译又缺失内存布局上下文。本文将展示如何通过Il2CppDumper(Unity专用逆向工具)与REHex(高级二进制编辑器)的协同工作流,突破二进制数据的可视化分析难题,让你在30分钟内从原始字节跃迁至函数调用流程图。
读完本文你将掌握:
- 利用Il2CppDumper精准定位元数据与代码注册信息
- 使用REHex的可视化特性识别二进制文件中的关键结构
- 构建从内存地址到C#类定义的完整映射链路
- 实战分析Android平台libil2cpp.so文件的核心技巧
技术准备:工具链与环境配置
基础工具清单
| 工具 | 功能 | 版本要求 | 获取方式 |
|---|---|---|---|
| Il2CppDumper | 解析il2cpp二进制与元数据 | ≥6.7.0 | git clone https://gitcode.com/gh_mirrors/il/Il2CppDumper |
| REHex | 二进制可视化编辑 | ≥0.6.0 | 官方网站下载 |
| .NET SDK | 编译Il2CppDumper | 6.0+ | Microsoft官网 |
| 7-Zip | 提取APK内文件 | 任意 | 官方网站 |
Il2CppDumper编译流程
# 克隆仓库
git clone https://gitcode.com/gh_mirrors/il/Il2CppDumper
cd Il2CppDumper
# 使用.NET SDK构建
dotnet build Il2CppDumper/Il2CppDumper.csproj -c Release -o bin
# 验证构建结果
ls bin/Il2CppDumper.exe # Windows
# 或
ls bin/Il2CppDumper # Linux/macOS
核心原理:Il2Cpp二进制结构解析
Il2Cpp编译流程回顾
Unity使用il2cpp技术将C#代码编译为原生二进制时,会生成两个关键文件:
- libil2cpp.so(或对应平台的可执行文件):包含AOT编译的原生代码
- global-metadata.dat:存储类型、方法、字段等元数据信息
关键数据结构在二进制中的分布
Il2CppDumper通过识别以下关键结构实现逆向:
CodeRegistration:函数指针表,存储所有C#方法的原生实现地址MetadataRegistration:元数据注册表,关联类型定义与内存布局Il2CppTypeDefinition:类型定义结构,包含类名、父类、字段偏移等信息
这些结构在不同平台二进制中的签名特征:
| 平台 | CodeRegistration特征 | MetadataRegistration特征 |
|---|---|---|
| Windows(PE) | 0x00 00 00 00 01 00 00 00 | 0x01 00 00 00 00 00 00 00 |
| Linux(ELF) | 0x00 00 00 00 02 00 00 00 | 0x02 00 00 00 00 00 00 00 |
| Android(ELF) | 0x00 00 00 00 03 00 00 00 | 0x03 00 00 00 00 00 00 00 |
实战流程:从APK到类结构图
步骤1:提取目标文件
以Android游戏APK为例,使用7-Zip提取关键文件:
# 创建工作目录
mkdir il2cpp_analysis && cd il2cpp_analysis
# 提取libil2cpp.so和global-metadata.dat
7z x target.apk lib/armeabi-v7a/libil2cpp.so assets/bin/Data/Managed/Metadata/global-metadata.dat -oextracted
步骤2:使用Il2CppDumper生成分析数据
# 执行基础分析
Il2CppDumper/bin/Il2CppDumper extracted/lib/armeabi-v7a/libil2cpp.so extracted/global-metadata.dat output
# 关键输出文件说明
ls output/
# il2cpp.h - 类型定义头文件
# script.json - 元数据JSON
# dummy.dll - 模拟程序集(用于反编译)
Il2CppDumper的工作流程可通过其Program.cs核心代码理解:
// 初始化元数据解析
var metadataBytes = File.ReadAllBytes(metadataPath);
metadata = new Metadata(new MemoryStream(metadataBytes));
// 根据文件魔术字识别可执行格式
switch (il2cppMagic)
{
case 0x464c457f: // ELF格式
il2Cpp = (il2cppBytes[4] == 2) ? new Elf64(il2CppMemory) : new Elf(il2CppMemory);
break;
case 0x905A4D: // PE格式
il2Cpp = new PE(il2CppMemory);
break;
// 其他平台格式处理...
}
// 搜索关键结构
var flag = il2Cpp.PlusSearch(metadata.methodDefs.Count, metadata.typeDefs.Length, metadata.imageDefs.Length);
if (!flag) flag = il2Cpp.Search();
if (!flag) flag = il2Cpp.SymbolSearch();
步骤3:REHex可视化分析二进制文件
导入数据与基础配置
- 启动REHex并打开
libil2cpp.so - 配置偏移显示:
视图 > 偏移格式 > 十六进制 - 设置编码:
编辑 > 编码 > UTF-8 - 启用网格视图:
视图 > 显示网格
定位CodeRegistration结构
使用Il2CppDumper输出的script.json查找CodeRegistration地址:
{
"CodeRegistration": "0x00123450",
"MetadataRegistration": "0x006789A0",
// ...
}
在REHex中跳转到该地址(Ctrl+G),观察其内存布局:
00123450: 00 00 00 00 03 00 00 00 50 78 90 00 00 00 00 00 ........Px......
00123460: A0 BC DE F0 12 34 56 78 90 AB CD EF 01 23 45 67 ............#Eg
通过REHex的"模式匹配"功能(搜索 > 查找十六进制)验证特征序列:
- 搜索
00 00 00 00 03 00 00 00(Android平台CodeRegistration签名)
分析方法表结构
CodeRegistration后紧跟方法指针表,每个条目为4字节(32位)或8字节(64位)地址:
在REHex中创建书签标记关键函数地址(编辑 > 添加书签),并使用"注释"功能记录方法名。
步骤4:构建内存地址与代码的映射关系
使用Il2CppDumper生成的头文件
il2cpp.h包含完整的类型定义,例如:
struct Il2CppClass {
void* klass;
void* monitor;
Il2CppType* type;
Il2CppMetadataTypeHandle type_handle;
// ... 其他字段
};
在REHex中,使用"结构解析"功能(工具 > 结构解析)导入此头文件,实现二进制数据到结构体字段的自动映射。
可视化类继承关系
结合REHex的"区域高亮"与Il2CppDumper输出的类型信息,创建类继承关系图:
高级技巧:复杂场景处理
处理加密/压缩的元数据
部分游戏会对global-metadata.dat进行加密或压缩,可通过以下方法识别:
-
在REHex中检查文件头部是否有已知压缩算法签名:
- LZ4:
0x04 0x22 0x4D 0x18 - ZLIB:
0x78 0xDA(默认压缩) 或0x78 0x01(无压缩)
- LZ4:
-
使用Il2CppDumper的强制版本模式绕过加密检测:
Il2CppDumper --force-version 24 libil2cpp.so encrypted_metadata.dat output
64位与32位二进制的差异分析
| 维度 | 32位二进制 | 64位二进制 |
|---|---|---|
| 指针大小 | 4字节 | 8字节 |
| CodeRegistration特征 | 00 00 00 00 02 00 00 00 | 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 |
| 方法表条目大小 | 4字节 | 8字节 |
| REHex偏移显示 | 32位十六进制 | 64位十六进制 |
在REHex中可通过编辑 > 数据解释 > 位数切换解析模式。
动态调试与静态分析结合
- 使用Il2CppDumper生成Ghidra脚本:
Il2CppDumper --ghidra libil2cpp.so global-metadata.dat output
-
在Ghidra中加载生成的脚本,获取函数名与参数信息
-
在REHex中标记Ghidra识别的函数起始地址,形成完整分析闭环
常见问题解决方案
Il2CppDumper无法识别文件格式
症状:ERROR: il2cpp file not supported.
解决步骤:
-
在REHex中检查文件头部魔术字:
- ELF:
7F 45 4C 46 - PE:
4D 5A - Mach-O:
CF FA ED FE
- ELF:
-
确认Il2CppDumper支持对应格式,必要时更新到最新版本:
git pull origin master
dotnet build -c Release
REHex中中文显示乱码
解决方案:
- 确认元数据编码:
工具 > 编码检测器 - 手动设置正确编码:
编辑 > 编码 > GBK(针对部分中文游戏) - 使用"字符串提取"工具:
工具 > 提取字符串 > 设置最小长度: 4
总结与后续学习路径
通过Il2CppDumper与REHex的协同工作,我们实现了从原始二进制到代码结构的完整解析。关键收获包括:
- 工具互补性:Il2CppDumper提供精准的元数据分析,REHex则擅长二进制可视化与手动探索
- 结构识别能力:掌握了Il2Cpp关键结构的签名特征与内存布局
- 分析流程标准化:建立从文件提取到代码还原的可复用工作流
进阶学习资源
- Il2Cpp内部机制:研究
Il2Cpp/Il2CppClass.cs源码了解类型系统实现 - REHex脚本开发:使用其内置JavaScript引擎编写自定义分析脚本
- 自动化分析:结合Python与
script.json批量处理函数地址映射
行动建议
立即选择一个Unity游戏APK,应用本文介绍的方法完成以下任务:
- 提取并分析
libil2cpp.so与global-metadata.dat - 使用REHex定位至少3个关键游戏类的
Il2CppClass结构 - 构建一个简单的函数调用流程图,展示游戏主循环
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



