从 Dragalia Lost ~失落的龍絆~ 入手,简析Metadata-hiding,并尝试在自己的Unity小游戏项目中实现类似功能
0x01 分析 Dragalia Lost ~失落的龍絆~ ,尝试dump出metadata
拿到ver1.6.1的安装包,用Bandizip打开看看:

可以发现,关键的metadata文件夹不见了,通常这种情况下global-metadata.dat会被隐藏在libil2cpp.so中。用ida打开,定位到MetadataLoader::LoadMetadataFile(),可以看到解密函数如下:

coneshell_global_metadata_dat_len即为global-metadata.dat文件的长度:

记住0xF26844这个数字,接下来我们用模拟器+GameGardian,dump出游戏解密后的内存:


dump出来的结果是一个bin文件,用winhex搜索global-metadata.dat文件的magic header"AF1BB1FA":

搜索得到唯一结果:

结合上文得到的文件长度,就能把metadata抠出来啦。不过仅仅如此也没法正常使用il2cppdumper,后续如何修复就不在本文的研究范围内了(逃
上述方法同样适用于部分加密了global-metadata.dat的游戏
0x02 尝试在自己的Unity项目中实现Metadata-hiding
参考Nu1LCTF
编译环境:win10 + Unity 5.6.4p4
首先使用原版代码生成一个正常的bird.apk,查看其内部结构:

此时存在global-metadata.dat且未加密,il2cpp.so大小为5m+。将global-metadata.dat提取至桌面,使用如下代码进行加密:

加密后的global-metadata.dat:

使用010 Editor打开该文件,File - Export Hex,生成头文件并重命名为MetadataHexData.h备用:

MetadataHexData.h 内容如下:

进入Unity安装目录\Unity5.6\Editor\Data\il2cpp\libil2cpp\vm下,导入头文件MetadataHexData.h,并修改MetadataLoader.cpp:


重新Build,得到修改后的bird.apk,查看其内部结构:

可以发现il2cpp.so大小增加至6m+。删除Managed文件夹下的Metadata文件夹,并重签名,进行安装测试。

测试环境:MuMu模拟器,2.0.20.2,安卓6.0.1

可正常打开。游戏逻辑无异常。
Comments | 9 条评论
浮冰新博客 帅啊
@lxy
蟹蟹!
请问这个加密代码可以通用的嘛‘
@邢
理论上是可行的,建议你实际操作试试
樓主您好, 我參照這網站 https://reurl.cc/XNbW0
取得metadata解密的python code
我取出日版chain chronicle的global-metadata.dat
執行python後產出了新的global-metadata.dat
但還是無法讓Il2CppDumper讀入, 會有以下錯誤
ERROR: Metadata file supplied is not a supported version[9.214607E+08]
是否其加密的方式不同於一般?
@Chris
你这肯定是不行的啊…
请问下我为什么修改了MetadataLoader.cpp代码之后,build报错了呢,具体如下
Failed running D:\BuildTool\Unity\Editor\Data\il2cpp/build/il2cpp.exe –convert-to-cpp –emit-null-checks –enable-array-bounds-check –dotnetprofile=”unityaot” –compile-cpp –libil2cpp-static –platform=”WindowsDesktop” –architecture=”x86″ –configuration=”Release” –outputpath=”D:\Client\Temp/StagingArea/Data\Native\GameAssembly.dll” –cachedirectory=”D:\Client\Assets\..\Library/il2cpp_cache” –map-file-parser=”D:\BuildTool\Unity\Editor\Data\Tools\MapFileParser\MapFileParser.exe” –directory=”D:\Client\Temp\StagingArea\Data\Managed” –generatedcppdir=”D:\Client\Temp\StagingArea\Data\il2cppOutput”
1.我从GG里打算dump il2cpp.so,但是发现该so的文件名不纯净,里面有些奇怪的字符,好像不是从原游戏file里直接读取的。。
2.用Prefare的il2cppdumper,只能读取出MetadataRegistration,而CodeRegestration=0,那么理论上说,我把所有地址都试一遍是不是就能dump出来= = 而且我发现大部分Codegen和Metadata的地址比较接近,随便发发
你这打包也太繁琐了把,打包流程: 打包li2cpp -> 解包 -> 加密 -> 替换头文件 -> 打包 -> 解包 -> 删除 -> 重新打包….
数据和算法都在so里面也是有办法dump出来的,直接内存里抓你解密之后的内容
我说下我的, 修改Unity.IL2CPP.dll global-metadata.dat的版本号迷惑逆向者,修改各种元数据的偏移量
就算内存抓出来看起来也是很正常的数据,解密工具失效了此时,需要修复版本号以及偏移量,这两点够逆向的喝一壶了