尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Unity il2cpp逆向:Il2CppDumper还原符号与避坑指南

发布时间:2026/9/26 17:01:56

资讯中心
01
ARTICLE

Unity il2cpp逆向:Il2CppDumper还原符号与避坑指南

Unity il2cpp逆向:Il2CppDumper还原符号与避坑指南
简介Il2CppDumper-win-v6.7.46 是一款面向 Unity 逆向工程与安全研究人员的实用工具包主要用于还原 il2cpp 编译后的 DLL 文件不含源码可提取 MonoBehaviour 与 MonoScript 信息适用于游戏逆向分析、协议研究及安全评估等场景。该版本支持 ELF、ELF64、Mach-O、PE、NSO 与 WASM 等多种格式兼容 Unity 5.3 至 2020 版本并能生成 IDA 与 Ghidra 分析脚本、结构体头文件同时支持从内存 dump 的 libil2cpp.so 绕过保护及简单 PE 保护。压缩包共 11 个文件包含 8 个 Python 脚本、2 个可执行程序及 1 个 JSON 配置文件脚本用于对接 IDA 与 Ghidra 的自动化分析流程可执行文件为 Windows 平台主程序整体约 10.7MB。目前已有 1035 人学习下载适合具备一定逆向基础、需要快速定位 Unity 游戏逻辑与脚本结构的开发者参考使用。1. 拿到一个 Unity 手游怎么把它的 il2cpp 结构还原出来做 Unity 手游逆向或者安全评估的人大概率都遇到过同一个卡点游戏是 il2cpp 编译的global-metadata.dat和libil2cpp.so摆在面前但里面的类名、方法名、字段偏移全是混淆过的直接扔进 IDA 只能看到一堆sub_xxxxxx。这时候 Il2CppDumper 就是绕不开的一环。它的作用很直接——解析 il2cpp 的元数据把类型、方法、字段、字符串还原成可读的符号再导出成 IDA、Ghidra 能直接加载的脚本。这次拆的是Il2CppDumper-win-v6.7.46Windows 平台的独立版本解压即用不需要额外装 .NET 运行时。适合做 Unity 逆向分析、外挂检测、协议还原、以及想搞清楚 il2cpp 内部结构的人。下面按「它到底怎么工作 → 怎么跑起来 → 参数怎么调 → 哪里会翻车」的顺序走一遍。2. Il2CppDumper 的解析链路从 metadata 到可读符号2.1 il2cpp 到底把什么藏起来了Unity 用 il2cpp 后端编译时C# 代码先被转成 CIL再由 il2cpp 编译器转成 C最后编译成原生机器码。这个过程里原本的类名、方法名、字段名不会直接出现在二进制里而是被压缩进一个叫global-metadata.dat的文件。这个文件里存的是字符串表、类型定义、方法定义、字段定义、以及各种索引关系。libil2cpp.soAndroid或GameAssembly.dllWindows里则存的是这些元数据的运行时结构体和函数指针。Il2CppDumper 干的事就是读global-metadata.dat的头部识别 Unity 版本对应的元数据格式然后按格式把字符串表、类型表、方法表、字段表全部解出来。解出来之后它还要跟libil2cpp.so里的函数地址做对应——因为元数据里只有方法索引没有实际地址地址要从二进制里根据 il2cpp 的导出函数和代码特征去推。注意不同 Unity 版本的 metadata 格式有差异v6.7.46 这个版本内置了从 Unity 5.x 到 2022.x 的格式定义但遇到特别新的 Unity 版本仍然可能识别失败。2.2 版本匹配是第一步也是最容易忽略的一步Il2CppDumper 在启动时会先读 metadata 的 magic 和 version 字段。如果版本号不在它支持的列表里会直接报Unsupported metadata version。这时候不是工具坏了而是 metadata 格式变了。常见的做法是去 Unity 官方仓库找对应版本的il2cpp-metadata.h看结构体有没有新增字段然后手动在 Il2CppDumper 的Il2CppGlobalMetadataHeader里补上。实际操作中大部分手游用的是 Unity 2019 到 2021 之间的 LTS 版本v6.7.46 对这些版本的支持是稳定的。如果拿到的是 Unity 2022 之后的包建议先确认 metadata 版本号再动手。2.3 解析流程拆成四步整个解析链路可以拆成四步读 metadata 头部拿到字符串表偏移、类型表偏移、方法表偏移、字段表偏移等关键指针。解字符串表把压缩的字符串按索引还原成 UTF-8 文本这一步决定了后面类名和方法名能不能读。解类型和方法定义按索引关系把类型、方法、字段串起来构建出完整的类型树。匹配二进制地址在libil2cpp.so里找il2cpp_codegen_register或者通过导出函数il2cpp_domain_get等定位代码段再把方法索引映射到实际地址。这四步里第三步和第四步是最容易出问题的。第三步如果 metadata 被做过加密或者混淆字符串表可能读出来是乱码第四步如果二进制被加固过代码段可能被抽走或者加密地址匹配就会失败。3. Windows 下跑通 Il2CppDumper文件准备与参数配置3.1 文件准备两个输入缺一不可Il2CppDumper 需要两个输入文件global-metadata.dat通常在 Android 包的assets/bin/Data/Managed/Metadata/目录下或者 Windows 游戏的*_Data/il2cpp_data/Metadata/目录下。libil2cpp.so或GameAssembly.dllAndroid 在lib/arm64-v8a/或lib/armeabi-v7a/下Windows 在游戏根目录。把这两个文件放到同一个目录然后打开Il2CppDumper.exe它会弹出文件选择框。先选global-metadata.dat再选libil2cpp.so。选完之后它会自动开始解析解析结果输出到output目录。提示如果 metadata 文件被加密过直接选会报Metadata file is encrypted。这时候需要先脱壳或者解密Il2CppDumper 本身不负责解密。3.2 命令行模式批量处理和自动化图形界面适合单次操作但如果要批量处理多个包命令行模式更顺手。v6.7.46 支持通过参数直接指定输入和输出Il2CppDumper.exe global-metadata.dat libil2cpp.so output_dir三个参数分别是 metadata 路径、二进制路径、输出目录。如果省略输出目录默认在当前目录下建output文件夹。命令行模式下不会弹窗适合写进脚本里批量跑。参数说明第一个参数必须是global-metadata.dat的完整路径不支持通配符。第二个参数是libil2cpp.so或GameAssembly.dll如果传的是目录它会自动在目录里找同名文件。第三个参数可选不传就用默认值。3.3 输出文件怎么用IDA 和 Ghidra 的加载方式解析完成后output目录里会生成几个关键文件文件名用途加载方式dump.cs还原后的 C# 伪代码包含类、方法、字段定义直接文本查看script.pyIDA 脚本用于还原符号名IDA 中 File → Script file 加载il2cpp.hC 头文件包含结构体定义配合 IDA 类型导入stringliteral.json字符串字面量映射按需查阅script.py是最常用的。在 IDA 里加载libil2cpp.so之后跑一遍这个脚本原本的sub_xxxxxx就会变成ClassName__MethodName这样的可读符号。Ghidra 的话用ghidra.py如果有或者手动导入il2cpp.h里的类型定义。注意脚本加载前要确保 IDA 的基址和 Il2CppDumper 解析时用的基址一致。如果二进制有重定位脚本里的地址可能对不上需要手动调ImageBase。3.4 参数调优什么时候需要改默认配置Il2CppDumper 的默认配置对大多数包都够用但遇到以下几种情况需要手动调二进制被加固如果libil2cpp.so的代码段被加密地址匹配会失败。这时候可以尝试用--no-address参数只导出元数据不匹配地址。metadata 版本不识别用--force-version强制指定版本号比如--force-version 24.1。输出符号太多用--filter只导出指定命名空间或类名的方法减少dump.cs的体积。这些参数在命令行模式下通过--help可以看完整列表。图形界面下没有暴露所有参数建议复杂场景直接用命令行。4. 避坑记录解析失败、符号错乱、地址对不上4.1 报Unsupported metadata version怎么办现象启动后直接弹窗报错提示 metadata 版本不支持。原因Unity 版本太新v6.7.46 内置的格式定义里没有这个版本号。或者 metadata 头部被改过版本字段是伪造的。解决先用十六进制编辑器打开global-metadata.dat看偏移0x04处的 4 字节版本号。如果是正常版本号但工具不认去 Il2CppDumper 的 GitHub 仓库看有没有更新如果版本号是乱码说明 metadata 被加密了需要先脱壳。4.2 解析成功但dump.cs里全是乱码现象dump.cs能生成但类名和方法名都是\uXXXX或者问号。原因字符串表被加密或者压缩算法变了。有些游戏会对 metadata 的字符串表做异或或者 AES 加密Il2CppDumper 读出来的是密文。解决这种情况工具本身解决不了需要先定位解密函数。常见做法是在libil2cpp.so里找il2cpp::vm::MetadataCache::Initialize或者MetadataLoader::LoadMetadataFile看它在读文件之后做了什么变换。找到解密逻辑后手动解密一份 metadata 再喂给 Il2CppDumper。4.3 IDA 脚本加载后符号还是sub_xxxxxx现象script.py跑完了但 IDA 里的函数名没变。原因最常见的是基址不对。Il2CppDumper 解析时用的基址是0x0但 IDA 加载 so 时默认基址可能是0x100000或者其他值。另一个原因是脚本里的地址是文件偏移而 IDA 里是虚拟地址两者没对上。解决在 IDA 里按CtrlS看当前段的基址然后在脚本开头找到base_address变量改成 IDA 里的实际基址。如果脚本里用的是文件偏移需要先做偏移到虚拟地址的转换。4.4 方法地址全是0x0或者负数现象dump.cs里方法定义有了但地址字段全是0x0或者-1。原因二进制里没有找到对应的代码段。可能是 so 被抽代码了或者 Il2CppDumper 用的匹配特征在这个版本上失效了。解决先确认libil2cpp.so是不是完整的。用readelf -S看代码段大小如果.text段特别小说明被抽了。如果 so 是完整的尝试用--no-address只导出元数据地址匹配的事交给 IDA 手动做。4.5 输出目录里没有script.py现象解析完成了但output目录里只有dump.cs没有script.py。原因Il2CppDumper 在地址匹配阶段失败了它认为没有足够的地址信息来生成脚本所以跳过了。解决检查libil2cpp.so的架构是否和 metadata 匹配。比如 metadata 是 64 位的但 so 是 32 位的就会匹配失败。另外确认 so 没有被压缩或者加密用file命令看是不是标准的 ELF。5. 进阶技巧用 dump.cs 做批量符号还原和差异对比5.1 从 dump.cs 提取方法偏移做批量 Hookdump.cs里的方法定义格式是固定的可以用脚本批量提取方法名和偏移生成 Frida Hook 脚本。比如下面这段 Python 从dump.cs里抽方法地址import re # dump.cs 里方法行的典型格式 # // RVA: 0x123456 Offset: 0x123456 VA: 0x123456 # public static void SomeMethod() {} pattern re.compile(r// RVA: (0x[0-9A-Fa-f]) Offset: (0x[0-9A-Fa-f]) VA: (0x[0-9A-Fa-f])\s*\n\s*(?:public|private|protected|internal).*?(\w)\s*\() with open(dump.cs, r, encodingutf-8) as f: content f.read() matches pattern.findall(content) for rva, offset, va, name in matches: # 这里只打印方法名和 RVA实际使用时可以生成 Frida 的 Interceptor.attach print(f{name}: RVA{rva}, VA{va})这段代码的逻辑是用正则匹配dump.cs里每个方法前面的注释行提取 RVA、Offset、VA 三个地址再抓方法名。参数说明RVA是相对虚拟地址VA是绝对虚拟地址Hook 时一般用VA减去基址得到偏移。实际生成 Frida 脚本时把VA填进Module.findBaseAddress(libil2cpp.so).add(offset)就行。提示不同版本的 Il2CppDumper 输出的注释格式可能略有差异跑之前先看几行确认正则能匹配上。5.2 用 diff 对比两个版本的符号变化做游戏更新分析时经常需要对比两个版本的dump.cs看哪些方法新增了、哪些删了、哪些偏移变了。直接 diff 文本噪音太大可以先把方法名和偏移提取成结构化数据再比# 提取方法名和 VA按方法名排序 grep -oP (?VA: )0x[0-9A-Fa-f].*?\K\w(?\() dump_old.cs | sort old_methods.txt grep -oP (?VA: )0x[0-9A-Fa-f].*?\K\w(?\() dump_new.cs | sort new_methods.txt # 对比差异 diff old_methods.txt new_methods.txt这个思路适合快速定位新增方法。如果要对比偏移变化把 VA 也一起提取出来用join按方法名合并两个文件再比。5.3 验证解析结果是否可信解析完之后怎么确认结果是对的我一般会做三个检查字符串抽查在stringliteral.json里搜几个游戏里确定存在的字符串比如 UI 文本、错误提示看能不能搜到。方法数量对比dump.cs里的方法总数应该和 metadata 里的方法表条目数接近差太多说明解析不完整。IDA 交叉验证随便挑一个方法在 IDA 里跳到对应地址看反汇编出来的逻辑和dump.cs里的方法签名是否吻合。这三个检查做完基本能判断这次解析是不是靠谱。从那以后我每次拿到新的 il2cpp 包都强制先跑一遍字符串抽查确认 metadata 没被加密再往下做。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。