有大大会解重构阿塔提丝吗,这游戏快停服了想解包资源纪念
import os
import lzma
from pathlib import Path
from decrypt_tea import decrypt_tea
#State base folder (which should contain the 7z files) no / or \ at the end
#Process will create "LZMA", "Encrypted Bundles" and "Decrypted Bundles" subfolders within that folder
input_folder = Path(r"C:\Users\casey\Desktop\Re-Aetatis")
LZMA_folder = input_folder / "LZMA"
Encrypted_folder = input_folder /"Encrypted Bundles"
Output_folder = input_folder /"Decrypted Bundles"
os.makedirs(LZMA_folder, exist_ok=True)
os.makedirs(Encrypted_folder, exist_ok=True)
os.makedirs(Output_folder, exist_ok=True)
delimiter = bytes([0x5D, 0x00, 0x00, 0x80, 0x00])
for filename in os.listdir(input_folder):
if filename.endswith('.7z'):
file_path = os.path.join(input_folder, filename)
with open(file_path, 'rb') as file:
data = file.read()
split_data = data.split(delimiter)
for i, chunk in enumerate(split_data):
chunk = delimiter + chunk
output_file = os.path.join(LZMA_folder, f"{os.path.splitext(filename)[0]}_{i}.dat")
with open(output_file, 'wb') as out_file:
out_file.write(chunk)
#LZMA Decompress
for filename in os.listdir(LZMA_folder):
if filename.endswith('.dat'):
bin_file_path = os.path.join(LZMA_folder, filename)
with open(bin_file_path, 'rb') as f:
compressed_data = f.read()
try:
decompressed_data = lzma.decompress(compressed_data)
with open(bin_file_path, 'wb') as f:
f.write(decompressed_data)
except:
continue
# Header and footer bytes - encrypted Unity header + "Androi" for footer - dont really know how the manifest reads the files
#just brute force it
header = bytes([0xDB, 0x86, 0xE3, 0xD0, 0xE5, 0x6C])
footer = bytes([0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69])
for filename in os.listdir(LZMA_folder):
input_file_path = os.path.join(LZMA_folder, filename)
with open(input_file_path, 'rb') as f:
content = f.read()
start = 0
file_index = 0
positions_dict = {}
while True:
start = content.find(header, start)
if start == -1:
break
end = content.find(footer, start)
if end == -1:
break
end += len(footer)
positions_dict[file_index] = (start, end)
file_index += 1
start = end
for index, (start_pos, end_pos) in positions_dict.items():
output_file_path = os.path.join(Encrypted_folder, f"{os.path.splitext(filename)[0]}_{index}.dat")
with open(output_file_path, 'wb') as output_file:
output_file.write(content[start_pos:end_pos-14])
#Uncomment if import from pyd doesn't work
#def bswap32(x):
# return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x >> 8) & 0xFF00) | ((x >> 24) & 0xFF)
#def decrypt_tea(result: memoryview, v2: int, v3: int) -> None:
# v4 = bswap32(int.from_bytes(result[v2:v2 + 4], byteorder='little'))
# v5 = bswap32(int.from_bytes(result[v3:v3 + 4], byteorder='little'))
# v6 = -957401312 & 0xFFFFFFFF
# const1 = 1640531527
# v7 = 32
# while v7 > 0:
# v5 = (v5 - (((v4 >> 5) - 1580959241) ^ (16 * v4 + 1901764813) ^ (v4 + v6))) & 0xFFFFFFFF
# v4 = (v4 - ((16 * v5 - 1784187092) ^ (v6 + v5) ^ ((v5 >> 5) - 1658011373))) & 0xFFFFFFFF
# v6 = (v6 + const1) & 0xFFFFFFFF
# v7 -= 1
# result[v2:v2 + 4] = bswap32(v4).to_bytes(4, byteorder='little')
# result[v3:v3 + 4] = bswap32(v5).to_bytes(4, byteorder='little')
def decrypt_full_data(data: bytearray) -> bytearray:
length = len(data)
view = memoryview(data)
for i in range(0, length - 8, 8):
decrypt_tea(view, i, i + 4)
remaining_bytes = data[length - (length % 8):]
if length % 8 != 0:
return data[:length - (length % 8)] + remaining_bytes
else:
decrypt_tea(view, length - 8, length - 4)
return data
for filename in os.listdir(Encrypted_folder):
file_path = os.path.join(Encrypted_folder, filename)
if os.path.isfile(file_path):
with open(file_path, 'rb') as f:
data = bytearray(f.read())
decrypted_data = decrypt_full_data(data)
output_file_path = os.path.join(Output_folder, filename)
with open(output_file_path, 'wb') as f:
f.write(decrypted_data)
1 个赞
Thank you for your reply. However, I’m quite new to game unpacking. Could you please tell me how to use this .py file correctly? It seems that I am missing the decrypt_tea.py file. Sorry for the trouble.