-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathfind_patch_phys.py
More file actions
87 lines (69 loc) · 2.89 KB
/
find_patch_phys.py
File metadata and controls
87 lines (69 loc) · 2.89 KB
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
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()