看到隔壁Twistzz大佬发了工具:https://live2dhub.com/t/topic/5799 ,也来抛砖引玉分享一下最近的解析经验。用最新版本国际服的data.pack做测试,scsp里面有一部分是3.8.99的spine且可以被scsp38-json工具正常解密。另一部分是2.1.27,目前的工具只有之前e7vault作者发布的epic7_scsp2json_v1_0 ,在scsp38-json不能解析的scsp中,少数可以被epic7_scsp2json_v1_0直接解析(但是需要在Live2DViewer中修复);
剩下的有两类,一类(附件c1002,立绘类)在解析过程中会在if (bone_parent < 65535): bones[“parent”] =result[bone_parent][“name”]报错list index out of range,print了一下发现result的长度为0。第一个骨骼即root bone是没有parent的,所以它的index应该是一个0xFFFF的特殊值;如果不是则会访问result[bone_parent],由于是第一个骨骼所以result长度必然为0导致index out of range。进一步检查发现,root bone的Bone index: 0, parent value: 0;而正常的parent value应该为65535才对,读取骨骼的offset出现了问题。代码中的bones区域默认是偏移88个字节,说明E7的2.1.27的scsp可能还存在不一样的offset,但是我不会反编译,在WinHex里看了半天也没看出来有啥规律
还有一类(附件elena_s01,貌似是战斗小人)有正常的offset,但是在代码中判断spine文件包含了BOUNDING_BOX然后直接sys.exit(1)退出,强行注释掉也会导致后续数据解析错位,最终在某个位置发生错误,似乎是2.1.27的作者没有打算处理包含BOUNDING_BOX的战斗小人spine文件;而用scsp38-json则可以解出部分战斗小人。
test.zip (1.7 MB) 附上测试用的scsp,atlas和png
IDA的激活工具GitHub上一大把,之前用的那个IDA-Patcher好像被封禁了
反编译其实没啥了不起的,没加密没混淆没加壳,其实也就是用IDA打开libur.so,也没做什么处理,不需要还原函数名。
去搜一下spine::v2::spSkeletonData_createWithSCSP就行了
V2_spSkeletonData_createWithSCSP.cpp
我看过了一部分,最近没什么时间搞了,倒是有这个88字节是怎么来的
uncompressed_size 4B | compressed_size 4B|
LZ4 compressed data:
data_size(uint32) 4B | string_size(uint32) 4B |
binary_data | (data_size)B
SCSP Magic 4B | Version(uint32) 4B |
HeaderSize 4B
Header (min(HeaderSize, 88))B
6*float32: weight, height, minX, minY, maxX, maxY
7*uint32: bones ? ? ? ? ? ?
...
data (data_size - HeaderSize)B
string_pool | (string_size)B
这一段是对的,不过你有兴趣还是去看下spine runtimes,熟悉了处理起来会更有目的性
SpineRuntime38
在反汇编里面我看它对旧格式(无scsp头)的数据有兼容,而且在读取头部之后就旧的与新的(有scsp头)的数据汇一起了,应该可以根据那个1.0的解包方式分析解包新数据,最好的情况只要那个新头读取的数据依照旧头的格式简单替换一下就可以,可以根据汇编代码确定旧头里面的数据在新头数据位置变实现。
xsl
2026 年3 月 26 日 06:25
4
2.1的可以散了,头部有2种,跳过字节数不一样,结果也略微有差异,但是这个不是重点,重点是2.1有一个很严重的问题,有一个filp翻转功能,spine自己都不认,根据spine官方的写出来的查看器也无法读取这个参数,所以2.1但凡用了那个骨骼,全部可以寄了,主要都是小人上面,立绘这个功能倒是不会用,然后2.1跟3.8骨骼缩放计算也不一样,企图转3.8也很麻烦,巨坑