SIFAS

ll卫星了好久(好像好几年了?)的虹团终于出了

这游戏现在已经被我群开除音游籍了,神秘live系统。【船新放置音游,不打不死,一打就死】

贴个抽卡(我怎么看周围人教程单抽都是UR,就我是R??)


一下午的沉迷ida后搞出了db的解密,资源我还没去看,但两个用的是同一个解密逻辑。

(上次mltd是stella头一个,这次似乎我确实是头一个了?)

Last Update: 10/18


10/18更新:

v1.1.0版本更换了密钥,看来klab算是个强烈反逆向的公司了。

llas db比对停止更新,此处将不再继续后续更新和研究

See you next time


搜索Decyprt简直极度贴心

跟着几步很快就找到了解密算法,那么问题就是key1和key2了

于是我决定走捷径,挂个hook康康密钥到底是什么

vmware启动,内存不足,壮烈蓝屏

重启后找了个老插件随便改了个钩子,扔上去安装,结果发现所有文件密钥都不一样,卒

中间这段有点失忆,反正胡翻的时候找到了AssetBundleLoader,然后又怎么瞎逛之后翻到了key1 key2都是从sqlite db里面读取出来的。看了眼本地下面确实有几个db,当然里面内容也都是加密的。

至于读取本地的也跟了半天没看懂,所以决定绕路去抓包。文件全部一删,fiddler启动,manifest get

刚开始看着这个文件还以为是msgpack,然而并不是。搜索文件名找到了 MasterData.MetaDataClass,文件读取也是挺直白的

<?php
// master data manifest
$f = new FileStream('masterdata_i_ja');

// head sha1? skipped in code
$f->position = 20;

function ReadByte(Stream $f) {
  return hexdec(bin2hex($f->byte));
}
function ReadInt(Stream $f) {
  $val = ReadByte($f);
  if ($val >= 128) {
    $b2 = ReadByte($f);
    $b3 = ReadByte($f);
    $b4 = ReadByte($f);
    $val = $val + (($b2 + (($b3 + ($b4 << 8)) << 8)) << 7);
  }
  return $val;
}
function ReadString(Stream $f) {
  $strlen = ReadInt($f);
  return $f->readData($strlen);
}
function GetKeyData($k) {
  $keys = [];
  for ($i=0; $i<strlen($k); $i+=8) {
    $keys[] = hexdec(substr($k, $i, 8));
  }
  return $keys;
}

// three header things
$hash = ReadString($f);
$lang = ReadString($f);
$rows = ReadInt($f);

$out = [];
for ($i=0; $i < $rows; $i++) {
  $v15 = ReadString($f); // db name
  $v16 = ReadString($f); // db keys
  $out[] = [$v15, $v16, GetKeyData($v16)];
}
for ($i=0; $i < $rows; $i++) {
  $out[$i][] = bin2hex($f->readData(20)); // download sha1 hash
  $out[$i][] = ReadInt($f); // download file size
}

有了索引就接着观察,读取完manifest之后调用了 MasterData.UpdateClass::DownloadSqlites,跟随里面的Action可以追溯到 MasterData.UpdateClass::Deflate,然后到 MasterData.UpdateClass.<>c__DisplayClass10_0::b__0 (大体上代码里面应该是内联函数块?),然后可以看到代码里面取了manifest里面的KeyData,以及来自 LLAS.DM.Dbapi.Constant 的类常量,两边key进行异或(常量密钥竟然是12345 67890 31415,真能想)完事这三个密钥附带一个FileStream扔进LCGStream,而后返回的流再扔进DeflateStream,所以跑完LCGStream之后出来的就应该是deflate压缩数据了。

然后这里就是最大的坑点了,ios程序的LCGStream::Read函数体看起来奇怪无比,直到后来我要了个apk里面的so,对比才发现问题所在

nmd为什么ios上面少了一个密钥变换???

我试了半天出来的数据就是没法扔进gzinflate,当时也在奇怪为什么key2没有进行任何操作,结果是指令过于神秘的问题??

反正把这个问题解决了结果一下子就出来了

(其实还有一个问题,代码里面在DeflateStream之后又喂了一次LCGStream,但是解压之后出来的就已经是sqlite db了,没太搞懂)

完整代码:SIFAS.php


在事后重新看的时候,所以资源的处理和db是一个方法,只不过这边是三个ManifestKey ^ ConstKey,资源那边就是12345, key1, key2,相当于把一个key固定成了12345

完事双草酸酯把我拉进了discord,然后我看里面triangle已经成功解密了资源,所以这个理论是没问题的

(至于跑不跑卡面提取,再说?)


update 9/29:

贴一个本地db,MASTER_KEY是PlayerPrefs里面的”SQ”的值

(不过manifest的文件名就是当前版本,可以直接自己拼路径?)

db diff和卡面提取都不会搞了,这游戏api太复杂,溜了

对我的兴趣还不如とキドル大(迫真)(但还是要Fuck KONMAI)


update 10/6:

db diff初版本靠triangle的api搞了

然后第二天他的api就坏了(x

然后我后来就照着双草的代码抄了一份api实现,故而处于这个原因,新版本的代码将不会再更新在toolkit仓库内(本质上也就是更新检测部分改了)

卡面提取考虑到服务器硬盘不是那么足(今天服务器硬盘爆了一次)(以及我api实现没抄完,只抄了一半)的原因,就不搞了

反正有三角dev,白嫖卡面

16 thoughts on “SIFAS”

  1. 大佬,所以我有旧版资源的情况下想解模型之类的,也必须要那个db文件?

  2. 用了gist的SIFAS.php结果在gzinflate()报错
    是我哪里搞错了吗

    用的档案是最近一次更新的.db档 从手机直接拷贝过去的

        1. 你是安卓?在/data下的prefs里面。我不知道具体路径。

  3. 感觉大佬拆的游戏都挺合我口味.
    请问有大佬出没的交流群?
    还要只会喊666的吗? #熊猫捂脸

    1. 居然看到心跳偶像..
      游戏虽然能用AS直接拆. 只能拿到模型没骨骼的的多边形面…
      说来SIFAS也时跟CGSS一样的黑洞模式 (幻想破灭)

发表回复

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

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