搞不懂,这游戏策划和其他ero不一样,咋一直换加密,也没几个角色
,前前后后换了有3次了,防谁啊![]()
好家伙又换了,我说怎么解不出来
有大佬能教一下怎么调图层吗?有的眼皮没了 有的JJ穿模了
他live2d不是隐藏了吗,你解出来了?
全部换成Spine了,图还是原来live2d的图,另外之前也说过了,只有在游戏中访问HCG才会下载对应的HCG文件
我还以为有办法直接下载hcg的资源包了呢,谢谢解惑
清单可能就是bin明码那些,关键是下载地址是经过处理的,同一份文件的清单、下载、本地保存名称均不一致
看了一下有些可读的ASCII
但是Bson解析也是失败或许又是哪个没见过的压缩格式
这不一眼二进制catalog吗,直接AddressablestoolsPy之类的解析啊。
catalog_1.16.002.bin这文件没啥用, 里面不是资产的下载清单,单纯就是unity文件的引用id
解析后可以看到一些包名类似
from pathlib import Path
from AddressablesToolsPy.src.AddressablesTools import parse_binary
from AddressablesToolsPy.src.AddressablesTools.Catalog.SerializedObjectDecoder import SerializedObjectDecoder
CATALOG_PATH = r"C:\Users\1\Downloads\catalog_1.16.002.bin"
def create_patcher():
def patcher(match_name: str) -> str:
if "EncryptedAssetBundleRequestOptions" in match_name:
return SerializedObjectDecoder.ABRO_MATCHNAME
elif "AssetBundleRequestOptions" in match_name:
return SerializedObjectDecoder.ABRO_MATCHNAME
return match_name
return patcher
def load_catalog(path: str):
data = Path(path).read_bytes()
patcher = create_patcher()
catalog = parse_binary(data, patcher=patcher)
return catalog
def dump_bundles(catalog):
print(f"资源总数: {len(catalog.Resources)}")
print("-" * 60)
# 打开文件 a.xtx,模式为写入('w'),会覆盖已有内容
with open("a.xtx", "w", encoding="utf-8") as f:
for name_key, infos in catalog.Resources.items():
if isinstance(name_key, str):
f.write(f"{name_key}\n") # 写入文件并换行
if __name__ == "__main__":
catalog = load_catalog(CATALOG_PATH)
dump_bundles(catalog)
晚点再研究AddressablesToolsPy吧在给python3.14造轮子
看文件url长度像是sha256的结果交叉引用没发现啥东西可能是自定义的算法
3.14运行速度提升挺大的在把3.9的环境升级上去就是折磨…
这个id不对,应该是通过加密获得的最终下载链接,只能反编译看源码
我也是这么认为的,只不过反编译我实在是不怎么擅长
找了一圈估计这个函数就是
System_String_o *BCUL_AddressablesManager_ResourceProviders_EncryptedAssetBundleResource__CalcHashName(
System_String_o *baseFileName,
UnityEngine_ResourceManagement_ResourceProviders_AssetBundleRequestOptions_o *options,
const MethodInfo *method)
{
uint32_t m_Crc; // w9
const MethodInfo *v6; // x4
UnityEngine_Hash128_o v7; // kr00_16
BCUL_AddressablesManager_CachingBundle_c *v8; // x0
uint32_t val; // [xsp+Ch] [xbp-24h] BYREF
if ( (byte_96CE867 & 1) == 0 )
{
sub_3D6561C();
sub_3D6561C();
byte_96CE867 = 1;
}
if ( options )
m_Crc = options->fields.m_Crc;
else
m_Crc = 0;
val = m_Crc;
v7 = UnityEngine_Hash128__Compute_uint_(&val, (const MethodInfo_522E5FC *)Method_UnityEngine_Hash128_Compute_uint___);
v8 = BCUL_AddressablesManager_CachingBundle_TypeInfo;
if ( !BCUL_AddressablesManager_CachingBundle_TypeInfo->_2.cctor_finished )
{
j_il2cpp_runtime_class_init_0(BCUL_AddressablesManager_CachingBundle_TypeInfo, v7.fields.u64_1);
v8 = BCUL_AddressablesManager_CachingBundle_TypeInfo;
}
return BCUL_AddressablesManager_AssetBundleUtils__GetHashName(baseFileName, v8->static_fields->AbHashKey, v7, v6);
}
System_String_o *BCUL_AddressablesManager_AssetBundleUtils__GetHashName(
System_String_o *assetBundleName,
System_String_o *hashKey,
UnityEngine_Hash128_o assetBundleHash,
const MethodInfo *method)
{
Il2CppObject *v6; // x0
System_String_o *v7; // x0
System_String_o *v8; // x19
System_Text_Encoding_o *UTF8; // x0
System_Byte_array *v10; // x0
const MethodInfo *v11; // x1
System_Byte_array *v12; // x20
System_Text_StringBuilder_o *v13; // x19
il2cpp_array_size_t max_length; // x8
unsigned __int64 v15; // x21
System_String_o *v16; // x0
UnityEngine_Hash128_o v18; // [xsp+0h] [xbp-60h] BYREF
uint8_t v19; // [xsp+1Ch] [xbp-44h] BYREF
UnityEngine_Hash128_o v20; // [xsp+20h] [xbp-40h] BYREF
UnityEngine_Hash128_o v21; // 0:x0.16
v20 = assetBundleHash;
if ( (byte_96CE828 & 1) == 0 )
{
sub_3D6561C();
sub_3D6561C();
sub_3D6561C();
sub_3D6561C();
sub_3D6561C();
byte_96CE828 = 1;
}
v21.fields.u64_0 = (uint64_t)&v20;
v21.fields.u64_1 = 0LL;
v19 = 0;
if ( UnityEngine_Hash128__get_isValid(v21, (const MethodInfo *)assetBundleHash.fields.u64_0) )
{
v18 = v20;
v6 = (Il2CppObject *)j_il2cpp_value_box_0(UnityEngine_Hash128_TypeInfo, &v18);
v7 = System_String__Format_130277216(
(System_String_o *)StringLiteral_17126,
(Il2CppObject *)assetBundleName,
v6,
(Il2CppObject *)hashKey,
0LL);
}
else
{
v7 = System_String__Concat_130275884(assetBundleName, (System_String_o *)StringLiteral_868, hashKey, 0LL);
}
v8 = v7;
UTF8 = System_Text_Encoding__get_UTF8(0LL);
if ( !UTF8 )
goto LABEL_15;
v10 = (System_Byte_array *)((__int64 (__fastcall *)(System_Text_Encoding_o *, System_String_o *, const MethodInfo *))UTF8->klass->vtable._18_GetBytes.methodPtr)(
UTF8,
v8,
UTF8->klass->vtable._18_GetBytes.method);
v12 = BCUL_AddressablesManager_AssetBundleUtils__ComputeHash(v10, v11);
v13 = (System_Text_StringBuilder_o *)sub_3D658A4(System_Text_StringBuilder_TypeInfo);
System_Text_StringBuilder___ctor(v13, 0LL);
if ( !v12 )
goto LABEL_15;
max_length = v12->max_length;
if ( (int)max_length >= 1 )
{
v15 = 0LL;
while ( 1 )
{
if ( v15 >= (unsigned int)max_length )
sub_3D658B0();
v19 = v12->m_Items[v15];
v16 = System_Byte__ToString_131272268((uint8_t)&v19, (System_String_o *)StringLiteral_16888, 0LL);
if ( !v13 )
break;
System_Text_StringBuilder__Append_130329112(v13, v16, 0LL);
LODWORD(max_length) = v12->max_length;
if ( (__int64)++v15 >= (int)max_length )
goto LABEL_13;
}
LABEL_15:
sub_3D658A8();
}
LABEL_13:
if ( !v13 )
goto LABEL_15;
return (System_String_o *)((__int64 (__fastcall *)(System_Text_StringBuilder_o *, const MethodInfo *))v13->klass->vtable._3_ToString.methodPtr)(
v13,
v13->klass->vtable._3_ToString.method);
}
System_Byte_array *BCUL_AddressablesManager_AssetBundleUtils__ComputeHash(
System_Byte_array *buffer,
const MethodInfo *method)
{
System_Security_Cryptography_SHA256CryptoServiceProvider_o *v3; // x19
__int64 v4; // x3
System_Byte_array *v5; // x21
System_Security_Cryptography_SHA256CryptoServiceProvider_c *klass; // x8
__int64 v7; // x9
int32_t *p_offset; // x10
__int64 v9; // x0
if ( (byte_96CE825 & 1) == 0 )
{
sub_3D6561C();
sub_3D6561C();
byte_96CE825 = 1;
}
v3 = (System_Security_Cryptography_SHA256CryptoServiceProvider_o *)sub_3D658A4(System_Security_Cryptography_SHA256CryptoServiceProvider_TypeInfo);
System_Security_Cryptography_SHA256CryptoServiceProvider___ctor(v3, 0LL);
if ( !v3 )
sub_3D658A8();
v5 = System_Security_Cryptography_HashAlgorithm__ComputeHash(
(System_Security_Cryptography_HashAlgorithm_o *)v3,
buffer,
0LL);
klass = v3->klass;
v7 = *(unsigned __int16 *)&v3->klass->_2.rank;
if ( *(_WORD *)&v3->klass->_2.rank )
{
p_offset = &klass->_1.interfaceOffsets->offset;
while ( *((System_IDisposable_c **)p_offset - 1) != System_IDisposable_TypeInfo )
{
--v7;
p_offset += 4;
if ( !v7 )
goto LABEL_8;
}
v9 = (__int64)&klass->vtable + 16 * *p_offset;
}
else
{
LABEL_8:
v9 = sub_3D24214(v3, System_IDisposable_TypeInfo, 0LL, v4);
}
(*(void (__fastcall **)(System_Security_Cryptography_SHA256CryptoServiceProvider_o *, _QWORD))v9)(
v3,
*(_QWORD *)(v9 + 8));
return v5;
}
看样子确实最后是sha256
最后还是挺烦人的感觉很多参数不确定得动态调试
catalog完全解析出来差不多如
{
"EntryCount": 139056,
"Resources": {
"00033a27790b90e88dd5ba3e653f1f3c.bundle": [
{
"__type__": "ResourceLocation",
"Data": {
"__type__": "WrappedSerializedObject",
"Object": {
"__type__": "AssetBundleRequestOptions",
"BundleName": "4694165b0206bf77910ebd6a1191b9e3",
"BundleSize": 90362,
"ComInfo": {
"__type__": "CommonInfo",
"AssetLoadMode": {
"__type__": "AssetLoadMode",
"_value_": 0,
"_name_": "RequestedAssetAndDependencies",
"__objclass__": {
"__type__": "EnumType",
"_generate_next_value_": "<max_depth:staticmethod>",
"__module__": "AddressablesTools.Classes.AssetBundleRequestOptions",
"__firstlineno__": 10,
"__static_attributes__": "<max_depth:tuple>",
"_new_member_": "<max_depth:builtin_function_or_method>",
"_use_args_": false,
"_member_names_": "<max_depth:list>",
"_member_map_": "<max_depth:dict>",
"_value2member_map_": "<max_depth:dict>",
"_hashable_values_": "<max_depth:list>",
"_unhashable_values_": "<max_depth:list>",
"_unhashable_values_map_": "<max_depth:dict>",
"_member_type_": "<max_depth:type>",
"_value_repr_": null,
"__doc__": null,
"RequestedAssetAndDependencies": "<cycle:AssetLoadMode>",
"AllPackedAssetsAndDependencies": "<max_depth:AssetLoadMode>",
"__new__": "<max_depth:function>"
},
"_sort_order_": 0
},
"ChunkedTransfer": false,
"ClearOtherCachedVersionsWhenLoaded": false,
"RedirectLimit": 32,
"RetryCount": 0,
"Timeout": 0,
"UseCrcForCachedBundle": true,
"UseUnityWebRequestForLocalBundles": false,
"Version": 3
},
"Crc": 3583767260,
"Hash": "00033a27790b90e88dd5ba3e653f1f3c"
},
"Type": {
"__type__": "SerializedType",
"AssemblyName": "Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "BCUL.AddressablesManager.ResourceProviders.EncryptedAssetBundleRequestOptions"
}
},
"Dependencies": [],
"DependencyHashCode": 0,
"DependencyKey": null,
"HashCode": 0,
"InternalId": "{AM.RemoteAssetRootURL}/00033a27790b90e88dd5ba3e653f1f3c.bundle",
"PrimaryKey": "00033a27790b90e88dd5ba3e653f1f3c.bundle",
"ProviderId": "BCUL.AddressablesManager.ResourceProviders.EncryptedAssetBundleProvider",
"Type": {
"__type__": "SerializedType",
"AssemblyName": "Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "UnityEngine.ResourceManagement.ResourceProviders.IAssetBundleResource"
}
}
],
"000b49d70268e5ab9e28dbeb5c56bade.bundle": [
{
"__type__": "ResourceLocation",
"Data": {
"__type__": "WrappedSerializedObject",
"Object": {
"__type__": "AssetBundleRequestOptions",
"BundleName": "7696b61c32022de421b8b69b8b6643ac",
"BundleSize": 14353,
"ComInfo": {
"__type__": "CommonInfo",
"AssetLoadMode": {
"__type__": "AssetLoadMode",
"_value_": 0,
"_name_": "RequestedAssetAndDependencies",
"__objclass__": {
"__type__": "EnumType",
"_generate_next_value_": "<max_depth:staticmethod>",
"__module__": "AddressablesTools.Classes.AssetBundleRequestOptions",
"__firstlineno__": 10,
"__static_attributes__": "<max_depth:tuple>",
"_new_member_": "<max_depth:builtin_function_or_method>",
"_use_args_": false,
"_member_names_": "<max_depth:list>",
"_member_map_": "<max_depth:dict>",
"_value2member_map_": "<max_depth:dict>",
"_hashable_values_": "<max_depth:list>",
"_unhashable_values_": "<max_depth:list>",
"_unhashable_values_map_": "<max_depth:dict>",
"_member_type_": "<max_depth:type>",
"_value_repr_": null,
"__doc__": null,
"RequestedAssetAndDependencies": "<cycle:AssetLoadMode>",
"AllPackedAssetsAndDependencies": "<max_depth:AssetLoadMode>",
"__new__": "<max_depth:function>"
},
"_sort_order_": 0
},
"ChunkedTransfer": false,
"ClearOtherCachedVersionsWhenLoaded": false,
"RedirectLimit": 32,
"RetryCount": 0,
"Timeout": 0,
"UseCrcForCachedBundle": true,
"UseUnityWebRequestForLocalBundles": false,
"Version": 3
},
"Crc": 1295375149,
"Hash": "000b49d70268e5ab9e28dbeb5c56bade"
},
"Type": {
"__type__": "SerializedType",
"AssemblyName": "Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "BCUL.AddressablesManager.ResourceProviders.EncryptedAssetBundleRequestOptions"
}
},
"Dependencies": [],
"DependencyHashCode": 0,
"DependencyKey": null,
"HashCode": 0,
"InternalId": "{AM.RemoteAssetRootURL}/000b49d70268e5ab9e28dbeb5c56bade.bundle",
"PrimaryKey": "000b49d70268e5ab9e28dbeb5c56bade.bundle",
"ProviderId": "BCUL.AddressablesManager.ResourceProviders.EncryptedAssetBundleProvider",
"Type": {
"__type__": "SerializedType",
"AssemblyName": "Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "UnityEngine.ResourceManagement.ResourceProviders.IAssetBundleResource"
}
}
],
"00109695489693987c9d5757005e1dec.bundle": [
{
"__type__": "ResourceLocation",
"Data": {
"__type__": "WrappedSerializedObject",
"Object": {
"__type__": "AssetBundleRequestOptions",
"BundleName": "6105ff46aa23fdfc1804a9619d1d4343",
"BundleSize": 6270,
"ComInfo": {
"__type__": "CommonInfo",
"AssetLoadMode": {
"__type__": "AssetLoadMode",
"_value_": 0,
"_name_": "RequestedAssetAndDependencies",
"__objclass__": {
"__type__": "EnumType",
"_generate_next_value_": "<max_depth:staticmethod>",
"__module__": "AddressablesTools.Classes.AssetBundleRequestOptions",
"__firstlineno__": 10,
"__static_attributes__": "<max_depth:tuple>",
"_new_member_": "<max_depth:builtin_function_or_method>",
"_use_args_": false,
"_member_names_": "<max_depth:list>",
"_member_map_": "<max_depth:dict>",
"_value2member_map_": "<max_depth:dict>",
"_hashable_values_": "<max_depth:list>",
"_unhashable_values_": "<max_depth:list>",
"_unhashable_values_map_": "<max_depth:dict>",
"_member_type_": "<max_depth:type>",
"_value_repr_": null,
"__doc__": null,
"RequestedAssetAndDependencies": "<cycle:AssetLoadMode>",
"AllPackedAssetsAndDependencies": "<max_depth:AssetLoadMode>",
"__new__": "<max_depth:function>"
},
"_sort_order_": 0
},
"ChunkedTransfer": false,
"ClearOtherCachedVersionsWhenLoaded": false,
"RedirectLimit": 32,
"RetryCount": 0,
"Timeout": 0,
"UseCrcForCachedBundle": true,
"UseUnityWebRequestForLocalBundles": false,
"Version": 3
},
"Crc": 949661317,
"Hash": "00109695489693987c9d5757005e1dec"
},
"Type": {
"__type__": "SerializedType",
"AssemblyName": "Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "BCUL.AddressablesManager.ResourceProviders.EncryptedAssetBundleRequestOptions"
}
},
"Dependencies": [],
"DependencyHashCode": 0,
"DependencyKey": null,
"HashCode": 0,
"InternalId": "{AM.RemoteAssetRootURL}/00109695489693987c9d5757005e1dec.bundle",
"PrimaryKey": "00109695489693987c9d5757005e1dec.bundle",
"ProviderId": "BCUL.AddressablesManager.ResourceProviders.EncryptedAssetBundleProvider",
"Type": {
"__type__": "SerializedType",
"AssemblyName": "Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "UnityEngine.ResourceManagement.ResourceProviders.IAssetBundleResource"
}
}
],...
}
BCUL_AddressablesManager_AssetBundleUtils__GetHashName(baseFileName, v8->static_fields->AbHashKey, v7, v6);
得知道这个AbHashKey怎么得到的
import requests
import json
import msgpack
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import unpad, pad
def xor(enc, k):
return "".join(chr(ord(c) ^ k) for c in enc)
def parse(data):
return msgpack.unpackb(
unpad(
AES.new(
base64.b64decode(
xor("ypqoI-OwPJmPI.uTO.OuKpm,JsSGSJGoDvekGHejNpH ", 29).replace(
"\\", "/"
)
),
AES.MODE_CBC,
base64.b64decode(xor("O,dsS/(2+OGqs%2+jd[PL\\ ", 29)),
).decrypt(base64.b64decode(msgpack.unpackb(data, raw=False)["p"])),
AES.block_size,
),
raw=False,
)
def encrypt(data: dict) -> str:
return base64.b64encode(
AES.new(
base64.b64decode(
xor("ypqoI-OwPJmPI.uTO.OuKpm,JsSGSJGoDvekGHejNpH ", 29).replace(
"\\", "/"
)
),
AES.MODE_CBC,
base64.b64decode(xor("O,dsS/(2+OGqs%2+jd[PL\\ ", 29)),
).encrypt(pad(msgpack.packb(data, use_bin_type=True), AES.block_size))
).decode("utf-8")
headers = {
"User-Agent": "UnityPlayer/2022.3.62f2 (UnityWebRequest/1.0, libcurl/8.10.1-DEV)",
"Accept-Encoding": "deflate, gzip",
"Accept-ViewType": "7",
"X-Unity-Version": "2022.3.62f2",
}
payload = {
"c": "Index",
"dgs_adult": 1,
"app_vc": {
"os": 1,
"catalog": "",
"use_cdn": "https://gina.sangduoan.com/prod",
"app_ver": "1.13.000",
"app_type": 1,
},
}
response = requests.post(
"https://prod.karen-megahare.com/i.php",
data={"p": encrypt(payload)},
headers=headers,
)
print(json.dumps(parse(response.content), indent=4))
变更:突然发现下发的json里面没有hash key了,应该是他们又改了啥,也可能少参数了,以前是能获取到的
2 个赞












