Skip to content

Instantly share code, notes, and snippets.

@0xD34D
Created March 5, 2024 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xD34D/09c46d45a8e7cfe8a08ce1c0fee599d6 to your computer and use it in GitHub Desktop.
Save 0xD34D/09c46d45a8e7cfe8a08ce1c0fee599d6 to your computer and use it in GitHub Desktop.
Ugly python code to decrpyt header2 from tjc.tft files
import argparse
from pathlib import Path
import struct
NONCE = struct.pack("III", 0x92930f5e, 0x924f6584, 0xfbad3bbf)
KEY = struct.pack("II", 0x582659b6, 0xbd829c9c)
if __name__ == "__main__":
desc = """TFT header2 decoder
Developped by Clark Scheff, licensed under GPLv3"""
parser = argparse.ArgumentParser(description=desc)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-i", "--input", metavar="TFT_FILE", type=str,
help="Path to the TFT file")
args = parser.parse_args()
tftPath = Path(args.input)
if not tftPath.exists():
parser.error("Invalid source file!")
header2 = None
with open(tftPath, 'rb') as f:
f.seek(200)
header2 = f.read(200)
if header2 is not None:
header_size = len(header2)
word_idx = 0
nonce_bytes = bytearray(NONCE)
while word_idx < header_size:
header_word = struct.unpack("I", header2[word_idx:word_idx+4])[0]
rk_idx = int(word_idx / 4) % len(KEY)
key_byte = KEY[rk_idx]
start_nonce1, start_nonce2, start_nonce3 = struct.unpack("III", nonce_bytes)
nonce1 = (start_nonce1 << 1) & 0xffffffff
nonce_bytes[0:4] = struct.pack("I", nonce1)
nonce_byte = nonce_bytes[header_size & 0x03]
nonce_bytes[header_size & 0x03] = ((key_byte ^ 0xbc) + nonce_byte) & 0xff
nonce1 = struct.unpack("III", nonce_bytes)[0]
nonce2 = (start_nonce2 << 2) & 0xffffffff
nonce_bytes[4:8] = struct.pack("I", nonce2)
b_idx = 3 - (key_byte & 0x03)
nonce_byte = nonce_bytes[4 + b_idx]
nonce_bytes[4 + b_idx] = ((key_byte ^ 0x58) + nonce_byte) & 0xff
nonce2 = struct.unpack("III", nonce_bytes)[1]
new_nonce = ~(((nonce1 + nonce2) ^ start_nonce3) + word_idx + 8) & 0xffffffff
new_nonce2 = (new_nonce + start_nonce3) & 0xffffffff
new_header_word = (header_word - new_nonce2) & 0xffffffff
new_header_word = (new_header_word ^ new_nonce) & 0xffffffff
nonce3 = (start_nonce3 << 3) & 0xffffffff
nonce_bytes[8:12] = struct.pack("I", nonce3)
b_idx = 3 - (key_byte & 0x03)
nonce_byte = nonce_bytes[8 + b_idx]
nonce_bytes[8 + b_idx] = ((key_byte ^ 0x7a) + nonce_byte) & 0xff
nonce3 = struct.unpack("III", nonce_bytes)[2]
result1 = (start_nonce2 + start_nonce3 + nonce1) & 0xffffffff
result = (result1 + start_nonce2) & 0xffffffff
new_header_word = ((new_header_word - result) ^ result1) & 0xffffffff
result1 = (start_nonce1 + start_nonce2) & 0xffffffff
b = (key_byte & 0x07)
result1 = ((start_nonce3 << b) + result1) & 0xffffffff
result = (result1 + start_nonce1) & 0xffffffff
new_header_word = ((new_header_word - result) ^ result1) & 0xffffffff
print(f'0x{word_idx+0xc8:03x}: 0x{header_word:08x} --> 0x{new_header_word:08x}')
word_idx += 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment