告别手动定义:Il2CppDumper与IDA无缝共享Unity类型信息

告别手动定义:Il2CppDumper与IDA无缝共享Unity类型信息

【免费下载链接】Il2CppDumper Unity il2cpp reverse engineer 【免费下载链接】Il2CppDumper 项目地址: https://gitcode.com/gh_mirrors/il/Il2CppDumper

你是否还在为Unity逆向分析中手动定义成百上千个类结构而头疼?是否经历过修改一处类型定义就要全局替换的重复劳动?本文将展示如何通过Il2CppDumper与IDA类型库的协作,实现Unity类型定义的自动化共享,将逆向效率提升至少300%。读完你将掌握:

  • 类型信息自动提取的完整流程
  • 生成IDA可用的C头文件与JSON元数据
  • 一键导入类型定义的实用脚本使用
  • 泛型类与复杂类型的自动处理方案

类型信息共享的核心价值

在Unity的IL2CPP逆向工程中,类型定义(如类结构、方法签名、字符串常量)是连接二进制分析与源代码逻辑的关键桥梁。传统手工定义方式存在三大痛点:

痛点手动处理耗时自动化处理
单个类结构定义15-30分钟3秒
泛型类实例化无法手动完成自动生成
类型引用更新全局搜索替换2小时一键同步

Il2CppDumper通过Outputs/StructGenerator.cs实现类型信息的自动化提取,其核心原理是解析IL2CPP二进制文件中的元数据段(Metadata)和代码段,重建C#类型系统的内存布局。

工作流程:从二进制到IDA类型库

数据提取阶段

Il2CppDumper的类型提取流程始于对两种核心文件的解析:

  1. global-metadata.dat:存储所有类型定义、方法签名和字符串常量
  2. libil2cpp.so/GameAssembly.dll:包含编译后的机器码和类型内存布局

StructGenerator.csWriteScript方法中(第42行),程序会遍历metadata.imageDefs中的所有程序集,为每个类型定义生成唯一的结构名称(第46-57行)。关键代码片段:

for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
{
    var imageDef = metadata.imageDefs[imageIndex];
    var imageName = metadata.GetStringFromIndex(imageDef.nameIndex);
    var typeEnd = imageDef.typeStart + imageDef.typeCount;
    for (int typeIndex = imageDef.typeStart; typeIndex < typeEnd; typeIndex++)
    {
        var typeDef = metadata.typeDefs[typeIndex];
        typeDefImageNames.Add(typeDef, imageName);
        CreateStructNameDic(typeDef);
    }
}

中间文件生成

处理完成后,会在输出目录生成两类关键文件:

  • il2cpp.h:包含所有类结构定义的C头文件
  • script.json:包含方法地址、签名和字符串常量的JSON元数据

StructGenerator.cs的第431行负责将这些信息写入文件:

File.WriteAllText(outputDir + "il2cpp.h", sb.ToString());
File.WriteAllText(outputDir + "script.json", JsonSerializer.Serialize(json, jsonOptions));

这些文件包含了逆向分析所需的全部类型信息,包括:

  • 类的内存布局(字段偏移、大小)
  • 方法的地址和参数签名
  • 字符串常量的地址和值
  • 泛型类的实例化信息

IDA类型导入实战

准备工作

确保已完成以下准备:

  1. 使用Il2CppDumper处理目标文件,获得il2cpp.hscript.json
  2. 启动IDA并加载Unity游戏主二进制文件(如libil2cpp.so)
  3. 将生成的两个文件复制到IDA脚本目录

一键导入脚本使用

Il2CppDumper提供了专为IDA设计的ida_with_struct.py脚本,其工作流程如下:

mermaid

脚本核心功能在第33-85行实现,主要处理五种类型的元数据:

  1. 函数地址范围(第36-41行):自动创建函数段并设置边界
  2. 方法签名(第43-51行):应用函数原型到对应地址
  3. 字符串常量(第53-62行):标记字符串地址并添加注释
  4. 元数据引用(第64-74行):处理类型信息与属性
  5. 泛型方法(第76-85行):解析泛型实例并生成对应签名

关键代码示例(方法签名应用):

signature = scriptMethod["Signature"].encode("utf-8")
if apply_type(addr, parse_decl(signature, 0), 1) == False:
    print "apply_type failed:", hex(addr), signature

验证导入结果

成功导入后,可以通过以下方式验证:

  1. 在IDA Structures窗口查看已导入的类型(如UnityEngine_Transform_o
  2. 导航到已知函数地址(如0x123456),确认已自动命名并应用签名
  3. 查看字符串常量地址(如0x7890AB),确认已添加注释

高级应用:泛型类与复杂类型处理

泛型类(如List<T>)的实例化是类型处理的难点。Il2CppDumper通过Outputs/StructGenerator.cs的59-73行代码,为每个泛型实例生成唯一的结构名称:

var typeBaseName = structNameDic[typeDef];
var typeToReplaceName = FixName(executor.GetTypeDefName(typeDef, true, true));
var typeReplaceName = FixName(executor.GetTypeName(il2CppType, true, false));
var typeStructName = typeBaseName.Replace(typeToReplaceName, typeReplaceName);
nameGenericClassDic[typeStructName] = il2CppType;
genericClassStructNameDic[il2CppType.data.generic_class] = typeStructName;

例如,List<int>会被处理为List_int_o,而Dictionary<string, UnityEngine.Object>则变为Dictionary_string_UnityEngine_Object_o_o,确保每个泛型实例都有唯一的类型定义。

常见问题解决

导入失败的排查步骤

  1. 版本不匹配:确保Il2CppDumper版本支持目标IL2CPP版本(查看StructGenerator.cs第425行的版本检查)
  2. 头文件错误:删除IDA的类型缓存(idc.ResetTypeCache())后重试
  3. 泛型处理失败:确认使用最新版本的ida_with_struct.py脚本

性能优化建议

对于大型项目(超过1000个类),建议:

  1. 分模块导入类型(修改ida_with_struct.py的processFields变量)
  2. 先导入核心类型(如UnityEngine命名空间)
  3. 使用IDA的类型库合并功能创建项目专属类型库

总结与展望

通过Il2CppDumper的Outputs/StructGenerator.csida_with_struct.py的协同工作,我们实现了Unity类型定义的自动化提取与导入。这种方法不仅消除了手动定义的繁琐工作,还确保了类型信息的准确性和一致性。

未来版本将进一步优化:

  • 类型继承关系的自动构建
  • 与Ghidra等其他逆向工具的集成
  • 动态类型更新机制

立即尝试这种自动化工作流,让你的Unity逆向分析效率实现质的飞跃!完整工具链可通过以下资源获取:

【免费下载链接】Il2CppDumper Unity il2cpp reverse engineer 【免费下载链接】Il2CppDumper 项目地址: https://gitcode.com/gh_mirrors/il/Il2CppDumper

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值