Files
2020-02-17 14:05:02 +01:00

88 lines
2.9 KiB
Python

import json
import time
##### TO PATCH #####
JSON_FILE = "/home/user/etudes/lab-windows/secure_kernel/info.json" # From extract_ida.py
SECUREKERNEL_PATH = "/home/user/etudes/lab-windows/secure_kernel/securekernel.exe"
####################
FUNCTIONS = json.load(open(JSON_FILE, "rb"))
# Shared variables
base_va = None
sk_cr3 = None
# Utils
def turn_phys_mode_on():
gdb.execute("maint packet Qqemu.PhyMemMode:1", to_string=True)
def turn_phys_mode_off():
gdb.execute("maint packet Qqemu.PhyMemMode:0", to_string=True)
def check_addrspace():
cur_cr3 = int(gdb.parse_and_eval("$cr3")) & 0xFFFFFFFFFFFFFFFF
if cur_cr3 != sk_cr3:
print("Please launch this command in the context of the secure kernel")
print("hint: hbreak *(0x%x)" % (base_va + FUNCTIONS["IumInvokeSecureService"]["va"]))
return False
return True
# Commands
class FindPatchIumEP(gdb.Command):
"""Find and patch a Ium secure call entry point in physical memory"""
RAM_MAX_ADDR = 0xffffffff
CHUNK = 0x10000
def __init__ (self):
super(FindPatchIumEP, self).__init__("find_patch_ium_ep", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
offset = FUNCTIONS["IumInvokeSecureService"]["offset"]
to_find = open(SECUREKERNEL_PATH, "rb").read()[offset: offset + 200]
print("Look for 'IumInvokeSecureService' in physical memory...")
turn_phys_mode_on()
inf = gdb.inferiors()[0]
offset = None
for i in range(0, self.RAM_MAX_ADDR, self.CHUNK):
if (i % 0x1000000 == 0):
print(hex(i))
data = inf.read_memory(i, self.CHUNK).tobytes()
try:
offset_invokesk = data.index(to_find) + i
print("Found at 0x%x!" % offset_invokesk)
break
except ValueError:
continue
print("Replace with infinite loop...")
inf.write_memory(offset_invokesk, b"\xeb\xfe")
turn_phys_mode_off()
class FixIumEP(gdb.Command):
"""Fix the Ium entry-point data, and note the current virtual address"""
def __init__ (self):
super(FixIumEP, self).__init__("fix_ium_ep", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
global base_va, sk_cr3
rip = int(gdb.parse_and_eval("$rip")) & 0xFFFFFFFFFFFFFFFF
inf = gdb.inferiors()[0]
if inf.read_memory(rip, 2).tobytes() != b"\xeb\xfe":
print("Please call this function once IumInvokeSecureService loophole has been reached")
return
offset = FUNCTIONS["IumInvokeSecureService"]["offset"]
orig = open(SECUREKERNEL_PATH, "rb").read()[offset: offset + 2]
inf.write_memory(rip, orig)
base_va = rip - FUNCTIONS["IumInvokeSecureService"]["va"]
sk_cr3 = int(gdb.parse_and_eval("$cr3")) & 0xFFFFFFFFFFFFFFFF
print("Base VA: 0x%x" % base_va)
# Register commands
FindPatchIumEP()
FixIumEP()