restore proper boot chain for samsung s7

This commit is contained in:
Jonathan Herrewijnen 2024-11-12 15:48:13 +01:00
parent 091efe2f80
commit e0269ae3f1

View File

@ -650,7 +650,6 @@ class ExynosDevice():
DEBUGGER_ADDR = 0x11200000 DEBUGGER_ADDR = 0x11200000
# Load bootloader stages # Load bootloader stages
bl1 = open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read() bl1 = open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read()
bl31 = open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read() bl31 = open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read()
bl2 = open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read() bl2 = open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read()
@ -725,7 +724,7 @@ class ExynosDevice():
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"
# Get current LR, and store it. Then set LR to debugger. # Get current LR, and store it. Then set LR to debugger.
lr = self.cd.arch_dbg.state.LR BL1_RA = 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 (before executing it) self.cd.restore_stack_and_jump(hijacked_fun) # will jump back to debugger after downloading the next stage (before executing it)
@ -741,32 +740,32 @@ class ExynosDevice():
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # to restore the oginal boot flow, without getting back to the debugger # self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # to restore the oginal boot flow, without getting back to the debugger
# Set LR to continue boot flow # Set LR to continue boot flow
self.cd.restore_stack_and_jump(lr) self.cd.restore_stack_and_jump(BL1_RA)
# Assure return to debugger # 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") # Patch something in BL31
# Get pointer to BL31 # Get pointer to where BL31 returns to
BL31_POINTER = self.cd.arch_dbg.state.LR BL31_RA_PTR = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
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!?)
MMU_CHECK = 0x020244e8 MMU_CHECK = 0x0202a314
if args.MIB3: if not args.MIB3:
MMU_CHECK = 0x0202a314 MMU_CHECK = 0x020244e8
self.cd.memwrite_region(MMU_CHECK, struct.pack('>I', 0x1f0c00f1)) # Change check to always be false self.cd.memwrite_region(MMU_CHECK, struct.pack('>I', 0x1f0c00f1)) # Change check to always be false
# DWC3 OTG update mode -> Might be useful at some point? # DWC3 OTG update mode -> Might be useful at some point?
# self.cd.memwrite_region(0x02021580, struct.pack('>I', 0x00000000)) # self.cd.memwrite_region(0x02021580, struct.pack('>I', 0x00000000))
# Jump into BL31 and execute it # Jump into BL31 and execute it
#BL31_POINTER = 0x02024010 BL31_POINTER = 0x02024010
#if args.MIB3: if args.MIB3:
# BL31_POINTER = 0x020c0000 BL31_POINTER = 0x020c0000
self.cd.restore_stack_and_jump(BL31_POINTER) self.cd.restore_stack_and_jump(BL31_POINTER)
# Obligatory reconnect and check of debugger # Obligatory reconnect and check of debugger
@ -784,14 +783,20 @@ class ExynosDevice():
print(f'MAIR_EL3: {hex(self.cd.arch_dbg.state.MAIR_EL3)}, MAIR_EL2: {hex(self.cd.arch_dbg.state.MAIR_EL2)}, MAIR_EL1: {hex(self.cd.arch_dbg.state.MAIR_EL1)}') print(f'MAIR_EL3: {hex(self.cd.arch_dbg.state.MAIR_EL3)}, MAIR_EL2: {hex(self.cd.arch_dbg.state.MAIR_EL2)}, MAIR_EL1: {hex(self.cd.arch_dbg.state.MAIR_EL1)}')
print(f'Current EL: {hex(self.cd.arch_dbg.state.CURRENT_EL)}') print(f'Current EL: {hex(self.cd.arch_dbg.state.CURRENT_EL)}')
# self.cd.arch_dbg.fetch_special_regs() # -> Does not work with original debugger (?->memory overlap somewhere). Only with relocated debugger. # self.cd.arch_dbg.fetch_special_regs() # -> Does not work with, "--MIB3" original debugger (?->memory overlap somewhere). Only with relocated debugger.
VBAR_EL3 = self.cd.arch_dbg.state.VBAR_EL3 VBAR_EL3 = self.cd.arch_dbg.state.VBAR_EL3
self.test_write_execute(0x11207010) self.test_write_execute(0x11207010)
#if args.MIB3:
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
self.cd.restore_stack_and_jump(hijacked_fun) # Jumps to function that waits for next boot stage
# In BL2, find string 'APOLLO' and modify it
if args.MIB3: if args.MIB3:
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR off = bl2.find(b'APOLLO')
self.cd.restore_stack_and_jump(hijacked_fun) bl2 = bl2[:off] + b'GUPJE' + bl2[off+6:]
# ==== Stage 4 BL2 ==== # ==== Stage 4 BL2 ====
self.send_normal_stage(bl2) self.send_normal_stage(bl2)
@ -816,7 +821,7 @@ class ExynosDevice():
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun) # self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)
# Disable this to keep access to the debugger after senindg the next stage # Disable this to keep access to the debugger after senindg the next stage
self.cd.arch_dbg.state.X23 = DEBUGGER_ADDR # TEMPORARY #self.cd.arch_dbg.state.X23 = DEBUGGER_ADDR # TEMPORARY
self.cd.restore_stack_and_jump(hijacked_fun) self.cd.restore_stack_and_jump(hijacked_fun)
time.sleep(1) time.sleep(1)