Live2D Spine资源解包 前作攻略Live2D Spine资源解包1
奥奇传说网页版 Spine 无加密 资源分类
鉴赏环节。8.0分。
这个应该是新出的皮肤,7060

时间过的真快😩,十年老兵,难凉热血

现在已经变成邵g传说了。碍于这个web端的性能,分辨率属实可惜,不过也有可能是webp的问题,但是我比对了一下png和webp的两个版本,几乎看不出任何区别。
7114

这不是我们碧蓝航线的圣路易斯吗,下次记得标明出处🥵






万物起源
![]()
![]()
获取清单
参考网页动画应该如何提取呢(已解决) - 讨论 - Live2DHub
现在只获取到了90kb版本https://aoqi.100bt.com/h5/version.json,没什么用
之前有3621kb的,来自隔壁。GamesArchive/AoQiChuanShuo/File/version~202510101760026048.json at main · violet-wdream/GamesArchive
根据batman提供的信息,目标变得很明确了。
需要把当前时间转为UNIX时间戳,然后获取version,之前考虑过是不是这个Stamp的问题,但是实测这个Stamp好像可有可无,然后就删了。
不过得到了个更加优雅的方式来获取Spine的ID,确实没注意到这么个东西。
https://aoqi.100bt.com/h5/config/pet/petspineicon.json
从马后炮的角度来看,中间的部分其实也是有缝隙的,只探测两边是不合理的。
VERSION
https://aoqi.100bt.com/h5/version.json
BASE-URL
https: //aoqi.100bt.com/h5/
海报
https://aoqi.100bt.com/h5/peticon/background/peticon6657.webp
静态立绘
https://aoqi.100bt.com/h5/peticon/static/peticon6657.webp
Spine立绘
https://aoqi.100bt.com/h5/peticon/spine/peticon6657.mix
下面的留作纪念吧。
不过好在命名比较整齐,然后数据范围相当可观,可以暴力破解获取,实际上序号大致是递增的(且递增步数最大为110,这里取150作为阈值),所以可以先测试一下1 ~ MIN - 1 的序号是否存在资源,这里检测测试了下左侧的区间1 ~ MIN - 1应该是没东西的。只需要测一下右边的区间就行。
接下来检测MAX + 1 ~ MAX + 150 的序号是否存在资源,如果存在一个资源序号为MAX1 > MAX,这里就可以更新MAX为MAX1然后继续探索,直到连续150个序号没有资源就停止。
随着游戏后续更新,序号的递增步长可能会超过150,所以可能需要动态更新这个阈值。
可供参考的数据:
- 2025-10-10 获取的最大序号是6657
- 2026-1-30 获取的最大序号是 7114
处理
直接通过petspineicon.json的ID拼接URL得到所有 output.txt
下载
可用Aria2c下载。
aria2c -i output.txt -d output
或者
解压mix文件
检测完整性 (可选)
总结
- 直接通过
petspineicon.json的ID拼接URL得到所有 output.txt - 批量下载mix
- 解压mix
- 校验完整性
修正了ID获取方式,总数1705, GamesArchive/AoQiChuanShuo/File/Spine at main · violet-wdream/GamesArchive 仅供参考,有很多重复的但是ID不同,其实没什么参考价值。
抓包
查询版本
https://cc2dhotupdate.100bt.com/manifest/aqsy/version_v4.manifest?p=0&c1=2&v=8.0.2207&vc=1010&pn=com.baitian.aqcs.aqcssy.bt&c2=140004&__cdn_asset_version__=1771674152.00696
得到version
{
"version": "8.0.2213",
"loginUrl": "https://service-gf-pjaqm.100bt.com",
"loginUrlBak": "https://bak-service-gf-pjaqm.100bt.com",
"zoneId": 1,
"force": 0,
"review": false
}
tv=8.0.2213
https://cc2dhotupdate.100bt.com/manifest/aqsy/project_v4.manifest?p=0&c1=2&v=8.0.2207&vc=1010&pn=com.baitian.aqcs.aqcssy.bt&c2=140004&tv=8.0.2213
得到path 以及 packageUrl,可以把v=8.0.2207 设为 v=0.0.0获取全部包
{
"appUrl": "http://aqsy.100bt.com/?sy0717",
"assets": [
{
"md5": "1e81578b1cda3927666ff1f7e92cba7e",
"path": "simplify/0/s_8.0.2209_8.0.2212.zip",
"size": 205063188,
"ver": 2209
},
{
"md5": "662c8067ce6748724a8e8454a3c1d3ad",
"path": "simplify/0/s_8.0.2210_8.0.2211.zip",
"size": 318659,
"ver": 2210
},
{
"md5": "3e0cc00cc71fa59dbdbb6a5ea9f5556d",
"path": "simplify/0/s_8.0.2211_8.0.2212.zip",
"size": 9178453,
"ver": 2211
},
{
"md5": "d6e2708cfc89a7380cdd4858e8f4e023",
"path": "simplify/0/s_8.0.2212_8.0.2213.zip",
"size": 20267633,
"ver": 2212
},
{
"md5": "1584961d6c566f708035758a637081a1",
"path": "h_0_8.0.2213_2213.zip",
"size": 58471222,
"ver": 2213
}
],
"packageUrl": "http://static.cc2dhotupdate.100bt.com/aqsy",
"packageUrl_backup": "http://static-cc2dhotupdate-bak.100bt.com/aqsy",
"remoteManifestUrl": "http://cc2dhotupdate.100bt.com/manifest/aqsy/project.manifest",
"remoteVersionUrl": "http://cc2dhotupdate.100bt.com/manifest/aqsy/version.manifest",
"searchPaths": [
"src",
"res"
],
"version": "8.0.2213",
"versionName": "8.0.2213"
}
packageUrl 拼接 path
http://static.cc2dhotupdate.100bt.com/aqsy/simplify/0/s_8.0.2209_8.0.2212.zip
奥拉星网页版 Spine 无加密 资源分类
跟奥奇传说网页版资源获取方式几乎一致。
鉴赏环节。8.5分。








获取清单
现在只获取到了858kb版本https://aola.100bt.com/h5/version.json
依旧只是部分数据,并不是完整的。同理,还是可以通过这些基础数据来推测范围然后爆破。
VERSION
https://aola.100bt.com/h5/version.json
#序列帧动画
https://aola.100bt.com/h5/peticon/breath/peticon4213.png
#Spine立绘
https://aola.100bt.com/h5/peticon/newbreath/petmovie5275/petmovie5275.png
https://aola.100bt.com/h5/peticon/newbreath/petmovie5275/petmovie5275.json
https://aola.100bt.com/h5/peticon/newbreath/petmovie5275/petmovie5275.atlas
#静态立绘
https://aola.100bt.com/h5/peticon/newlarge/type1/peticon5841/peticon5841_1.png
#海报
https://aola.100bt.com/h5/pet/petskin/background/bg/img_petskinbackground_926.png
没什么可说的,和奥奇传说基本一致。
可供参考的数据:
2026-1-30 理论可得:
- 若干序列帧动画
- spine 光启图鉴515 + 皮肤图鉴569 = 1084
- 海报243
实际得到:
-
序列帧动画没弄
-
spine 1193
-
海报337,不知道怎么设计的,有很多一模一样的图,分辨率和size都是一样的。

本来想和应该和奥奇传说一样,会有一个config记载所有的ID,这样就不用爆破了,倒是找到了一个疑似的文件,出现了很多4400之前的数据,以及最高序号是5848,而不是6001,具体作用有待考究。
https://aola.100bt.com/h5/data/eggconfig.json
还有一个,这个序号就完全不知道是指什么了。
https://aola.100bt.com/h5/data/petassetsmap.json
处理
下载
可用Aria2c下载。
aria2c -i output.txt -d output
或者
分类spine

检测完整性(可选)
.Scripts/SpineFileProcess/CheckSpineFiles.py at main · violet-wdream/.Scripts
无效立绘,可以直接删除。https://aola.100bt.com/h5/peticon/newlarge/type1/peticon5080/peticon5080_1.png

人工检测发现这个xshuimi应该是部件名称标错了,不用改。

手动合成一下链接
https://aola.100bt.com/h5/peticon/newbreath/petmovie4406/petmovie44062.png
https://aola.100bt.com/h5/peticon/newbreath/petmovie4407/petmovie44072.png
https://aola.100bt.com/h5/peticon/newbreath/petmovie4427/petmovie44272.png
https://aola.100bt.com/h5/peticon/newbreath/petmovie4427/petmovie44273.png
https://aola.100bt.com/h5/peticon/newbreath/petmovie4427/petmovie44274.png
https://aola.100bt.com/h5/peticon/newbreath/petmovie4512/petmovie45122.png
https://aola.100bt.com/h5/peticon/newbreath/petmovie5273/petmovie5273.png #这个url存在,可能是意外下载失败了。
总结
- 获取version文件
- 通过version文件得到petmovie目录文件路径,拼接为URL得到基础 output.txt
- 更新基础output.txt
- 批量下载
- 校验完整性
一共1193,仅供参考。2026-1-31导出资源:GamesArchive/AoLaXing/File at main · violet-wdream/GamesArchive
星之翼(Starward) Spine XOR加密
鉴赏环节。7.9分。
参考求助大佬,关于游戏星之翼的文件解密 - 讨论 - Live2DHub



资源路径
PC版。移动端同理
APK\Games\XzyLauncher_Data\StreamingAssets\yoo\Spine
热更\Games\XzyLauncher_Data\yoo\Spine
解密
将尾部16bytes作为key进行XOR
拖动文件夹到exe上直接处理。
论坛提供的。XOREnd16Key.exe
导出
导入AS后搜索
Assets/GameData/UiSpine/CharacterPaintingAssets/GameData/UiSpine/NameCard/MiddleBackgroundAssets/GameData/UiSpine/KV
黑色信标(BlackBeacon) Spine UnityCN
鉴赏环节。7.5分。




游戏资源
国服,无和谐《黑色信标》官方网站——欢迎来到世界的背面
资源路径
APK
assets > assetsBundles
热更

解密
Raz版AS
解密方式选择UnityCN,指定key 5F6C4E3F3A3F233F3F3F3F663F1A3F3F

key的获取方式可以参考另一篇文章-逆向
导出
搜索
assets/product/ui/texture/hero立绘assets/product/spine/resSpine
==三国杀名将传 Cocos Spine 无加密 自定义资源package
公式三国换皮放置游戏。Cocos引擎,Spine立绘。资源包是自定义格式,XXTEA
资源路径
APK

热更,这里的assets就是上面APK的32个package,下面的patch是更新部分,看起来是一个ttf文件。

package结构
查看package.assets000粗略可以看到一些明文的路径,fight/scene/1.png类似的,但是后面紧跟着的数据没有文件头也没有数据块信息。猜测是自定义的包格式。
AppDelegate::applicationDidFinishLaunching
物理存储分为了两个部分,跟上面的判断一致。
FileStorage::setPackageFileName("package.assets");
FileStorage::setPatchFileName("patch.assets");
addStorageFileName("base", "base.assets");
addStorageFileName("extra", "extra.assets");
这里的base.assets / extra.assets 是 逻辑路径,不是真实文件系统
接下来还是需要知道具体的package结构
cocos2d::PackageFile::initialize
cocos2d::PackageFile::getFileData
getFileData(path)
├─ PackageFile::getSearchFilePath(path) 通过 normalize_key 把path转化为key
├─ 通过key 查询hash表 得到 PACKAGE_FILE_DESC
├─ PackageFile::readFile
│ ├─ fread
│ ├─ abc_decrypt (XXTEA)
│ ├─ zlib uncompress
│ └─ 返回明文
└─ 返回给上层(Lua / 引擎)
def normalize_key(path: str) -> str:
for p in ("res/", "src/"):
i = path.find(p)
if i != -1 and i + 4 < len(path):
return path[i:]
return path
cocos2d::PackageFile::readFile
readFile
├─ 校验 entry.size
├─ 计算 offset
├─ fread 加密块
│ ├─ [u32 rawSize]
│ ├─ [u32 encParam]
│ └─ payload
├─ if encrypted → abc_decrypt
├─ if compressed → zlib uncompress
└─ 返回明文数据
cocos2d::abc_decrypt
abc_decrypt
├─ abc 派生 key 16B
├─ 将 data 转成 uint32_t[]
├─ XXTEA
├─ 校验尾部长度(padding)
├─ 还原 byte 流
└─ 返回明文
cocos2d::abc
import hashlib
import struct
CONST = "WxZwQEmMOYNLXDInuA1PoxsKGPEVFY9d"
def abc_key(this_ptr: int, a2: int) -> bytes:
s = f"k={this_ptr}s={a2}{CONST}".encode()
md5 = hashlib.md5(s).digest() # 16 bytes
hexstr = md5.hex().encode() # 32 bytes ascii
return hexstr[:16] # 只取前 16 字节
def key_to_u32(key16: bytes):
return list(struct.unpack("<4I", key16))
key = key_to_u32(abc())
==姬不可失:據點不設防 Cocos Spine 无加密 资源分类
2026-2-5 上线 Facebook
谷歌商店下载
经典的uuid36 -> uuid22 分类,目前找到的清单残缺,只能分类一半。
UI_new > paint_renwu 立绘
花亦山心之月 Spine/Live2D UnityCN 自定义Spine格式


文件乱七八糟的,同时部分spine是自定义格式的,把动作和基础骨骼分离开了,而其他部分则是可以正常播放的。
资源路径
APK

- ab文件
- spineanimations目录下都是.spineani文件,也就是自定义spine中被分离开的动作。
Update
结构与APK完全一致。

- ab文件
- assets目录下找到spineanimations
合并一下两个spineanimations目录,同名文件保留来自Update的。
├─ APK
├─ Update
└─ spineanimations
导出
Spine
导入Raz版AS,选择UnityCN key

搜索
assets/rescollection/prefabs/spine/spinedynamicassets/art/spine
不分组导出(把skel atlas png都放在一个目录,记为RES),因为如果按照容器路径导出,会有部分的atlas和png放一起,但是skel单独放在另一个目录下。
然后再把之前的spineanimations的所有.spineani文件也放到这个混合目录RES下。这样skel atlas png spineani 都在同一个目录RES之下。
DelFileSuf(.txt .bytes .asset .prefab).bat
批量去除文件后缀 asset prefab txt bytes
Live2d
就10个,嫌麻烦就算了吧。
目前没找到既能处理加密又能一键导出Live2D的AS。所以多处理一步。
手动处理UnityCN,然后导入MOD版AS一键导出。
解析Spine自定义格式
TheMoonlitOath/MergeSkelAndAni.py
Spine_Animation_o *Spine_SkeletonData__ParseBinaryAnimation
Spine_Animation__Deserialize
具体的解析细节太多,大致就是主体部分转为json后animations是空的,然后用spineani提取animations部分的数据,不展开介绍了。自定义改动的部分太多了,14种TimeLine几乎都改了,包括但不限于自定义读取方式以及大端读取。参考IDA反编译代码、SpineSkeletonDataConverter以及LLM炼丹。
目前解析的模型都可以正常运作,只有一个模型解析有略微的问题Senior_Yunwuji_Rw.json
---> System.ArgumentException: Color hexidecimal length must be 8, recieved: 5FAFFFFFF (Parameter 'hexString')
[E]2026-02-14 00:40:04 - Failed to load: D:\Tools\UsefulTools\MuMu\Shared\Download\花亦山\output\TMP\Senior\Senior_Yunwuji_Rw\Senior_Yunwuji_Rw.json, Failed to load spine with version '3.8'
手动改为5FAFFFFF,应该是多了一个F

分类
把同一个spine的skel/json png atlas 放在同名目录下。
获取UnityCN key
没什么特别之处,简述一下。
SetABEncryption <- SetAssetBundleDecryptKey <- SetAssetBundleKey


dump.cs

Unity内部的虚拟路径。

点击mono后需要导入DummyDLL还原数据


string EncryptKey = "INHJnhdypqk547xd"
string -> hex
494e484a6e68647970716b3534377864
超次元女友: 神姫放置幻想乐园
https://apps.qoo-app.com/cn/app/11256
需要合并APK bundleRes hotRes 三个部分的资源
cocos2d::FileUtils::s_decodeBuff = gameex;
void *__fastcall gameex(_QWORD *a1, _BYTE *dest_1)
size_t __fastcall gamedc(const void *src, size_t n, __int128 *a3, size_t *a4)
其中hotRes下的protector.dat 解密后 大小会变成7MB

其中的内容为以下格式 物理文件名 相对路径/虚拟文件名,也就是文件名的还原表。
1.atlas 6a85f4b6-02b9-c286-bf32-74c1835e7617/4bd42639-eeb2-72d1-2370-e69badf28083/3c6a7c80-015a-c1ba-2169-ba570a5e07e1/8ff56a66-4d8c-8ffb-9aea-5df4aeb143d6/47319e0f-e53a-0ab2-2707-b07766c443fc/8d7f802f-32fb-2bcc-836e-3226e4c0a7ef
1.json 6a85f4b6-02b9-c286-bf32-74c1835e7617/4bd42639-eeb2-72d1-2370-e69badf28083/3c6a7c80-015a-c1ba-2169-ba570a5e07e1/8ff56a66-4d8c-8ffb-9aea-5df4aeb143d6/47319e0f-e53a-0ab2-2707-b07766c443fc/f5fb22ca-6ae2-500e-d21b-bf3d6f222c0e
抓包
暴力搜索版本号CrackVersion.py,
或者通过文件版hot_res_ver.txt 获取版本号,我也不知道怎么获得这个文件。
http://kanojo-jp-cdncf.y2sgames.com/kanojo-jp/1.0.1624/hot_file_list.dat
http://kanojo-jp-cdncf.y2sgames.com/kanojo-jp/1.0.1624/protector.dat
获取热更资源清单hot_file_list.dat 以及 protector.dat 分类表,需要解密后使用。
| 对于每一行 package名称 | 压缩前大小 | MD5 | -1 | 压缩后大小 | 相对路径/文件名 |
0000154e-2527-2a4e-4803-4cbbb5e109e3 137987 5b3a3efa7ff1edb48175c3e539af1857 -1 137570 3cc2118c-8c7a-f67e-aa85-563ba61829dd/6a85f4b6-02b9-c286-bf32-74c1835e7617/47319e0f-e53a-0ab2-2707-b07766c443fc/9904f5b8-3418-7b6c-8142-6506624a975f
通过拼接http://kanojo-jp-cdncf.y2sgames.com/kanojo-jp/1.0.1624/下载package
http://kanojo-jp-cdncf.y2sgames.com/kanojo-jp/1.0.1624/0000154e-2527-2a4e-4803-4cbbb5e109e3
下载后是一个压缩包,需要解压。
所以可以反向筛选出package下载对应Spine资源
- 通过protector筛选关键词
spinehbjavgsj获取对应相对路径表 - 通过hot_file_listt 查找相对路径,获取对应的package表
- 通过package表下载资源
- 解压,通过protector再还原文件名
落星(MeteoriteFall)
Zgirls3
unzip -> cocos2d::PkJson::getFileData -> cocos2d::FileUtils::getStringFromFile -> ` cocos2d::PkJson::init`
cocos2d::PkJson::moveToNextFile

校验PK!头, 文件尾也是PK!
得到data.bin 结构
Magic 3B // "PK!"
uint16 fileCount; // big-endian
file_1
[name_len: 2B] // big-endian 00 29大端读取是41, 也就是36+5 (uuid36 + ".json"(5))
[name: name_len B]
[flag: 1B]
[size: 3B] // 体积/解压后体积 big-endian
[(optional) extra_size: 3B] // flag判断 压缩体积 big-endian
[data: size or extra_size B] // 需要先检测头, 如果是`1F 8B 08`则需要gzip解压
file_2
...
file_3
...
file_fileCount
...
Magic 3B // "PK!"
| moc3 | _1(初始服装) | _2(外出服装) | _3(沙滩泳装) | _4(学园制服) | _5(婚纱) | _6(睡衣/家居服) |
|---|---|---|---|---|---|---|
| G1_(戴假猫耳) | √ | √ | √ | √ | ||
| G4_(金色卷短发) | √ | √ | √ | √ | ||
| G5_(白毛 异色瞳 蓝粉色环) | √ | √ | √ | √ | ||
| G9_(武器 红色太刀 单马尾) | √ | √ | √ | √ | ||
| G15_(粉毛) | √ | √ | √ | |||
| G22_(黄紫毛) | √ | √ | √ | √ | √ | |
| G23_(蓝色长发) | √ | √ | √ | |||
| G24_(金长发) | √ | √ | √ | |||
| G25_(短发半遮面) | √ | √ | √ |
百分之一
DBreeze_Storage_StorageLayer__Table_Read
DBreeze_LianaTrie_LTrieRow__GetFullValue
DBreeze_LianaTrie_LTrieWriteCache__ReadValue
_DBreeze
Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00493990 6D 00 73 00 63 00 6F m.s.c.o
004939A0 00 72 00 6C 00 69 00 62 00 01 00 00 00 08 54 15 .r.l.i.b......T.
004939B0 00 00 01 00 00 00 2A 2A 2A 00 ......***.
Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
005F7B40 6D 00 73 00 63 00 6F 00 72 00 6C 00 m.s.c.o.r.l.
005F7B50 69 00 62 00 01 00 00 00 08 54 15 00 00 01 00 00 i.b......T......
005F7B60 00 2A 2A 2A 00 .***.
Iron Saga
求助大佬,机动战队(機動戦隊アイアンサーガ)的解包方法 - 讨论 - Live2DHub
The Legend of Neverland
【公式】カバラの伝説 @好評配信中 (@Cabala_JP) / X
Forgotten Journey
- .jn
- .atb
- .pvr.ccz
搜关键词.jn / .atb
BattleLayer::createHero
spUtil_readFile
spAtlas_create
spSkeletonJson_readSkeletonDataFile
cocos2d::FileUtils::getInstance
cocos2d::FileUtils::FileUtils
cocos2d::FileUtils::DecodeFile
cocos2d::ZipUtils::decodeEncodedPvr
在 cocos2d::FileUtils::FileUtils 可以找到Key YUNMIAO2014RES
加密方式 cocos2d::FileUtils::DecodeFile
def decode(data: bytes, key: bytes) -> bytes:
out = bytearray(len(data))
klen = len(key)
ki = 0
for i in range(len(data)):
out[i] = (data[i] - key[ki]) & 0xFF
ki = (ki + 1) % klen
return bytes(out)
虽然有 decodeEncodedPvr 但是实际上pvr都没有加密
溯回青空 (ReverseBlue×Re-birthEnd)
龙族卡塞尔之门
影之诗超凡世界 (Shadowverse:Beyond) Spine 加密
奇难无比
求助 影之诗Beyond如何解包 - 讨论 - Live2DHub
阴阳师:百闻牌
魂器学院
灰烬战线
龙与少女的交响曲
失落之剑
魔竞革命
放置天使
Angelica Aster R
求助AngelicaAsterR解包问题 - 讨论 - Live2DHub
异域战记
铃兰之剑
三国杀
三国杀移动美化版解包资源【安装包】【SPINE】 - 资源 - Live2DHub
千年之旅
禁欲战姬
依露希尔
UnityCN
spine都只有待机动作的,没什么可聊的。
assets/rawresource/ui/spineskeletons/
assets/loadableresources/ui/spineskeletons/char
assets/loadableresources/story/timelineprefabs/
有几个文件名一坨,png不带后缀,自行搜索单独处理。
Nikke
尘白禁区 UE
40G
AES: 0xC14735FB5A872D2AFA76A5C38521AB8B8E21072C08525B913307608BD1182FA7
鸣潮 UE
模板() Spine/Livc2D 加密
鉴赏环节。10.0分。
Comments