逆向
引路人
unity引擎基于Windows下的il2cpp逆向初探——以CTF赛题为例-先知社区
[原创]IL2CPP 逆向初探-软件逆向-看雪安全社区|专业技术交流与安全研究论坛
dnspy
反编译C#相关程序,反编译修改后需要保存模块以应用到目标程序。
IDA激活
需要自行配备python3.8以上环境,IDA安装时会自动检测。
磁力链接下载IDA9.1
magnet:?xt=urn:btih:f24cfadb8a66b343bf1ff4f0c1386a5f6991c818&dn=ida91
激活方式,生成License
ThatNotEasy/IDA-Patcher: IDA Pro Patcher & License Generator
main第28行写错了,修改为
end_year = args.end_date or (now.year + 10)
执行命令参数为安装目录,也就是ida.exe的根目录
python main.py -p "D:\Tools\IDA"
成功激活后如下

Zygisk-Il2CppDumper
下载Magisk工具Release Magisk (f9f02c65) (30403) · ayasa520/Magisk
【安卓模拟器安装 Magisk30.4】 https://www.bilibili.com/video/BV1PYWHzCEjE/?share_source=copy_web&vd_source=05320767bb904def1ce7c1e88823462a
获取游戏包名称,以mumu模拟器为例,在这个路径的文件夹名称就是包名。

Fork本体violet-wdream/Zygisk-Il2CppDumper: Using Zygisk to dump il2cpp data at runtime,不需要下载,然后在你Fork的分支actions里面输入包名,构建文件。
原仓库使用的actions太久了需要改成v4版本,修改了build.yml
- uses: actions/upload-artifact@v4

Workflow runs · violet-wdream/Zygisk-Il2CppDumper放置少女jp.glee.girl构建结果模块
安装构建的模块。

启动游戏,会在/data/data/GamePackageName/files/目录下生成dump.cs
这里使用mumu模拟器自带的root explorer查看。选中后选择压缩就会发送到可直接查看的目录/storage/emulated/0/SpeedSoftware/Archives

本机的根目录。

Il2CppDumper
和Zygisk-Il2CppDumper二选一即可。Perfare/Il2CppDumper: Unity il2cpp reverse engineer
使用方法Il2CppDumper/README.zh-CN.md at master · Perfare/Il2CppDumper
这里的放置少女的global-metadata.dat已被加密,所以不适用。
对于global-metadata.dat和libil2cpp.so都正常的情况:会生成以下这些文件

如果你没有指定目录,那么就会这些生成在Il2CppDumper安装目录
在IDA中选择file > script file... 选中Il2CppDumper安装目录下的ida_with_struct_py3.py
然后会继续弹框让你选择文件,依次选择script.json > il2cpp.h
之后就等待IDA运行脚本了。
ADB
adb connect 127.0.0.1:5555
adb connect 127.0.0.1:16384
adb devices
adb root
adb shell
exit
#查找package,不建议自己查,不如MT管理器简单方便
pm path com.fknzj.qooapp
ls -l /data/data/com.fknzj.qooapp
Frida连接
模拟器frida服务
APP逆向第五课: Frida安装&基础HOOK⽅法_哔哩哔哩_bilibili
模拟器adb shell连接
查看模拟器adb端口

找到adb路径D:\Games\Mumu\MuMuPlayer\nx_device\12.0\shell,getprop查询CPU架构为x86_64
adb.exe connect 127.0.0.1:5555
adb.exe shell
getprop ro.product.cpu.abi

找到对应版本下载。https://github.com/frida/frida/releases/download/16.1.0/frida-server-16.1.0-android-x86_64.xz
解压xz文件后得到一个无拓展名文件。重新命名为frida 根据个人喜好。
传入到模拟器中。这里使用mumu共享文件夹传输文件,然后在共享文件夹再次把文件移动到本机根目录
或者使用push指令一步到位
adb push ...\frida /data/local/tmp

打开root exploreer或者任意root管理器,找到frida文件

再次移动frida,移动到tmp目录,因为其他目录下不能修改这个文件的权限。

修改文件权限为777,全部勾选即可。

接下来cd进这个目录,启动frida
cd /data/local/tmp;
./frida
然后这里会显示权限不够。
`Cetus:/data/local/tmp $ ./frida
Unable to save SELinux policy to the kernel: Permission denied`。
需要提升权限,输入exit返回
exit
adb root
adb shell
cd /data/local/tmp
./frida
然后如果命令行一动不动,说明模拟器frida服务成功开启了

物理机连接frida服务
接下来用物理机连接模拟器的frida服务,新建一个终端,还是在D:\Games\Mumu\MuMuPlayer\nx_device\12.0\shell这个路径下,进行端口转发。
adb forward tcp:27042 tcp:27042
物理机下载frida和frida-tools,参照这个表找到对应版本thelicato/frida-compatibility-matrix: Compatible versions of the frida package for each version of the frida-tools package. Automatically updated through CI/CD
因为我们下载的是16.1.0版本,所以tools下载12.3.0,如果版本下载太高了就无法识别模拟器的frida服务。
pip uninstall frida-tools frida -y #如果下载错了需要先卸载frida和依赖
pip install frida==16.1.0 frida-tools==12.3.0
两个包都需要指定版本,不然会自动下载默认版本,可能会出问题。
如果一切顺利,查询模拟器进程,可以查到PID和对应进程。
frida-ps -U

hook
模拟器frida服务容易掉线,如果出现了问题可以检查一下是不是frida服务掉线了。
最后一个参数是包名,获取方式在Zygisk-Il2CppDumper这个章节,这里是目标游戏放置少女的包名。
在物理机下输入以下指令,会自动启动
frida -U -f "jp.glee.girl"

这里就完成了Frida功能的初步验证。
获取逆向所需文件
打开APK安装包,自己找,只要是unity游戏一定会有。
- libil2cpp.so 所有的C#方法被编译成了C++
- global-metadata.dat 结构化的数据库,存放了定义


启动游戏后,通过Zygisk-Il2CppDumper可以自动获取dump.cs,可以绕过保护。
- dump.cs 反编译出的所有方法的可读函数名
获取关键加密信息
使用IDA导入文件libil2cpp.so
从dump.cs中寻找关键字decrypt encrypt

可以看到这里有对称加密算法的相关方法。
然后可以去IDA按g输入跳转RVA地址,观察是否有值得注意的信息,可以右键切换视图。
继续搜索相关的信息RC4 DES AES等等
基本可以确定加密算法是 RC4,需要获取初始向量IV和密钥Key
Gemini编写hook脚本 hook.js
关闭游戏,通过frida注入hook启动,需要在hook脚本路径下执行,或者指定hook路径。
这个是动态注入的,也就是说你可以随时更改hook脚本来观察结果。
以下两种方式选择一种,在物理机上执行。
Spawn启动(会重启游戏,如果游戏是开着的)
frida -U -f "jp.glee.girl" -l hook.js
Process.enumerateModules()
Attach到进程启动,注意每次重开游戏PID都会改变,需要重新在物理机上查询。
frida-ps -U #查看PID为 28902
frida -H 127.0.0.1:27042 -p 28902 -l hook.js --realm emulated
#如果报错提示Failed to attach: process is not using emulation则移除 --realm emulated
Process.enumerateModules()
==需要注意的是mumu模拟器当前如果是x86-64架构,而游戏是arm64架构,是无法直接找到libil2cpp.so模块的,而是通过libhoudini.so翻译层执行。==
反斜杠表示转义。

卸载游戏,重启模拟器。试了一下,改成这样直接APK无法下载了。
另一个解法就是换成root过的真机。
hook脚本也确实提示找不到libil2cpp.so,这里在adb shell上查看一下进程内存分配,PID替换为实际进程号
cat /proc/PID/maps
发现有global-metadata.dat,可以确认libil2cpp.so 模块一定在内存中
78d540735000-78d540dfa000 rw-p 00000000 08:23 6423855 /data/media/0/Android/data/jp.glee.girl/files/il2cpp/Metadata/global-metadata.dat
但是却找不到,说明大概率是模块名称被修改了。
未完待续。。。
Comments