Project SEKAI 逆向(7):3D 模型提取

Project SEKAI 逆向(7):3D 模型 1. 文件结构 目前发现的 3D 模型基本都在 [ab cache]/live_pv/model/ 下 初步观察: (1) Body 即目标模型;当然,作为skinned mesh,而且带有blend shapes,处理细节会很多;后面继续讲 (2) 处的 MonoBehavior 就其名字猜测是碰撞盒 (3) 处的几个 Texture2D 则作为texture map 2. 模型收集 利用sssekai取得数据的流程在(5)中已有描述,这里不再多说 首先整理下根据mesh发现的数据需求 (1) Static Mesh pjsk发现的所有mesh在相应assetbundle中会有1个或更多GameObject的ref;对于这些ref,static mesh会出现在m_MeshRenderer之中 其他细节暂且不说;因为做 Skinned Mesh 导入时都是我们要处理的东西 (2) Skinned Mesh 不同于static mesh,这些ref会出现在m_SkinnedMeshRenderer之中 同时,我们也会需要骨骼结构的信息;bone weight以外,也需要bone path(后面会用来反向hash)和transform (3) Blend Shapes 这些可以出现在static/skinned mesh之中;如果存在,我们也会需要blend shape名字的hash,理由和bone path一致 加之,Unity存在aseetbundle中动画path也都是crc,blendshape不是例外 总结: (1) 所以对于static mesh,搜集对应GameObject即可 (2) 对于skinned mesh,同时也需要构造bone hierarchy(就是个单根有向无环图啦),并且整理vertex权重; 则需要收集的,反而只是bone的transform而已;transform有子/父节点信息,也有拥有transform的GameObject的ref (3) 的数据,在(1)(2)中都会有 3. 模型导入 当然,这里就不考虑将模型转化为中间格式了(i.e. FBX,GLTF)...

January 5, 2024 · 2 min · 237 words · mos9527

Project SEKAI 逆向(4): pjsk AssetBundle 反混淆 + PV 动画导入

Project SEKAI 逆向(4): pjsk AssetBundle 反混淆 + PV 动画导入 分析variant:世界計劃 2.6.1 (Google Play 台服) 1. 数据提取 pjsk资源采用热更新模式;本体运行时之外,还会有3~4G左右的资源 (**注:**不定量,见下一篇) 尝试从本机提取资源 没有magic UnityFS,考虑ab文件有混淆 2. 加载流程分析 进dnSpy直接搜assetbundle找相关Class 进ida看impl,可以很轻松的找到加载ab的嫌疑流程 最后直接调用了unity的LoadFromStream,Sekai.AssetBundleStream实现了这样的Stream: 可以注意到 加载时根据 _isInverted flag 决定是否进行反混淆操作 如果有,则先跳过4bytes,之后5bytes按位取反 最后移交InvertedBytesAB继续处理 注意到n00应为128,v20为读取offset 这里考虑offset=0情况,那么仅前128字节需要处理 跟进InvertedBytesAB 可见,这里即跳过4bytes后,每 8bytes,取反前5bytes 综上,解密流程分析完毕;附脚本: import sys import os def decrypt(infile, outfile): with open(infile, 'rb') as fin: magic = fin.read(4) if magic == b'\x10\x00\x00\x00': with open(outfile,'wb') as fout: for _ in range(0,128,8): block = bytearray(fin.read(8)) for i in range(5): block[i] = ~block[i] & 0xff fout....

December 31, 2023 · 2 min · 223 words · mos9527