Add descriptions to commit and cleanup

This commit is contained in:
Jonathan Herrewijnen 2024-09-04 14:16:26 +02:00
parent 906629b80f
commit 66621d36d7

View File

@ -628,23 +628,29 @@ class ExynosDevice():
"""
Boot into USB recovery mode using the debugger.
"""
# Setup initial debugger
self.setup_guppy_debugger()
self.cd.arch_dbg.state.auto_sync = False
self.cd.arch_dbg.state.auto_sync_special = False
logger.debug('State after setting up initial debugger')
self.cd.arch_dbg.state.print_ctx()
DEBUGGER_ADDR = 0x2069000 # 0x2069000
# Relocate to other debugger
# # Relocate to other debugger to 02048000 (after BL31, space in 0x020c0000 is no longer reachable -> dying debugger)
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
### Overwrite boot_usb_ra to our debugger
# # # Relocate to other debugger to 020c0000
# debugger = open("../../dump/reloc_debugger.bin", "rb").read()
# self.relocate_debugger(debugger)
# DEBUGGER_ADDR = 0x020c0000
# Test debugger connection
self.cd.test_connection()
# ==== BL1 ====
### Overwrite boot_usb_ra to our debugger
hijacked_usb_ra = self.cd.memdump_region(0x02020f60, 8)
self.cd.memwrite_region(0x02020f60, p64(DEBUGGER_ADDR))
@ -652,11 +658,13 @@ class ExynosDevice():
BOOT_USB_FUNCTION = 0x000064e0
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
self.cd.restore_stack_and_jump(BOOT_USB_FUNCTION)
# Wait for device return (happens after each download)
time.sleep(1)
self.connect_device()
# Setup jump and authentication
AUTH_BL1 = 0x00012848
# Setup jump and bl_auth
AUTH_BL1 = 0x00012848 # Location of the authentication function
def auth_bl1(lr=0x2069000):
# Load the firmware
self.cd.arch_dbg.state.X0 = 1
@ -666,7 +674,8 @@ class ExynosDevice():
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
### Check if authentication was successful - X0 should not be 0??
# assert self.cd.arch_dbg.state.X0 == 0, "auth_bl1 returned with error!"
# Jump into BL1 (sboot.bin.1.bin)
JUMP_BL1 = 0x000002c0
def jump_bl1(lr):
self.cd.arch_dbg.state.LR = lr
@ -676,89 +685,86 @@ class ExynosDevice():
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read())
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
# BL1 is loaded, now authenticat and patch it
# BL1 is loaded, now authenticate and patch it
auth_bl1(DEBUGGER_ADDR)
self.usb_write(b"FLSH") # Flush cache
self.usb_write(b"FLSH") # Flush cache (Frederic does this..)
# Hijack ROM download function
hijacked_fun = u32(self.cd.memdump_region(0x020200dc, 4))
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"))
# And jump into BL1 to execute it
jump_bl1(DEBUGGER_ADDR)
# ==== BL31 ====
# Assure that the debugger is still alive
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
self.get_ttbr0_el3()
# Functions to check ttbr0 (should be trash until after executing BL31)
# self.get_ttbr0_el3() # Should be trash, as the
# self.check_mem_write_execute(0x020c0000)
# Download next stage via ROM_DOWNLOAD_USB
# Get current LR, and store it. Then set LR to debugger.
lr = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
self.cd.restore_stack_and_jump(hijacked_fun) # will jump back to debugger after downloading the next stage
self.cd.restore_stack_and_jump(hijacked_fun) # will jump back to debugger after downloading the next stage (before executing it)
# After downloading the next stage, make sure the device reconnects
time.sleep(2)
self.connect_device()
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read())
time.sleep(2)
# Assure that the debugger is returning (obligatory assuration)
self.usb_read(0x200) # GiAs
# lr = self.cd.arch_dbg.state.LR
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # Resore oginal boot flow
self.get_ttbr0_el3()
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # to resotre oginal boot flow, without getting back to the debugger
# Set LR to continue boot flow
self.cd.restore_stack_and_jump(lr)
# Assure return to debugger
time.sleep(2)
self.usb_read(0x200) # GiAs
self.cd.memwrite_region(0x02031008, b"ELH")
# trampoline = self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br") # Keep LR
# self.cd.memwrite_region(0x02024020, trampoline)
# ====== PATCHES TO BL31 here! ======
# Relocate to other debugger
# Relocate to other debugger (For after BL31, but we need a good space!)
# debugger = open("../../dump/reloc_debugger_0x2019e5c.bin", "rb").read()
# self.relocate_debugger(debugger=debugger, entry=0x14AC0000, storage=0x14AC3000, g_data_received=0x14AC4000)
# DEBUGGER_ADDR = 0x14AC0000
# Jump BL31
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
# self.cd.memwrite_region(0x20219b8, p32(DEBUGGER_ADDR))
# self.cd.restore_stack_and_jump(hijacked_fun)
# Write 0's to 0x11600
# Inspect TTBR0_EL3 table
TTBR0_EL3 = 0x02035600 # Zeroed
# Overwrite 02028b0c from 5f5820f8 to d503201f -> Doesn't seem to be doing anything
# self.cd.memwrite_region(0x02028b0c, struct.pack('>I', 0xd503201f))
# Same at 02028b8c
# self.cd.memwrite_region(0x02028b8c, struct.pack('>I', 0xd503201f))
TTBR0_EL3 = 0x02035600 # Zeroed out
# Modifies setting up MMU (but is set up eventually)
# 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(0x020244fc, b'\00'*8) # Change check to always false
# Write jump backs from BL31 at different levels
# self.cd.memwrite_region(0x02030a28, p64(DEBUGGER_ADDR))
# Overwrite jump back at 0202f810
# self.cd.memwrite_region(0x0202f818, struct.pack('>I', 0xfa610091))
# Jump into BL31 and execute it
self.cd.restore_stack_and_jump(0x02024010)
# Obligatory reconnect and check of debugger
time.sleep(2)
self.connect_device()
self.usb_read(0x200) # GiAs
regs = self.cd.arch_dbg.fetch_special_regs()
# print status of MMU
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (1=enabled, 0=disabled)')
# self.cd.arch_dbg.fetch_special_regs() # -> Does not work with original debugger (??). Only with relocated debugger.
VBAR_EL3 = self.cd.arch_dbg.state.VBAR_EL3
# Print status of MMU
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
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)
@ -770,17 +776,17 @@ class ExynosDevice():
time.sleep(2)
self.connect_device()
# ==== Stage 4 ====
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
# Patching
# stage4_len = len(stage4)
# patch_len = len(b"USB RECOVERY MODE")
# patch = b"ELHER HERE" + (b"\x00" * (patch_len - len(b"ELHER HERE")))
# patch_offset = stage4.find(b"USB RECOVERY MODE")
# stage4 = stage4[:patch_offset] + patch + stage4[patch_len + patch_offset:]
# assert len(stage4) == stage4_len, "Invalid stage4 length"
self.send_normal_stage(stage4)
time.sleep(2)