。。。记得带上游戏名:龙珠激斗(Dragonball Mobile)
import sys
import struct
import lz4.block
S_XXTEA_KEY = b"\x1a\xa3\x4b\xac\x2c\x85\xb1\x8e\x9a\xd0\xa2\xc3\x0f\x97\x62\xf4"
def to_words(d):
nw = (len(d) + 3) // 4
return list(struct.unpack(f"<{nw}I", d.ljust(nw * 4, b"\0")))
def to_bytes(words):
return struct.pack(f"<{len(words)}I", *words)
def xxtea_decrypt(d, dk):
DELTA = 0x9E3779B9
SUM_OFFSET = 0xB54CDA56
v = to_words(d)
k = to_words(dk)
n = len(v)
if n <= 1:
return to_bytes(v)
sv = (52 // n * DELTA + SUM_OFFSET) & 0xFFFFFFFF
y = v[0]
while sv != 0:
e = (sv >> 2) & 3
p = n - 1
while p > 0:
z = v[p - 1]
mx = ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) & 0xFFFFFFFF
dk = ((sv ^ y) + (k[(p & 3) ^ e] ^ z)) & 0xFFFFFFFF
v[p] = (v[p] - (mx ^ dk)) & 0xFFFFFFFF
y = v[p]
p -= 1
z = v[n - 1]
mx = ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) & 0xFFFFFFFF
dk = ((sv ^ y) + (k[(p & 3) ^ e] ^ z)) & 0xFFFFFFFF
v[0] = (v[0] - (mx ^ dk)) & 0xFFFFFFFF
y = v[0]
sv = (sv - DELTA) & 0xFFFFFFFF
return to_bytes(v)
def decrypt(i, o):
with open(i, "rb") as f:
enc = f.read()
s = enc[2]
es = struct.unpack("<I", enc[19:23])[0]
if s == 33:
km = enc[3:19]
dk = bytes([S_XXTEA_KEY[i] ^ km[i] for i in range(16)])
ed = enc[23:]
xd = xxtea_decrypt(ed, dk)
dec = lz4.block.decompress(
xd[4 : 4 + (struct.unpack("<I", xd[-4:])[0] - 4)], uncompressed_size=es
)
elif s == 101:
km = enc[3:19]
dk = bytes([S_XXTEA_KEY[i] ^ km[i] for i in range(16)])
ed = enc[23:]
dec = xxtea_decrypt(ed, dk)[:es]
if dec:
with open(o, "wb") as f:
f.write(dec)
if __name__ == "__main__":
decrypt(sys.argv[1], "dec")