Add descriptions to commit and cleanup
This commit is contained in:
parent
906629b80f
commit
66621d36d7
@ -628,23 +628,29 @@ class ExynosDevice():
|
|||||||
"""
|
"""
|
||||||
Boot into USB recovery mode using the debugger.
|
Boot into USB recovery mode using the debugger.
|
||||||
"""
|
"""
|
||||||
|
# Setup initial debugger
|
||||||
self.setup_guppy_debugger()
|
self.setup_guppy_debugger()
|
||||||
|
|
||||||
self.cd.arch_dbg.state.auto_sync = False
|
self.cd.arch_dbg.state.auto_sync = False
|
||||||
self.cd.arch_dbg.state.auto_sync_special = False
|
self.cd.arch_dbg.state.auto_sync_special = False
|
||||||
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()
|
||||||
|
|
||||||
DEBUGGER_ADDR = 0x2069000 # 0x2069000
|
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()
|
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
|
||||||
|
|
||||||
### 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()
|
self.cd.test_connection()
|
||||||
|
|
||||||
|
# ==== BL1 ====
|
||||||
|
### Overwrite boot_usb_ra to our debugger
|
||||||
hijacked_usb_ra = self.cd.memdump_region(0x02020f60, 8)
|
hijacked_usb_ra = self.cd.memdump_region(0x02020f60, 8)
|
||||||
self.cd.memwrite_region(0x02020f60, p64(DEBUGGER_ADDR))
|
self.cd.memwrite_region(0x02020f60, p64(DEBUGGER_ADDR))
|
||||||
|
|
||||||
@ -652,11 +658,13 @@ class ExynosDevice():
|
|||||||
BOOT_USB_FUNCTION = 0x000064e0
|
BOOT_USB_FUNCTION = 0x000064e0
|
||||||
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
||||||
self.cd.restore_stack_and_jump(BOOT_USB_FUNCTION)
|
self.cd.restore_stack_and_jump(BOOT_USB_FUNCTION)
|
||||||
|
|
||||||
|
# Wait for device return (happens after each download)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
|
|
||||||
# Setup jump and authentication
|
# Setup jump and bl_auth
|
||||||
AUTH_BL1 = 0x00012848
|
AUTH_BL1 = 0x00012848 # Location of the authentication function
|
||||||
def auth_bl1(lr=0x2069000):
|
def auth_bl1(lr=0x2069000):
|
||||||
# Load the firmware
|
# Load the firmware
|
||||||
self.cd.arch_dbg.state.X0 = 1
|
self.cd.arch_dbg.state.X0 = 1
|
||||||
@ -667,6 +675,7 @@ class ExynosDevice():
|
|||||||
### Check if authentication was successful - X0 should not be 0??
|
### Check if authentication was successful - X0 should not be 0??
|
||||||
# assert self.cd.arch_dbg.state.X0 == 0, "auth_bl1 returned with error!"
|
# assert self.cd.arch_dbg.state.X0 == 0, "auth_bl1 returned with error!"
|
||||||
|
|
||||||
|
# Jump into BL1 (sboot.bin.1.bin)
|
||||||
JUMP_BL1 = 0x000002c0
|
JUMP_BL1 = 0x000002c0
|
||||||
def jump_bl1(lr):
|
def jump_bl1(lr):
|
||||||
self.cd.arch_dbg.state.LR = 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())
|
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"
|
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)
|
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))
|
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(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"))
|
||||||
|
|
||||||
|
# And jump into BL1 to execute it
|
||||||
jump_bl1(DEBUGGER_ADDR)
|
jump_bl1(DEBUGGER_ADDR)
|
||||||
|
|
||||||
# ==== BL31 ====
|
# ==== BL31 ====
|
||||||
|
# Assure that the debugger is still alive
|
||||||
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"
|
||||||
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)
|
# 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
|
lr = self.cd.arch_dbg.state.LR
|
||||||
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
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)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read())
|
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read())
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
|
# Assure that the debugger is returning (obligatory assuration)
|
||||||
self.usb_read(0x200) # GiAs
|
self.usb_read(0x200) # GiAs
|
||||||
# lr = self.cd.arch_dbg.state.LR
|
# lr = self.cd.arch_dbg.state.LR
|
||||||
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # Resore oginal boot flow
|
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # to resotre oginal boot flow, without getting back to the debugger
|
||||||
|
|
||||||
self.get_ttbr0_el3()
|
|
||||||
|
|
||||||
|
# Set LR to continue boot flow
|
||||||
self.cd.restore_stack_and_jump(lr)
|
self.cd.restore_stack_and_jump(lr)
|
||||||
|
|
||||||
|
# Assure return to debugger
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.usb_read(0x200) # GiAs
|
self.usb_read(0x200) # GiAs
|
||||||
self.cd.memwrite_region(0x02031008, b"ELH")
|
self.cd.memwrite_region(0x02031008, b"ELH")
|
||||||
|
|
||||||
# trampoline = self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br") # Keep LR
|
# Relocate to other debugger (For after BL31, but we need a good space!)
|
||||||
# self.cd.memwrite_region(0x02024020, trampoline)
|
|
||||||
|
|
||||||
# ====== PATCHES TO BL31 here! ======
|
|
||||||
|
|
||||||
# Relocate to other debugger
|
|
||||||
# debugger = open("../../dump/reloc_debugger_0x2019e5c.bin", "rb").read()
|
# debugger = open("../../dump/reloc_debugger_0x2019e5c.bin", "rb").read()
|
||||||
# self.relocate_debugger(debugger=debugger, entry=0x14AC0000, storage=0x14AC3000, g_data_received=0x14AC4000)
|
# self.relocate_debugger(debugger=debugger, entry=0x14AC0000, storage=0x14AC3000, g_data_received=0x14AC4000)
|
||||||
# DEBUGGER_ADDR = 0x14AC0000
|
# DEBUGGER_ADDR = 0x14AC0000
|
||||||
|
|
||||||
# Jump BL31
|
|
||||||
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
||||||
# 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 0's to 0x11600
|
|
||||||
|
|
||||||
# Inspect TTBR0_EL3 table
|
# Inspect TTBR0_EL3 table
|
||||||
TTBR0_EL3 = 0x02035600 # Zeroed
|
TTBR0_EL3 = 0x02035600 # Zeroed out
|
||||||
|
|
||||||
# Overwrite 02028b0c from 5f5820f8 to d503201f -> Doesn't seem to be doing anything
|
# 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(0x02028b0c, struct.pack('>I', 0xd503201f))
|
|
||||||
# Same at 02028b8c
|
|
||||||
# self.cd.memwrite_region(0x02028b8c, struct.pack('>I', 0xd503201f))
|
|
||||||
|
|
||||||
# Modifies setting up MMU (but is set up eventually)
|
|
||||||
# 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 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)
|
self.cd.restore_stack_and_jump(0x02024010)
|
||||||
|
|
||||||
|
# Obligatory reconnect and check of debugger
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
|
|
||||||
self.usb_read(0x200) # GiAs
|
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
|
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
|
# Again restore bootflow
|
||||||
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun))
|
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun))
|
||||||
self.cd.restore_stack_and_jump(hijacked_fun)
|
self.cd.restore_stack_and_jump(hijacked_fun)
|
||||||
@ -770,17 +776,17 @@ class ExynosDevice():
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
|
|
||||||
|
|
||||||
# ==== Stage 4 ====
|
# ==== Stage 4 ====
|
||||||
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
|
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
|
||||||
# Patching
|
|
||||||
|
|
||||||
|
# Patching
|
||||||
# stage4_len = len(stage4)
|
# stage4_len = len(stage4)
|
||||||
# patch_len = len(b"USB RECOVERY MODE")
|
# patch_len = len(b"USB RECOVERY MODE")
|
||||||
# patch = b"ELHER HERE" + (b"\x00" * (patch_len - len(b"ELHER HERE")))
|
# patch = b"ELHER HERE" + (b"\x00" * (patch_len - len(b"ELHER HERE")))
|
||||||
# patch_offset = stage4.find(b"USB RECOVERY MODE")
|
# patch_offset = stage4.find(b"USB RECOVERY MODE")
|
||||||
# stage4 = stage4[:patch_offset] + patch + stage4[patch_len + patch_offset:]
|
# stage4 = stage4[:patch_offset] + patch + stage4[patch_len + patch_offset:]
|
||||||
# assert len(stage4) == stage4_len, "Invalid stage4 length"
|
# assert len(stage4) == stage4_len, "Invalid stage4 length"
|
||||||
|
|
||||||
self.send_normal_stage(stage4)
|
self.send_normal_stage(stage4)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user