关于 Unity 的 IL2CPP 打包后反编译探索

  1. 本人反编译仅作学习用途。
  2. 应相关要求,下文所提及的有关所有软件及程序的下载不附地址,仅提供名字(包含模糊化名字)。
  3. 以下内容仅为作者个人理解,不专业表达请谅解!

IL2CPP 打包概述

  IL2CPP 后端打包包含 C# 转 C++ 的过程,除方法名以外全部代码混淆,即,通过函数抽取对代码进行加固。

  打包后各脚本存放在 APK 包目录下的 classes.dex,IL2CPP 打包格式及调用逻辑在 apk/lib/游戏名/libil2cpp.so,各脚本的方法体存放在 apk/assets/bin/Data/Managed/Metadata/global-metadata.dat

  IL2CPP 打包后的游戏,最多只能用反编译软件(例 Asset Studio)还原各脚本的变量名和函数名,不能还原函数体的源代码。这是最大程度地还原可阅读脚本逻辑。

  示例其中一个脚本的空函数情况如下:

反编译函数体

  函数体可以反编译出来,但是最多只能还原成混淆后反编译成汇编语言,再切换成 C 语言,可以定位及修改相关变量,不能还原成源码,仅用于学习。具体操作如下。

  1. IL2CPP Dumper 打开 libil2cpp.so,接着打开 global-metadata.dat
  2. 进入反编译进程,导出 dump.cs

  1. 用编译器(例 VS)打开 dump.cs,在里面找到自己所需要的方法名的 offset

  1. IDA 导入分析 libil2cpp.so,按 G 输入 offset 搜索位置。

  1. 跳转到 游戏运行时调用方法体的 汇编语言。

  1. F5 转成C语言查看。

  1. 也可继续转到 4DDA94 方法。

  即使还原到这样,已经是最大程度的可阅读代码了,但看起来仍然晦涩难懂。有兴趣的可以继续跳转,最终会抵达 Unity 的各种方法。

止步于此,因为作者目的不是修改数据及破解游戏,后续断点调试定位变量不做深入学习与探讨。


其他反编译方法

jar2dex 反编译 classes.dex

  1. classes.dex 复制到 j2d 软件包目录下,Win + R 输入 cmd 打开控制台。
  2. cd j2d目录 进入该目录。
  3. 运行:
    1
    d2j-dex2jar d classes.dex
  4. 在目录下导出 classes-dex2jar.jar,然后用 JD-GUI 查看。

此方法也只能看到空方法体的脚本而已,此方法各函数已混淆为 abcd...,导致代码可读性低。

上述过程已有一站式软件,如 JADX-GUI


APKTool 反编译 APK

APKTool 反编译后也只能还原为il2cpp打包后的包,所以方法体的代码已经被加固混淆。操作如下:

  1. apkapktool 置于同目录下。
  2. Win + Rcmd 打开控制台,进入文件夹目录。
  3. 输入命令执行 jar 程序:
    1
    java -jar apktool.jar d xxx.apk
  4. 反编译完成后,在目录下生成 xxx.apk/ 文件夹。


MetaDataStringEditor 分析 global-metadata.dat

MetaDataStringEditor软件可以分析并可视化global-metadata.dat文件的字符串,可以作为软件汉化工具。


总结

  il2cpp打包后,反编译还原不了方法体的源代码,最多只能还原脚本内声明的变量名及个方法的函数名。最多最多只能还原出剔除方法体或空方法体或return null的脚本工程demo进行学习。

📌 本文仅作学习交流,严禁用于非法用途!