(已解决)求助,幻想曹操传2 解包求助

通过网盘分享的文件:huanxiang
链接: 百度网盘 请输入提取码 提取码: e92g
pass:0721

该游戏对游戏资源进行了加密
连png也加密了,根本解不出来

from pathlib import Path
from json import loads as cJson
from numpy import frombuffer as npbf, tile as nptl

SIGNLEN, KEYLEN = len((SIGN := b'sign_sunnygame675')), (KEY := npbf(b'key_gamesunny326', dtype='<u1')).size

def Loop(d: dict, res: dict, start: int, path: str = ''):
    for k, v in d.items():
        if (o := v.get('offset', None)) is None:
            Loop(v['files'], res, start, f'{path}{k}/')
        else:
            if (size := v['size']) <= 0:
                return
            res[f'{path}{k}'] = {'size':size, 'offset':start + int(o)}

def Decrypt(data: bytes) -> bytes:
    if data.startswith(SIGN):
        arr, length = npbf(data[SIGNLEN:], dtype='<u1'), len(data) - SIGNLEN
        data = (arr ^ nptl(KEY, -(-length // KEYLEN))[:length]).tobytes()
    return data

def extract(asar: str, out: str):
    outpath= Path(out).joinpath('Extract')
    with open(asar, 'rb') as f:
        ints, res = [int.from_bytes(f.read(4), 'little', signed=False) for _ in range(4)], {}
        Loop(cJson(f.read(ints[3]))['files'], res, ints[1] + 8)
        for k, v in res.items():
            f.seek(v['offset'])
            data = Decrypt(f.read(v['size']))
            path = outpath.joinpath(k)
            path.parent.mkdir(parents=True, exist_ok=True)
            with path.open('wb') as w:
                w.write(data)

if __name__ == '__main__':
    inpath = r'D:\BaiduNetdiskDownload\huanxiang\app.asar' # app.asar 路径
    outpath = r'D:\BaiduNetdiskDownload\huanxiang' # 导出路径
    extract(inpath, outpath)

加密只是xor, 包的格式也简单
前16字节是 4个 uint32
跳到16字节, 然后根据第4个uint32读取对应的长度的数据转成字典
然后根据字典的偏移和位移拆文件就好

感谢大佬,真的成功了