Project SEKAI 游戏分析

惊闻初音出了新手游,熟练地打开 Play 下载、运行,游戏也熟练地用流畅的动画弹出「通信エラーが発生しました」。嗯,毕竟是喜爱滥用 SafetyNet 的日系软件。

上滑返回,将游戏加入 MagiskHide 列表中。清除数据,打开游戏,接着——「通信エラーが発生しました」。嗯?怎么回事?再次返回确认设置、清理数据,错误依旧。渐渐地回忆起被 Disney+ Widevine L1 支配的恐惧,莫非这游戏也强制了 SafetyNet Hardware-backed Key Attestation?

包含了 Live2D 动画的 Press START 画面

打开搜索引擎,敲入“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 操作。这种混淆方式基本不影响性能,但却能有效浪费分析者时间,可以说是不错的权衡。

这个头部一开始以为是自研的文件打包格式,原来是 xor 后的 UnityFS…

写了一个简单的程序 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

Project SEKAI 游戏分析》有3个想法

  1. 我看过做绑绑/SEKAI工具的作者在博客的分析,文章之间互有补缺
    主要是有缺失的Live2D,期望作者之间能够合作

  2. emmmm,为什么我用SEKAI2DMotionExtractor什么也不会生成啊

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注