''' STM32 Soldering Station Firmware Registration Handler. Loosely based on code by Dmitry Artamonov . REF: https://web.archive.org/web/20220328075324/http://t12.omegahg.com/keygen.py This program is free software. It comes without any warranty, to the extent permitted by applicable law. You can redistribute it and/or modify it under the terms of the WTFPL, Version 2, as published by Sam Hocevar. See http://www.wtfpl.net/ for more details T12/Desolderer sample data: ID1 = 0xDC90 # RG1: 4D6E ID2 = 0x5A92 # RG2: A789 ID1 = 0xB0B3 # RG1: C650 ID2 = 0x0FAD # RG2: 401A ID1 = 0x3251 # RG1: 8BE3 ID2 = 0x1351 # RG2: 29E1 ID1 = 0xB57E # RG1: 9FDB ID2 = 0x43AB # RG2: 19D6 ID1 = 0xC9E9 # RG1: B04F ID2 = 0x0D09 # RG2: 503A ID1 = 0x8CB7 # RG1: 92F0 ID2 = 0x1B90 # RG2: 0114 Combo sample data: ID1 = 0x45D1 # RG1: E68F ID2 = 0x6C6D # RG2: FECC SMD Rework Station sample data: ID1 = 0xE784 # RG1: B968 ID2 = 0xE7F4 # RG2: 4AAC ID1 = 0x0130 # RG1: 5A09 ID2 = 0x2028 # RG2: 9AFC ID1 = 0xD06F # RG1: C8A1 ID2 = 0xDCF4 # RG2: 1754 ''' import binascii import struct import argparse import functools class CRC16: CCIT_POLY = 0x8408 def __init__(self, Extra=0): self.Extra = Extra def ReverseInt16(self, i): i = (i & 0x5555) << 1 | (i >> 1) & 0x5555 i = (i & 0x3333) << 2 | (i >> 2) & 0x3333 i = (i & 0x0F0F) << 4 | (i >> 4) & 0x0F0F i = (i & 0x00FF) << 8 | (i >> 8) return i def GenTable(self, poly): self.Table = [0] * 256 poly = self.ReverseInt16(poly) for x in range(0, 256): w = x << 8 for _ in range(0, 8): w = (w << 1) ^ poly if w & 0x8000 else w << 1 self.Table[x] = w & 0xFFFF def Calculate(self, Data, InitialCrcValue=0): crc = InitialCrcValue for c in Data: crc = ((crc << 8) & 0xFF00) ^ (self.Table[((crc + self.Extra) >> 8) ^ (c & 0xFF)] & 0xFFFF) return crc def Permutate(self, CrcPermutation): Result = [] for i in range(0, 32): Idx = CrcPermutation[i] << 3 Result += self.Table[Idx : Idx + 8] self.Table = Result ProductKeys = { "t12": { "ivec": b"\xB5\x06\x46\x42\xF2\xD3\x60\x81\xEA\x00\x04\x43\xF2\xF2\x60\x44\x40\x0D\x46\x40\xF2\x91\x60\x44\x40\x44\xF6\x82", "xor": 0x9ACF ^ 0x20, "permutation": [ 1, 2, 3, 4, 31, 5, 6, 7, 8, 9, 10, 11, 12, 0, 13, 25, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, ], # These are part of Chinese 1bpp glyphs, but it does not matter for the registration purpose. "prefix_id1": b"\x00\x04\x04\x44\xc4\x4f\x44\x44\xc4\x24\x24\x2f\xb4\x24\x04\x04\x00\x40\x44\x24\x24\x15\x0c\x04\xfe\x04\x0c\x15", "prefix_id2": b"\x00\x10\x60\x02\x8c\x00\x00\xfe\x92\x92\x92\x92\x92\xfe\x00\x00\x00\x04\x04\x7e\x01\x40\x7e\x42\x42\x7e\x42\x7e", }, "combo": { "ivec": b"\xB5\x06\x46\x41\xF2\x91\x60\x81\xEA\x00\x02\x46\xF6\x17\x60\x42\x40\x41\xF2\x11\x60\x42", "xor": 0x2A92 ^ 0x20, "permutation": [ 1, 2, 3, 4, 31, 5, 6, 7, 20, 8, 9, 10, 11, 12, 0, 13, 24, 25, 14, 15, 16, 17, 18, 19, 21, 22, 23, 26, 27, 28, 29, 30, ], "prefix_id1": b"\x04\x04\x44\xc4\x4f\x44\x44\xc4\x24\x24\x2f\xb4\x24\x04\x04\x00\x40\x44\x24\x24\x15\x0c\x04\xfe\x04\x0c\x15\x24", "prefix_id2": b"\x10\x60\x02\x8c\x00\x00\xfe\x92\x92\x92\x92\x92\xfe\x00\x00\x00\x04\x04\x7e\x01\x40\x7e\x42\x42\x7e\x42\x7e\x42", }, "rework": { "prefix_id1": b"\x00\x00\xF8\x49\x4A\x4C\x48\xF8\x48\x4C\x4A\x49\xF8\x00\x00\x00\x10\x10\x13\x12\x12\x12\x12\xFF\x12\x12\x12\x12", "prefix_id2": b"\x10\x13\x12\x12\x12\x12\xFF\x12\x12\x12\x12\x13\x10\x10\x00\x10\x60\x02\x8C\x00\x00\xFE\x92\x92\x92\x92\x92\xFE", "crc_extra": 0xB, }, } def CalcRegCode(product, id1, id2): print(f'ID1: {id1:04X}') print(f'ID2: {id2:04X}') ID = struct.pack('