SHOW BY ROCK – Fes A Live

2022-12-03:

停服前资源汇总:https://pan.baidu.com/s/1eoeaeHBbgw8sHEhsrJVHag


English version post

有一说一,我大一时候的第一个入坑的日系抽卡音游就是旧版运营的sb69。

差不多打了半年,后来在出了LR卡不久就退坑了。不过我的歌单里面还一直存着Bud Virgin Logic的x旋律,这歌是真的好听。

SE做的新SBR在之前也听说了,今天看到开服了的样子,就下了试试手。

首先初始抽卡,我连抽6个男人号(我:??),给我整疯了。最后终于出了个太夫。

然后游戏体验来讲,效果……很勉强。总体上手而言体验非常一般,游戏没有特别有意思的点,只能说多年来SBR乐队的歌曲积累以及系列本身已有的人气才换来比较大的玩家基础。如果只是这样持续的话,可能不会有太大的发展,至少我是不会被吸引住的。


索引:

  • 资源文件
  • 资源索引
  • 通信

资源文件:

首先,cri密钥是54605542411982574,hex:00C1FF73 963BD6EE。配置里写了authentication file是zYzGZYc.png,不过也没用到的样子,不是很懂

入手先从已有的资源文件开始。一如既往,在dump.cs里面随便搜关键词,搜到了 SBR.Core.AssetBundles.ABLoadService 类下的 decryptAssetBundle 方法。旁边有一个 LoadAssetBundleCrypto 看起来就非常显眼。

点进方法体一看,先获取内嵌资源的TextAsset,文件名是类静态成员confName,值是abc。打开data.unity3d一看里面果然有这么个TextAsset。

然后初始化了一个 SBR.Core.AssetBundles.ABCryptoKey 类,ctor内读了两个字符串(5pvoKUvp2EinvR5C 和 Vh6TCcm4sJsO9VpS)作为 key 和 salt。ABCryptoKey 继承自AssetBundleCryptoKey,抽象类含有两个string转byte[]的函数,打开查看看到是 Convert.FromBase64String 。

初始化的ABCryptoKey类送给了 Ulibow.Common.Crypto.CryptoService 的 Decrypto 方法。实际上这里我卡了一下,因为Decrypto里面是动态方法表的调用。但是我后来看了一下 Ulibow.Common.Crypto.Provider 发现里面只有一个 RijndaelServiceProvider ……可还行

仔细读了这个类的 Decrypto ,输入进来的 password 和  salt 送进了 Rfc2898DeriveBytes(又是你)进行1024次变换,取出48字节,前32为key,后16为IV,送给Rijndael(或者是AES256)。

上面abc的TextAsset在这样解密完成之后得到一个MemoryStream,按照int32 length + byte[] data的格式分别读出 pwBytes 和 saltBytes,存进 AssetBundleCryptoConfig 类,这就是所有资源文件的密码(并不能叫做密钥,因为密钥是从这两个生成的)。


  • 资源索引文件:

资源索引分为两个部分,一个是资源信息,另一个是bundle目录。

首先需要理解资源文件的路径,资源的下载url是这样的

https://prod-dlc-cache.showbyrock-fes.com/asset/2624265425389168865/13723598818173245104/7245282449204259530

而本地的路径则是

/Documents/2624265425389168865/13723598818173245104/7245282449204259530

可以看出两个之间是相同的。

从dump.cs挖宝的时候就已经看到了 SBR.Core.Manager.AcbManager::getEncryptedServerPath 这种直白的函数名,里面调用了 SBR.Core.Encryptor::Encrypt 。跟进去一看发现调用了Standart.Hash.xxHash64,一搜是个公开库,岂不美哉?

刚开始看着函数体,感觉好像被改了,不过后来仔细对比,实际上是因为64位数的符号导致的,外加ida输出的代码是真的很难看。

路径的每个部分都是xxHash64的结果,seed参数为 0x33DC7CB65408BDF ,上面那个路径的本体就是 /asset/ios/charactercard/charactercard00323001。

在每次启动时,游戏都会下载 /asset/ios/filelist,这个文件是自定义格式数据,用到了AssetListFileCryptoKey 类 ctor 内的 key 和 salt: KAjyg6DTjC5ScfH9 和 2Ae2C7jQEJuU6h2j。

读取简单,先文件头0xBFC2A1C2,然后读个int32扔掉,接下来每个里面都是AssetInfo类:int32 len + char[] name,int64 hash,int32 size,int32 category,bool is_individual_download,一直读到文件结尾

读完filelist后再按需获取 /asset/ios/ios,文件是标准bundle,里面有一个AssetBundleManifest对象(好像还是unity自带的类?),对象包含names、variants(空的)、infos,infos底下有包hash和加载依赖信息。然后加载其他包就从这里查找文件名就行了。


  • 通信

通信基本上没啥好研究的,直白的msgpack无加密。本来我看到有个request_hash,结果后来去看的时候发现这货怎么是个时间戳?

反正照着实际代码抄一个db更新也很快,里面有个app_version字段,服务器检测只是小于当前运营版本号才报错,我改个大的数字也无所谓。

发表回复

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

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax