求助,花妖物语解包教程

游戏内的ab包进行了加密,作为初学者实在每头绪,希望大佬能教一下如何解包。

游戏链接: https://pan.baidu.com/s/1-uVddF5vLwdzXMYlZLXolQ?pwd=1111 提取码: 1111


有大佬能麻烦教一下吗?bundle文件里面也没查找到头文件和版本信息

#!/usr/bin/env python3

-- coding: utf-8 --

import os
import sys
import struct
import argparse
from Crypto.Cipher import AES

KEY = bytes.fromhex(“4142434445464748494a4b4c4d4e4f50”)
MODE = AES.MODE_ECB

def decrypt_data(data: bytes) → bytes:
if len(data) % 16 != 0:
raise ValueError(f"len {len(data)} not multiple of 16")
plain = AES.new(KEY, MODE).decrypt(data)
if plain[:8] == b"UnityFS\x00":
file_size = struct.unpack_from(“>q”, plain, 32)[0]
if 0 < file_size <= len(plain):
plain = plain[:file_size]
return plain

def check_bundle(path: str) → bool:
with open(path, “rb”) as f:
head = f.read(64)
p = decrypt_data(head)
ok = p[:8] == b"UnityFS\x00"
if ok:
fmt_ver = struct.unpack_from(“>I”, p, 8)[0]
guv = p[12:18]
uv = p[18:32]
file_size = struct.unpack_from(“>q”, p, 32)[0]
csize = struct.unpack_from(“>I”, p, 40)[0]
usize = struct.unpack_from(“>I”, p, 44)[0]
flags = struct.unpack_from(“>I”, p, 48)[0]
real = os.path.getsize(path)
print(f" [OK] formatVersion={fmt_ver} genVersion={guv!r} unityVersion={uv!r}“)
print(f” fileSize(BE)={file_size} (real {real}) csize={csize} usize={usize} flags=0x{flags:x}")
return ok

def find_encrypted_files(root: str):
result =[]
for dirpath, _, filenames in os.walk(root):
for fn in filenames:
path = os.path.join(dirpath, fn)
try:
if os.path.getsize(path) < 64:
continue
with open(path, “rb”) as f:
head = f.read(16)
if len(head) != 16:
continue
if head[:8] == b"UnityFS\x00":
continue
p = AES.new(KEY, MODE).decrypt(head)
if p[:8] == b"UnityFS\x00":
result.append(path)
except Exception:
continue
return sorted(result)

def main():
ap = argparse.ArgumentParser()
ap.add_argument(“–check”, action=“store_true”)
ap.add_argument(“–out”, default=None)
args = ap.parse_args()

script_dir = os.path.dirname(os.path.abspath(__file__))
print(f"scan root: {script_dir}")
files = find_encrypted_files(script_dir)
print(f"found {len(files)} encrypted files\n")

if not files:
    return

if args.check:
    ok = check_bundle(files[0])
    print("check", "passed" if ok else "failed")
    return

out_dir = args.out or os.path.join(script_dir, "decrypted_bundles")
os.makedirs(out_dir, exist_ok=True)

ok_count = 0
total = 0
for src in files:
    rel = os.path.relpath(src, script_dir)
    dst = os.path.join(out_dir, rel)
    os.makedirs(os.path.dirname(dst), exist_ok=True)
    data = open(src, "rb").read()
    total += len(data)
    plain = decrypt_data(data)
    open(dst, "wb").write(plain)
    good = plain[:8] == b"UnityFS\x00"
    if good:
        ok_count += 1
    print(f"  [{'OK' if good else 'FAIL'}] {rel}  ({len(data)} -> {len(plain)} bytes)")

print(f"\ndone: {ok_count}/{len(files)} ok, {total/1048576:.1f} MB")
print(f"output: {out_dir}")

if name == “main”:
main()