Skip to content

Instantly share code, notes, and snippets.

@dot-mike
Created February 20, 2025 21:49
Show Gist options
  • Save dot-mike/354b802493a8565ab3ca4c0a9b05c406 to your computer and use it in GitHub Desktop.
Save dot-mike/354b802493a8565ab3ca4c0a9b05c406 to your computer and use it in GitHub Desktop.
decrypts SWZ files
import struct
import zlib
import argparse
import sys
def rotate_left(value, shift, bit_size=32):
"""Rotate left a 32-bit integer."""
return ((value << shift) & (2**bit_size - 1)) | (value >> (bit_size - shift))
def decrypt_and_decompress(file_path):
"""Decrypts and decompresses binary data from a given file."""
try:
with open(file_path, "rb") as f:
data = f.read()
except FileNotFoundError:
print(f"Error: File '{file_path}' not found.")
sys.exit(1)
offset = 0
# Read the encryption key
if len(data) < 8:
print("Error: File is too small to contain required header data.")
sys.exit(1)
decryption_key, = struct.unpack(">I", data[offset:offset+4]) # Read 4 bytes as uint32
offset += 4
# Read number of XML blocks
num_blocks, = struct.unpack(">I", data[offset:offset+4]) # Read another 4 bytes
offset += 4
xml_list = []
for _ in range(num_blocks):
if offset + 4 > len(data):
print("Error: Unexpected end of file while reading chunk size.")
break
# Read chunk size
chunk_size, = struct.unpack(">I", data[offset:offset+4])
offset += 4
if offset + chunk_size > len(data):
print("Error: Unexpected end of file while reading chunk data.")
break
encrypted_chunk = bytearray(data[offset:offset+chunk_size])
offset += chunk_size
# Decrypt the chunk
for i in range(chunk_size):
shift_amount = i & 7
encrypted_chunk[i] ^= (decryption_key & 0xFF)
decryption_key = rotate_left(decryption_key, 32 - shift_amount)
# Decompress the chunk
try:
decompressed_data = zlib.decompress(encrypted_chunk)
except zlib.error:
print("Decompression failed! The data might be corrupt or incorrectly decrypted.")
continue
# Convert bytes to string (XML)
xml_string = decompressed_data.decode("utf-8")
xml_list.append(xml_string)
return xml_list
def main():
parser = argparse.ArgumentParser(description="Decrypt and decompress an AS3 encrypted binary file containing XML data.")
parser.add_argument("input_file", help="Path to the encrypted binary file.")
args = parser.parse_args()
xml_contents = decrypt_and_decompress(args.input_file)
for idx, xml in enumerate(xml_contents):
print(f"Extracted XML {idx + 1}:\n{xml}\n")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment