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,白嫖卡面
有人能帮忙把音效包整出来吗?实在需要还操作不了咳咳
大佬,所以我有旧版资源的情况下想解模型之类的,也必须要那个db文件?
无法提取最新的asset_a_ja_0
Warning: gzinflate(): data error in SIFAS.php on line 73
密钥改了,有需求请自己逆向,这里不再更新。
llas db对比也将停止
用了gist的SIFAS.php结果在gzinflate()报错
是我哪里搞错了吗
用的档案是最近一次更新的.db档 从手机直接拷贝过去的
附图
1
手机复制过去的是本地加密,请看9/29的更新内容
https://i.imgur.com/Eh3N4KY.png
是这个吗 可是它的值要怎么取
你是安卓?在/data下的prefs里面。我不知道具体路径。
对不起我可能问题会蛮多的 第一次搞游戏逆向(汗
感觉大佬拆的游戏都挺合我口味.
请问有大佬出没的交流群?
还要只会喊666的吗? #熊猫捂脸
居然看到心跳偶像..
游戏虽然能用AS直接拆. 只能拿到模型没骨骼的的多边形面…
说来SIFAS也时跟CGSS一样的黑洞模式 (幻想破灭)
求把我也拉进去QAQ
我也能解可以帮帮忙)
tql wsl