惊闻初音出了新手游,熟练地打开 Play 下载、运行,游戏也熟练地用流畅的动画弹出「通信エラーが発生しました」。嗯,毕竟是喜爱滥用 SafetyNet 的日系软件。
上滑返回,将游戏加入 MagiskHide 列表中。清除数据,打开游戏,接着——「通信エラーが発生しました」。嗯?怎么回事?再次返回确认设置、清理数据,错误依旧。渐渐地回忆起被 Disney+ Widevine L1 支配的恐惧,莫非这游戏也强制了 SafetyNet Hardware-backed Key Attestation?
打开搜索引擎,敲入“Project SEKAI 无法连接”。哦!原来是检测到了加速器。测试发现这游戏大概是用了 GeoIP2 Anonymous IP Database 之类的库,看来是有备而来。鉴于游戏 Press START 界面的设计异常的有诚意,并没有点到为止。一通折腾之后成功进入了游戏。
assetbundle.sekai.colorfulpalette.org assetbundle-info.sekai.colorfulpalette.org game-version.sekai.colorfulpalette.org production-game-api.sekai.colorfulpalette.org production-web.sekai.colorfulpalette.org # 别问,我不知道这是啥
游戏资源分析
同此前分析的一款游戏(Dream Blast)一样,是使用 il2cpp 编译的 Unity 游戏。
游戏资源主要分为两类,本地资源与按需下载(OnDemand)资源。本地资源用 AssetStudio 直接解包即可,按需下载资源缓存在 sdcard/Android/data/{package name}/data
下。
资源混淆
按需下载资源使用 Sekai.AssetBundleManager.XORStream
(libil2cpp.so)函数进行了简单的混淆,去除 0x4 字节的 flag 后,对头部 0x80 字节进行了与 FF FF FF FF FF 00 00 00
的 xor 操作。这种混淆方式基本不影响性能,但却能有效浪费分析者时间,可以说是不错的权衡。
写了一个简单的程序 sekai-xor,对混淆过的资源进行批量解密。
Live2D 资源
Live2D 资源未经加密,但储存结构、方式似乎与其他游戏有所不同,因此无法直接使用 UnityLive2DExtractor 进行导出。其中模型文件直接储存为了 .png
、.moc3
、.model3.json
、.physics3.json
格式,可以直接使用 AssetStudio 导出并查看。
动作文件则储存为了 Unity 的 .anim
格式,文件中绑定的参数名并非像 .motion3.json
格式中那样,以 string 形式直接储存,而是存为了 crc32(参数类型 + '/' + 参数名)
。
UnityLive2DExtractor 中通过读取动作文件对应的 GameObject(Transform) 来获取参数列表。通过计算各参数的 crc32 后反查,然后将 .anim
文件转换回 .motion3.json
,但本游戏似乎并没有这样的 GameObject。
分析几个文件后,发现只能在 .moc3
中找到模型 string 形式的参数列表。但 .moc3
并非开源格式,现在也没有公开的第三方解析器。因此目前暂时通过直接搜索 .moc3
中的 ASCII 字符来获取参数列表,用以转换 .anim
中 crc32 后的参数。
通过修改 UnityLive2DExtractor,实现了 .anim
文件到 .motion3.json
文件的批量转换:SEKAI2DMotionExtractor。
音频资源
游戏的音频文件都加密打包成了 .acb
格式,可以使用 CriTools 解包、解密。经过搜索引擎搜索,发现其密钥与『バンドリ! ガールズバンドパーティ!』的一致。
但至于本游戏的密钥是储存在哪里的,分析过后依然未能找到。
按需下载资源
本游戏包含大量的按需下载资源(~ 4GB),部分资源如果不执行到相应的场景,则不会进行下载。要获取所有的资源,除了把各分支都过一遍外,也可对游戏的网络通信进行分析。
网络通信分析
由于游戏仍在运营,这里仅作简单的分析记录,仅供学习研究之用。
游戏使用 MessagePack 序列化数据,通过固定的 AES 密钥及 IV 进行 AES-128-CBC 加密,再通过 TLS(https)加密传输。
TLS 的证书验证测试无法通过导入根证书等方式绕过。猜测验证发生在 libunity.so 的 curl 库中,通过二进制修改该文件可停用 curl 的证书验证。这里也找到了一个不错的支持 ARM64 的汇编代码转换网站。
AES 的 Key、IV 在 Sekai.APIManager 的构造函数中设置,具体的密钥则在游戏编译时导出到了 global-metadata.dat
,参考 Perfare 大神的文章,在该文件中定位到找到密钥及IV。
MessagePack 则可以直接转换为 JSON 格式,便于阅读。分析网络通信后,可以找到按需下载资源的列表等数据。
总结
我一向不喜欢手机网游,但无论从资源包数量上,还是从游戏本身,都能感觉到这个游戏还是挺有诚意的。
这次的分析也算是简单尝试了下 ARM64 下的二进制 patch。当然,也同上次一样,基本上都是靠的前人研究与工具。如果塞几个未知算法进去,估计就够呛了。
Coxxs
姐姐写得真好
我看过做绑绑/SEKAI工具的作者在博客的分析,文章之间互有补缺
主要是有缺失的Live2D,期望作者之间能够合作
emmmm,为什么我用SEKAI2DMotionExtractor什么也不会生成啊