mirror of
https://github.com/commial/experiments
synced 2026-06-16 13:58:02 +00:00
88 lines
2.9 KiB
Python
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()
|