1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
| import struct import sys
a=[0x99,0xDD,0x56,0xFF,0x6D,0xD9,0x55,0x54,0x42,0x4D,0x79,0x1A,0x34,0xB7,0x81,0x2F] UNK_10170 = b'' for i in a: UNK_10170+=i.to_bytes(1) b=[0x87,0xC1,0x56,0xC0,0x4C,0xF4,0x63,0x4F] UNK_10180 = b'' for i in b: UNK_10180+=i.to_bytes(1) enc=[0xA9,0xB,0x5C,0x1C,0xA3,0x41,0x88,0xCA,0x66,0xD9,0x77,0x1D,0x78,0x3,0x8E,0x7A,0xBA,0x7B,0xD4,0x90,0xCD,0x50,0x7,0x83,0x41,0x4A,0x82,0x9C,0x79,0x1D,0xCC,0x6F,0x9D,0x2F,0x39,0x2D,0xA2,0xDA,0x83,0x1B] TARGET_CIPHERTEXT = b'' for i in enc: TARGET_CIPHERTEXT+=i.to_bytes(1) def rc4_ksa(key): """RC4 Key-Scheduling Algorithm (based on sub_2C740)"""S = list(range(256)) j = 0 key_bytes = key key_len = len(key_bytes)
for i in range(256): j = (j + S[i] + key_bytes[i % key_len]) % 256 S[i], S[j] = S[j], S[i] return S
def rc4_prga_sub_293E0(initial_S, input_data): """RC4 Pseudo-Random Generation Algorithm (based on sub_293E0 loop)"""S = list(initial_S) output_data = bytearray(len(input_data))
v8 = 0 v7 = 0
for k in range(len(input_data)): v8 = (v8 + 1) % 256 v7 = (v7 + S[v8]) % 256 S[v8], S[v7] = S[v7], S[v8]
keystream_index = (S[v7] + S[v8]) % 256 keystream_byte = S[keystream_index] output_data[k] = keystream_byte ^ input_data[k]
return bytes(output_data)
XTEA_DELTA_CONSTANT = 1640531527 # 0x61C88647
def calculate_encryption_v4_sequence(key_bytes): """计算加密轮次中 v4 值的序列。"""v4_sequence = [0] v4_current = 0 k = [ struct.unpack('<I', key_bytes[i*4 : i*4+4])[0] for i in range(4) ]
for round_index in range(32): k2_index = round_index & 3 k2 = k[k2_index] v4_update_term = (round_index ^ k2) - XTEA_DELTA_CONSTANT v4_current = (v4_current + v4_update_term) & 0xFFFFFFFF v4_sequence.append(v4_current)
return v4_sequence
def decrypt_block_round(v6_end, v5_end, v4_start_of_round, v4_end_of_round, round_index, key_bytes): """解密定制 XTEA 变种的一轮。"""v6_end = v6_end & 0xFFFFFFFF v5_end = v5_end & 0xFFFFFFFF v4_start_of_round = v4_start_of_round & 0xFFFFFFFF v4_end_of_round = v4_end_of_round & 0xFFFFFFFF
k = [ struct.unpack('<I', key_bytes[i*4 : i*4+4])[0] for i in range(4) ]
k3_index = (v4_end_of_round >> 11) & 3 k3 = k[k3_index] intermediate_term2 = v6_end + ((v6_end >> 5) ^ (v6_end << 4)) term2 = (k3 + v4_end_of_round) ^ intermediate_term2 v5_start = (v5_end - term2) & 0xFFFFFFFF
k1_index = v4_start_of_round & 3 k1 = k[k1_index] intermediate_term1 = v5_start + ((v5_start >> 5) ^ (v5_start << 4)) term1 = (k1 + v4_start_of_round) ^ intermediate_term1 v6_start = (v6_end - term1) & 0xFFFFFFFF
return (v6_start, v5_start)
def cbc_decrypt(ciphertext, key, iv): """使用定制 XTEA 变种以 CBC 模式解密密文。"""block_size = 8 # 字节 if len(ciphertext) % block_size != 0: print(f"错误:密文长度 ({len(ciphertext)}) 不是分组大小 ({block_size}) 的倍数。无法执行 CBC 解密。") sys.exit(1)
v4_sequence = calculate_encryption_v4_sequence(key)
plaintext_bytes = bytearray() previous_ciphertext_block = iv
for i in range(0, len(ciphertext), block_size): current_ciphertext_block = ciphertext[i : i + block_size]
c0, c1 = struct.unpack('<II', current_ciphertext_block)
decrypted_block_state = (c0, c1)
for reverse_round_index in range(31, -1, -1): v4_start = v4_sequence[reverse_round_index] v4_end = v4_sequence[reverse_round_index + 1]
decrypted_block_state = decrypt_block_round( decrypted_block_state[0], decrypted_block_state[1], v4_start, v4_end, reverse_round_index, key )
p_prime_bytes = struct.pack('<II', decrypted_block_state[0], decrypted_block_state[1])
plaintext_block = bytes([ p_prime_bytes[j] ^ previous_ciphertext_block[j] for j in range(block_size) ])
plaintext_bytes.extend(plaintext_block)
previous_ciphertext_block = current_ciphertext_block
return bytes(plaintext_bytes) if not UNK_10170 or len(UNK_10170) != 16: print("错误:请提供 UNK_10170 的 16 字节数据,需从 SO 文件中提取。") elif not UNK_10180 or len(UNK_10180) != 8: print("错误:请提供 UNK_10180 的 8 字节数据,需从 SO 文件中提取。") elif not TARGET_CIPHERTEXT or len(TARGET_CIPHERTEXT) != 40: # <-- 检查长度为 40 字节 print(f"错误:请提供 TARGET_CIPHERTEXT 的 **完整的 40 字节** 数据,需从 SO 文件中提取。") print(f"(当前提供的长度为 {len(TARGET_CIPHERTEXT)})") else: print("占位符数据似乎已提供。尝试解密...")
rc4_key_material = b"DoNotHackMe" S_box_for_73040 = rc4_ksa(rc4_key_material) KEY_QWORD_73040 = rc4_prga_sub_293E0(list(S_box_for_73040), UNK_10170)
S_box_for_73050 = rc4_ksa(rc4_key_material) KEY_QWORD_73050 = rc4_prga_sub_293E0(list(S_box_for_73050), UNK_10180)
print(f"派生出的加密密钥 (qword_73040): {KEY_QWORD_73040.hex()}") print(f"派生出的 IV (qword_73050): {KEY_QWORD_73050.hex()}") print(f"目标密文 (40字节): {TARGET_CIPHERTEXT.hex()}")
decrypted_padded_plaintext = cbc_decrypt(TARGET_CIPHERTEXT, KEY_QWORD_73040, KEY_QWORD_73050)
plaintext = decrypted_padded_plaintext.rstrip(b'\x00')
print(f"\n解密后的填充明文 (40 字节): {decrypted_padded_plaintext.hex()}") # <-- 输出提示长度为 40
try: flag = plaintext.decode('utf-8') print(f"恢复的 Flag (解码为 UTF-8): {flag}") except UnicodeDecodeError: print(f"无法将恢复的明文解码为 UTF-8。") print(f"恢复的明文字节 (十六进制): {plaintext.hex()}") except Exception as e: print(f"在最终处理过程中发生未知错误: {e}")
# palu{thiS_T1Me_it_seeM5_tO_8e_ReAl_te@}
|