Skip to content

Instantly share code, notes, and snippets.

@ubuntor
Last active October 6, 2024 10:11
Show Gist options
  • Save ubuntor/94b41aa37dd04d0888c4c531e9740355 to your computer and use it in GitHub Desktop.
Save ubuntor/94b41aa37dd04d0888c4c531e9740355 to your computer and use it in GitHub Desktop.
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()
@qm3ster
Copy link

qm3ster commented Nov 2, 2020

🧊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment