闪烁之光解密求助

《闪烁之光》手游官网——七周年庆「夏日爽玩服」重磅开启!七年不散场,今夏一起爽!

png skel atlas 都加密了

通过网盘分享的文件:E14303.rar

链接: 百度网盘 请输入提取码 提取码: 2axz

有FG壳子,想弄得慢慢解咯…

fg没啥难度,直接dump然后回填就行,就是他这个在xxtea之前还在fg的vm里面白化
我说放置千千万,怎么玩这么拉的,立绘和spine也太拉了。。要不是有fg我都懒得看

from __future__ import annotations

import struct
from pathlib import Path

import cxxtea

SIGN = b"8be795854eaf54b1"
KEY = b"777e82adc842b744"
ROOT = Path(__file__).resolve().parent


def _u32(buf: bytes, off: int) -> int:
    return struct.unpack_from("<I", buf, off)[0]


def _w24(size: int) -> int:
    n = min(size, 0x1000)
    seed = struct.pack("<II", n ^ 0xDF6EFCC8, n ^ 0xB7F52CC3)
    h = 0x287EFE6D
    s8 = 0x35E82AB2
    for b in seed:
        h = (h + ((h << 5) & 0xFFFFFFFF) + b) & 0xFFFFFFFF
        if (h & 0xF) > 0xA:
            h = ((h ^ 1) + 0x62654F67) & 0xFFFFFFFF
        elif ((h >> 4) & 0xF) == 0xF:
            h = ((h ^ 1) + (s8 ^ 0xDF5CCFCB)) & 0xFFFFFFFF
        elif ((h >> 8) & 0xF) <= 1:
            s8 = h ^ 0x0885EA87
        elif ((s8 + 0x567A) & 0xFFFFFFFF) <= 0xA9117213:
            if (s8 ^ 0x3D591079) <= 0xD269BB3D:
                s8 = 0xD269BB3D ^ (s8 >> 8)
            elif h <= 0x76F780AC:
                s8 = h ^ ((s8 + 0xAB878EC2) & 0xFFFFFFFF)
            else:
                s8 = ((h + 0xEB29FCFB) ^ 0xD269BB3D) & 0xFFFFFFFF
        else:
            s8 = h ^ (s8 >> 16)
    return h


def _rc4mod(data: bytes, key: bytes) -> bytes:
    s = list(range(256))
    j = 0
    kl = len(key)
    for i in range(256):
        j = (j + s[i] + key[i % kl]) & 255
        s[i], s[j] = s[j], s[i]
    i = j = 0
    out = bytearray(data)
    for n in range(len(out)):
        i = (i + 1) & 255
        j = (j + s[i]) & 255
        s[i], s[j] = s[j], s[i]
        k = s[(s[i] + s[j]) & 255]
        k = ((k << 4) | (k >> 4)) & 255
        out[n] ^= (k - 0x16) & 255
    return bytes(out)


def _mod9(x: int) -> int:
    return x % 9


def fg_whiten(data: bytes) -> bytes:
    n = min(len(data), 0x1000)
    if n <= 0:
        return data
    w24 = _w24(len(data))
    out = bytearray(data)
    head = _rc4mod(bytes(out[: min(n, 256)]), struct.pack("<I", w24))
    out[: len(head)] = head
    if n <= 256:
        return bytes(out)
    k0 = _u32(data, 0x50) ^ (n ^ 0xB7F52CC3)
    k1 = _u32(data, 0x7C) ^ (n ^ 0xDF6EFCC8)
    k2 = _u32(data, 0xC0) ^ n
    k3 = w24 ^ _u32(data, 0xE0)
    k16w = (k0, k1, k2, k3)
    x22 = _rc4mod(data[:256], struct.pack("<4I", *k16w))
    ux = lambda o: _u32(x22, o)
    x19 = [0] * 9
    x19[0] = ux(0x30) ^ 0xA527D5A5
    x19[1] = k3 ^ 0x1602656E
    x19[2] = x19[0] ^ ux(0xE4)
    x19[4] = k0 ^ 0xA40565FB
    x19[5] = k1 ^ 0x1CCD73D7
    x19[7] = x19[1] ^ k2
    x19[3] = x19[7] ^ ux(0x98)
    x19[6] = x19[5] ^ ux(0xB0)
    x19[8] = x19[4] ^ ux(0xF4)  # (x19[4]-2+2) ^ x22[0xF4]
    nblk = (n - 256) >> 8
    for b in range(nblk):
        sel = x19[b % 9] & 3
        base = 256 + b * 256
        if sel == 0:
            for i in range(64):
                v = _u32(out, base + i * 4) ^ _u32(x22, i * 4) ^ (0x40 - i)
                v ^= x19[_mod9(k16w[i & 3])]
                struct.pack_into("<I", out, base + i * 4, v & 0xFFFFFFFF)
        elif sel == 1:
            for i in range(64):
                xw = _u32(x22, i * 4)
                v = _u32(out, base + i * 4) ^ xw ^ k16w[xw & 3] ^ x19[_mod9(xw)]
                struct.pack_into("<I", out, base + i * 4, v & 0xFFFFFFFF)
        elif sel == 2:
            for i in range(64):
                xw = _u32(x22, i * 4)
                v = _u32(out, base + i * 4) ^ xw ^ i ^ k16w[xw & 3]
                struct.pack_into("<I", out, base + i * 4, v & 0xFFFFFFFF)
        else:
            for i in range(64):
                v = _u32(out, base + i * 4) ^ _u32(x22, i * 4) ^ (0x40 - i)
                v ^= k16w[x19[i % 9] & 3]
                struct.pack_into("<I", out, base + i * 4, v & 0xFFFFFFFF)
    tail = n - 256 - nblk * 256
    tbase = 256 + nblk * 256
    for i in range(tail):
        kw = k16w[i & 3]
        t = x19[_mod9(kw)]
        out[tbase + i] ^= x22[i] ^ (i & 255) ^ (t % 255)
    return bytes(out)


def xxtea_decrypt(data: bytes, key: bytes) -> bytes:
    return cxxtea.decrypt(key + data, key, key)


def decrypt_res(blob: bytes, key: bytes = KEY) -> bytes:
    if not blob.startswith(SIGN):
        return blob
    return xxtea_decrypt(fg_whiten(blob[len(SIGN) :]), key)

1 个赞

大老,小白这边有尝试另一款游戏

目前是能dump出so出来,但感觉相当不全

libcocos2dlua.zip (5.0 MB)

不太了解还需要dump什么才能做回填的动作,要如何回填
希望能多讲解些