Last active
October 6, 2024 10:11
-
-
Save ubuntor/94b41aa37dd04d0888c4c531e9740355 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import struct | |
import binascii | |
from collections import Counter | |
def u16(b): | |
return struct.unpack('<H', b)[0] | |
def p16(x): | |
return struct.pack('<H', x) | |
def p32(x): | |
return struct.pack('<I', x) | |
def xor_block(block, key): | |
return b''.join(p16(u16(block[i:i+2])^key) for i in range(0,len(block),2)) | |
def majority(block): | |
c = Counter() | |
for i in range(0, len(block), 2): | |
c[u16(block[i:i+2])] += 1 | |
return c.most_common(1)[0][0] | |
def decrypt(s): | |
decrypted = b'' | |
s = s[0x200:] # don't know what the first block is, but it doesn't matter | |
# base = majority(s[:0x200]) ^ 0xFFFF # heuristic | |
base = u16(s[:2]) ^ u16(b'\xFF\xFB') # better heuristic, thanks to foone! | |
for i in range(0, len(s), 0x200): | |
block = s[i:i+0x200] | |
key = binascii.crc_hqx(p32(i//0x200), 0) ^ base | |
decrypted += xor_block(block, key) | |
return decrypted | |
def main(): | |
if len(sys.argv) < 3: | |
print("usage: {} INFILE OUTFILE".format(sys.argv[0])) | |
return | |
with open(sys.argv[1], "rb") as f: | |
encrypted = f.read() | |
decrypted = decrypt(encrypted) | |
with open(sys.argv[2], "wb") as f: | |
f.write(decrypted) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
🧊