Skip to content

Instantly share code, notes, and snippets.

@lab313ru
Created September 4, 2023 18:56
Show Gist options
  • Select an option

  • Save lab313ru/c1e3afe814e82cb048975d9cf7ae80d1 to your computer and use it in GitHub Desktop.

Select an option

Save lab313ru/c1e3afe814e82cb048975d9cf7ae80d1 to your computer and use it in GitHub Desktop.

Revisions

  1. lab313ru created this gist Sep 4, 2023.
    104 changes: 104 additions & 0 deletions gen_unscramble_key.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,104 @@
    SEEDS = [
    0x576A, 0x05E8, 0x629D, 0x45A3, 0x649C, 0x4BF0, 0x2342, 0x272E,
    0x7358, 0x4FF3, 0x73EC, 0x5F70, 0x7A60, 0x1AD8, 0x3472, 0x3612,
    0x224F, 0x0454, 0x030E, 0x70A5, 0x7809, 0x2521, 0x48F4, 0x5A2D,
    0x492A, 0x043D, 0x7F61, 0x3969, 0x517A, 0x3B42, 0x769D, 0x0647,
    0x7E2A, 0x1383, 0x49D9, 0x07B8, 0x2578, 0x4EEC, 0x4423, 0x352F,
    0x5B22, 0x72B9, 0x367B, 0x24B6, 0x7E8E, 0x2318, 0x6BD0, 0x5519,
    0x1783, 0x18A7, 0x7B6E, 0x7602, 0x4B7F, 0x3648, 0x2C53, 0x6B99,
    0x0C23, 0x67CF, 0x7E0E, 0x4D8C, 0x5079, 0x209D, 0x244A, 0x747B,
    0x350B, 0x0E4D, 0x7004, 0x6AC3, 0x7F3E, 0x21F5, 0x7A15, 0x2379,
    0x1517, 0x1ABA, 0x4E77, 0x15A1, 0x04FA, 0x2D61, 0x253A, 0x1302,
    0x1F63, 0x5AB3, 0x049A, 0x5AE8, 0x1CD7, 0x4A00, 0x30C8, 0x3247,
    0x729C, 0x5034, 0x2B0E, 0x57F2, 0x00E4, 0x575B, 0x6192, 0x38F8,
    0x2F6A, 0x0C14, 0x45FC, 0x41DF, 0x38DA, 0x7AE1, 0x7322, 0x62DF,
    0x5E39, 0x0E64, 0x6D85, 0x5951, 0x5937, 0x6281, 0x33A1, 0x6A32,
    0x3A5A, 0x2BAC, 0x743A, 0x5E74, 0x3B2E, 0x7EC7, 0x4FD2, 0x5D28,
    0x751F, 0x3EF8, 0x39B1, 0x4E49, 0x746B, 0x6EF6, 0x44BE, 0x6DB7
    ]


    def reverse_bit16(n):
    n = ((n >> 1) & 0x5555) | ((n << 1) & 0xaaaa)
    n = ((n >> 2) & 0x3333) | ((n << 2) & 0xcccc)
    n = ((n >> 4) & 0x0f0f) | ((n << 4) & 0xf0f0)
    n = ((n >> 8) & 0x00ff) | ((n << 8) & 0xff00)

    return n


    def prbs15_next_28_bits(seed_rev):
    prbs_result = seed_rev ^ (seed_rev >> 1)
    temp = (prbs_result << 15) | seed_rev
    prbs_result = (temp ^ (temp >> 1)) & 0xFFFFFFF

    next_seed_rev = (prbs_result >> 13) & 0xFFFF

    return prbs_result, next_seed_rev


    def prbs15_next_7_bytes(seed_rev, buf, reverse):
    prbs_bits_0_27, next_seed = prbs15_next_28_bits(seed_rev)
    prbs_bits_28_55, next_seed = prbs15_next_28_bits(next_seed)

    if reverse:
    prbs_bits_0_27 = ~prbs_bits_0_27
    prbs_bits_28_55 = ~prbs_bits_28_55

    buf[0] = 0xFF & prbs_bits_0_27
    buf[1] = 0xFF & (prbs_bits_0_27 >> 8)
    buf[2] = 0xFF & (prbs_bits_0_27 >> 16)
    buf[3] = (prbs_bits_0_27 >> 24) | (0xFF & (prbs_bits_28_55 << 4))
    buf[4] = 0xFF & (prbs_bits_28_55 >> 4)
    buf[5] = 0xFF & (prbs_bits_28_55 >> 12)
    buf[6] = 0xFF & (prbs_bits_28_55 >> 20)

    return next_seed


    def prbs15_gen(seed, buf, reverse):
    seed_rev = reverse_bit16(seed)
    seed_rev >>= 1
    length = len(buf)

    off = 0

    while length > 0:
    if length >= 7:
    tmp = buf[off:off+7]
    seed_rev = prbs15_next_7_bytes(seed_rev, tmp, reverse)
    buf[off:off + 7] = tmp
    off += 7
    length -= 7
    else:
    cur_prbs_buf = bytearray(b'\x00' * 7)
    seed_rev = prbs15_next_7_bytes(seed_rev, cur_prbs_buf, reverse)

    for i in range(length):
    buf[off+i:off+i+1] = struct.pack('B', cur_prbs_buf[i])

    length = 0

    seed = reverse_bit16(seed_rev)
    seed >>= 1

    return seed


    def brute_seed():
    size = 0x20000
    idx = 0

    with open('block_key.bin', 'wb') as w:
    while size > 0:
    tmp = bytearray(0x400)
    prbs15_gen(SEEDS[idx], tmp, False)

    w.write(bytes(tmp))
    w.write(bytes(tmp))
    size -= 0x800
    idx += 1


    if __name__ == '__main__':
    brute_seed()