求助开源项目 UnityPy 中 Python 的 lzma.LZMADecompressor 行为和 7z 不一致,有没有人知道问题出在哪里?

21次阅读

共计 1272 个字符,预计需要花费 4 分钟才能阅读完成。

场景(嫌长跳过)

最近水 Discord 知道一个朋友在尝试开发战女的私服(一款 2019 年停服的日本抽卡游戏,制作挺良心的)想起来以前上学的时候也玩过一段时间这游戏,有点情怀了,刚好我以前开发过几款停服游戏的私服 /t/1033715 /t/1049388,算是很有经验了,想帮他一起开发。

这个游戏虽然是手游,但 asset 加载完全按照页游的逻辑,没有提供任何预载当前用不上资源的接口,导致我们不可能在停服前对游戏资源文件进行完整备份。同时资源缓存放置在 /data/data/ 游戏包名 /cache 底下,除非 ROOT 或者使用第三方 Recovery,没有任何办法能够提取它的文件,各种手机的备份都是调用的 BackupService,它备份不到 cache 目录下面的东西。这导致了即使我们能联系上很多还没有卸载游戏的朋友,能提供缓存文件备份的也是非常少数。

更逆天的一点是这个游戏每个有加密的资源文件都使用了完全不同的密钥进行 AES 加密,和文件的下载链接一起通过 API 下发。如果没有备份到对应的 API 返回解密后的内容(全部 API 响应用每个用户都不同的 AES 密钥二次加密,只有首次登录的时候会返回这个密钥,首次登录返回的内容用一个 .so 库返回的初始密钥加密)。这导致成功提取出缓存文件还有相当一部分不能用。

好在我们根据现有的存档数据完成游戏的基础功能开发后,有很多位朋友也贡献出了他们的曾经备份的文件,但是因为前面这些原因,这些文件中有相当一部分不能用的。有的是有加密但没备份到密钥,我们需要把这部分文件筛出来不能让游戏加载,有的是因为 target 是 iOS,我们想要通过重打包来实现在 Android 上使用(纹理等做不到无损转换的,有损也总比没有好),有的 size 和 API 中返回的对应的上,但就是没有办法通过任何工具载入,不知道哪里出了问题。同时这个游戏的缓存文件名 hash 方法入参只有资源名,算出来的结果和版本无关,我们需要保留最新、可用的一份。这个游戏的 Asset Bundle 非常多,我们收集到的去重后就有接近 5 万个,这三件事显然要用脚本来完成。(写这么长也是想问问有没有 V 友有更好的思路)

问题

因为以前用过 UnityPy 这个包来编辑 Asset Bundle,所以也是想到了用这个包来写脚本。这个包是 AssetStudio 的 Python port,AssetStudio 能够载入这款游戏的大部分资源文件,但是 UnityPy 没办法载入这款游戏的任何资源文件,报错

_lzma.LZMAError: Corrupt input data

因为太长了,完整报错信息和样本文件请在 https://github.com/K0lb3/UnityPy/issues/237 下载。查看了 BundleFile.py 对 UnityWeb 文件的处理逻辑,和 AssetStudio 一致。修改代码打印了解析出来的压缩后的数据头尾部分、长度,和在 AssetStudio 打断点获得的数据完全一致,说明问题是出在 LZMA 解压的部分。

求助开源项目 UnityPy 中 Python 的 lzma.LZMADecompressor 行为和 7z 不一致,有没有人知道问题出在哪里? 求助开源项目 UnityPy 中 Python 的 lzma.LZMADecompressor 行为和 7z 不一致,有没有人知道问题出在哪里?求助开源项目 UnityPy 中 Python 的 lzma.LZMADecompressor 行为和 7z 不一致,有没有人知道问题出在哪里?

尝试了 LZMA 参数的各种组合都没有成功解压文件,想问一下有没有 V 友知道问题出在哪里?

正文完
 0