mirror of https://github.com/UMSKT/peacestone.git
mac key derivation
This commit is contained in:
parent
6604a71d07
commit
16a9a1054c
|
@ -36,6 +36,7 @@ image_start = ql.loader.images[0].base
|
|||
image_end = ql.loader.images[0].end
|
||||
image_size = image_end - image_start
|
||||
pe = pefile.PE(data=ql.mem.read(image_start, image_size))
|
||||
scratch_base = ql.mem.map_anywhere(0x1000)
|
||||
|
||||
def mem_read_int(addr):
|
||||
return ql.unpack(ql.mem.read(addr, 4))
|
||||
|
@ -52,7 +53,7 @@ def array_write_int(array, offset, val):
|
|||
|
||||
return arr_copy
|
||||
|
||||
stub_frame = 0x010BE265
|
||||
stub_frame = 0x120f989
|
||||
|
||||
num_obd = mem_read_int(sym_data_inv["?g_nNumObfuscatedBlockData@WARBIRD@@3KA"])
|
||||
obd_addr = sym_data_inv["?g_ObfuscatedBlockData@WARBIRD@@3PAU_OBFUSCATED_BLOCK_DATA@1@A"]
|
||||
|
@ -108,16 +109,43 @@ val1 = (obd[index][1] + obd[index][0]) % (1 << 32)
|
|||
val2 = (obd[index][2] - obd[index][0]) % (1 << 32)
|
||||
val3 = (obd[index][4] + obd[index][3]) % (1 << 32)
|
||||
unk3 = obd[index][3]
|
||||
|
||||
print(f"VAL1 {hex(val1)} VAL2 {hex(val2)} VAL3 {hex(val3)} UNK3 {hex(unk3)}")
|
||||
|
||||
data_size = unk3 & 0xfff
|
||||
xor_plus_binstart = image_start + xor_value
|
||||
val1_bytes = val1.to_bytes(4, "little")
|
||||
val2_bytes = val2.to_bytes(4, "little")
|
||||
enc_bytes = ql.mem.read(xor_plus_binstart, data_size + 1)
|
||||
dec_bytes = [0] * data_size
|
||||
chksum = 0xa5
|
||||
|
||||
if val2 & 0x1000000 == 0:
|
||||
raise Exception("USES MAC-DERIVED KEY")
|
||||
print("DERIVING KEY FROM MAC")
|
||||
mac_func = mem_read_int(sym_data_inv["?g_apMacFuncs@WARBIRD@@3PAP6AXAA_JPBE1ABU_CBCKey2@1@@ZA"] + (val2 >> 25) * 4)
|
||||
|
||||
for instr in md.disasm(ql.mem.read(mac_func, 0x100), mac_func):
|
||||
if instr.mnemonic == "ret":
|
||||
mac_end = instr.address
|
||||
break
|
||||
|
||||
ql.mem.write(scratch_base, b"\x00\x01\x02\x03\x04\x05")
|
||||
ql.mem.write(scratch_base + 0x10, ql.pack(xor_value))
|
||||
ql.mem.write(scratch_base + 0x14, ql.pack(0))
|
||||
ql.arch.stack_push(scratch_base)
|
||||
ql.arch.stack_push(val1 + image_start + (val2 & 0xffff))
|
||||
ql.arch.stack_push(val1 + image_start)
|
||||
ql.arch.stack_push(0x10)
|
||||
ql.arch.stack_push(0x69696969)
|
||||
|
||||
old_sp = ql.arch.regs.esp
|
||||
ql.run(begin=mac_func, end=mac_end)
|
||||
ql.arch.regs.esp = old_sp
|
||||
|
||||
key1 = ql.mem.read(0x10, 4)
|
||||
key2 = ql.mem.read(0x14, 2)
|
||||
else:
|
||||
print("USING BLOCK VALUES AS KEY")
|
||||
key1 = val1.to_bytes(4, "little")
|
||||
key2 = (val2 & 0xFFFF).to_bytes(2, "little")
|
||||
|
||||
for i in range(data_size - 1, -1, -1):
|
||||
enc_byte = enc_bytes[i]
|
||||
|
@ -128,30 +156,30 @@ for i in range(data_size - 1, -1, -1):
|
|||
b = 0
|
||||
|
||||
if i % 2 == 1:
|
||||
if (enc_byte ^ val1_bytes[3]) % 2 == 1:
|
||||
a = (enc_byte ^ val1_bytes[3] ^ val1_bytes[2] ^ 0x100) >> 1
|
||||
if (enc_byte ^ key1[3]) % 2 == 1:
|
||||
a = (enc_byte ^ key1[3] ^ key1[2] ^ 0x100) >> 1
|
||||
else:
|
||||
a = (enc_byte ^ val1_bytes[3]) >> 1
|
||||
a = (enc_byte ^ key1[3]) >> 1
|
||||
|
||||
if (a ^ b) % 2 == 1:
|
||||
dec_byte = (a ^ b ^ val2_bytes[1] ^ 0x100) >> 1
|
||||
dec_byte = (a ^ b ^ key2[1] ^ 0x100) >> 1
|
||||
else:
|
||||
dec_byte = (a ^ b) >> 1
|
||||
else:
|
||||
if (enc_byte ^ val1_bytes[1]) % 2 == 1:
|
||||
a = (enc_byte ^ val1_bytes[1] ^ val1_bytes[0] ^ 0x100) >> 1
|
||||
if (enc_byte ^ key1[1]) % 2 == 1:
|
||||
a = (enc_byte ^ key1[1] ^ key1[0] ^ 0x100) >> 1
|
||||
else:
|
||||
a = (enc_byte ^ val1_bytes[1]) >> 1
|
||||
a = (enc_byte ^ key1[1]) >> 1
|
||||
|
||||
if (a ^ b) % 2 == 1:
|
||||
dec_byte = (a ^ b ^ val2_bytes[0] ^ 0x100) >> 1
|
||||
dec_byte = (a ^ b ^ key2[0] ^ 0x100) >> 1
|
||||
else:
|
||||
dec_byte = (a ^ b) >> 1
|
||||
|
||||
chksum ^= dec_byte
|
||||
dec_bytes[i] = dec_byte
|
||||
|
||||
if chksum != val2_bytes[2]:
|
||||
if chksum != (val2 >> 16) & 0xFF:
|
||||
raise Exception("CHECKSUM FAILED!")
|
||||
|
||||
print(dec_bytes)
|
||||
|
@ -187,11 +215,9 @@ while index < num_relocs:
|
|||
offset = -xor_plus_binstart % (1 << 32)
|
||||
elif ofmode == 2:
|
||||
offset = xor_plus_binstart
|
||||
elif ofmode == 3:
|
||||
offset = 0
|
||||
|
||||
if ((private_relocs[index] >> 30) & 3) == 2:
|
||||
print(hex(addr - xor_value), hex(offset))
|
||||
if ((private_relocs[index] >> 30) & 3) == 2 and offset != 0:
|
||||
print(f"RELOC @ OFFSET {hex(addr - xor_value)} +{hex(offset)}")
|
||||
val = array_read_int(dec_bytes, addr - xor_value)
|
||||
val = (val + offset) % (1 << 32)
|
||||
dec_bytes = array_write_int(dec_bytes, addr - xor_value, val)
|
||||
|
|
|
@ -41,7 +41,7 @@ ks = Ks(KS_ARCH_X86, KS_MODE_32)
|
|||
md = Cs(CS_ARCH_X86, CS_MODE_32)
|
||||
md.detail = True
|
||||
md.skipdata = True
|
||||
ql = Qiling(["./rootfs/sppsvc.exe"], "./rootfs")
|
||||
ql = Qiling(["./rootfs/sppsvc.exe"], "./rootfs", verbose=QL_VERBOSE.OFF)
|
||||
image_start = ql.loader.images[0].base
|
||||
image_end = ql.loader.images[0].end
|
||||
image_size = image_end - image_start
|
||||
|
@ -79,15 +79,17 @@ if __name__ == "__main__":
|
|||
f = open("log.txt", "w")
|
||||
|
||||
for match in re.finditer(STUB_RET4_REGEX, pe_data):
|
||||
print(hex(match.start()))
|
||||
|
||||
match_addr = image_start + match.start()
|
||||
stub_code = ql.mem.read(match_addr - 0x1000, 0x1000)
|
||||
stub_code = ql.mem.read(match_addr - 0x50, 0x50)
|
||||
|
||||
try:
|
||||
stub_start_offset = list(re.finditer(PUSH_REGEX, stub_code))[0].start()
|
||||
except:
|
||||
continue
|
||||
|
||||
stub_start_addr = match_addr - 0x1000 + stub_start_offset
|
||||
stub_start_addr = match_addr - 0x50 + stub_start_offset
|
||||
instrs = list(md.disasm(ql.mem.read(stub_start_addr, 0x47), stub_start_addr))
|
||||
ret = 0
|
||||
|
||||
|
@ -170,7 +172,13 @@ if __name__ == "__main__":
|
|||
else:
|
||||
handler_name = hex(handler_addr)
|
||||
|
||||
f.write(f"J R4 S {hex(jmp_insert_addr)} H {handler_name} N {hex(next_addr)}\n")
|
||||
if next_addr in sym_data:
|
||||
next_name = f"{hex(next_addr)} {sym_data[next_addr]}"
|
||||
else:
|
||||
next_name = hex(next_addr)
|
||||
|
||||
f.write(f"J R4 S {hex(jmp_insert_addr)} H {handler_name} N {next_name}\n")
|
||||
|
||||
# input()
|
||||
print()
|
||||
print()
|
||||
# input()
|
Loading…
Reference in New Issue