Better boot memory overview. Boots into recovery.

This commit is contained in:
Jonathan Herrewijnen 2024-08-26 17:45:29 +02:00
parent fb2c105bf3
commit 5044941619
5 changed files with 757 additions and 318 deletions

View File

@ -77,7 +77,7 @@ This results in the following files:
After loading the stage1 (entry.S - Frederic's exploit), we're allowed to send custom payloads to the device. The first payload that is then sent, is the debugger.
debugger
Debugger
--------
The initial debugger is written to ``0x2069000``, with debugger_stack and _storage at ``0x0206b000`` and ``0x0206d000`` respectively.
@ -179,7 +179,7 @@ After authentication the bootROM jumps to this function at, we can execute this
jump_fwbl1()
BL1 is laoded at the download buffer and self copies to ``0x02024000`` and resumes execution there (``0x02024010``).
BL1 is loaded at the download buffer and self copies to ``0x02022000`` and resumes execution there (``0x02024010``), with a size of 0x2000 (0x02022000 to 0x02024000).
However, this does not result in a jump back to the debugger. But the ROM still allows receival of one data package from the USB host (this is likely the system 'waiting' to receive the bootloader).

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,13 @@
start,end,name,order,comment
0,131072,BootROM,,
704,21184,BL1 boot entry point,ENTRY,
25824,46304,Boot USB function,,
75848,96328,bootrom authentication function,,
103184,123664,BL1 boot function,,
2146304,2166784,Frederic Destination pointer,,
33689440,33689448,Boot USB return address,,
33691000,33711480,Event buffer pointer,,
33984512,34004992,First debugger location,,
33992704,34013184,End of memory stack,,
0x00000000,0x00020000,BootROM,,
0x02020f60,0x02020f68,_boot_usb_ra,,
0x00012848,0x000128e8,auth_bl1,,
0x000064e0,0x0000658c,_boot_usb,,
0x020c0000,0x020c0004,_frederic_dest_ptr,,
0x000002c0,0x000002c4,_jump_bl1,,
0x02022000,0x02024000,BL1,,
0x02024000,0x02048000,BL31,,
0x02048000,0x0206ed10,BL2,,
0x02069000,0x0206f000,Debugger,,
0x020c0000,0x020c7000,Debugger relocated,,
0x0206ed10,0x02070000,End of readable memory space in buffer,,
1 start end name order comment
2 0 0x00000000 131072 0x00020000 BootROM
3 704 0x02020f60 21184 0x02020f68 BL1 boot entry point _boot_usb_ra ENTRY
4 25824 0x00012848 46304 0x000128e8 Boot USB function auth_bl1
5 75848 0x000064e0 96328 0x0000658c bootrom authentication function _boot_usb
6 103184 0x020c0000 123664 0x020c0004 BL1 boot function _frederic_dest_ptr
7 2146304 0x000002c0 2166784 0x000002c4 Frederic Destination pointer _jump_bl1
8 33689440 0x02022000 33689448 0x02024000 Boot USB return address BL1
9 33691000 0x02024000 33711480 0x02048000 Event buffer pointer BL31
10 33984512 0x02048000 34004992 0x0206ed10 First debugger location BL2
11 33992704 0x02069000 34013184 0x0206f000 End of memory stack Debugger
12 0x020c0000 0x020c7000 Debugger relocated
13 0x0206ed10 0x02070000 End of readable memory space in buffer

View File

@ -306,25 +306,20 @@ class ExynosDevice():
count += 1
def dump_memory(self, start: hex=0x0, end: hex=0x0206ffff, write=False):
def dump_memory(self, start: hex=0x0, end: hex=0x02070000, write=False):
"""
Dumps memory from the device.
Transfer XFER_BUFFER at 0x02021800, to: 0x02020F08. End of memory at 0x0206ffff.
"""
# NOT WORKING YET
transferred = ctypes.c_int()
dumped = b""
# Read data from memory
for block in tqdm.tqdm(range(start, end, 0x200)):
self.usb_write(p32(block-0x200))
res = self.usb_read(0x200)
dumped += res
if write:
filename = f"dump_{hex(start)}_{hex(end)}_{self.target}_{datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.bin"
with open(filename, "wb") as f:
f.write(dumped)
try:
for block in tqdm.tqdm(range(start, end, 0x6000)):
dump = self.cd.memdump_region(block, 0x6000)
dumped += dump
except:
print("Error reading memory, at block: ", hex(block))
return dumped
@ -402,26 +397,6 @@ class ExynosDevice():
assert self.usb_read(0x200) == b"GiAs", "Failed to relocate debugger"
self.cd.relocate_debugger(0x020c7000, 0x020c0000, 0x020c4000)
def relocate_debugger_3(self):
"""
Relocate debugger to 0x0201a000, 0x0201c000, 0x0201a000
"""
if os.getenv("USER") == "eljakim":
debugger_reloc = open("/home/eljakim/Source/gupje/source/bin/samsung_s7/debugger_0x0201a000.bin", "rb").read()
else:
try:
debugger_reloc = open("../../dump/reloc_debugger.bin", "rb").read()
except Exception as e:
print(f'Are you missing your debugger? Please ensure it is present in dump/debugger_0x0201a000.bin. {e}')
sys.exit(0)
self.cd.memwrite_region(0x020c0000, debugger_reloc)
# self.usb_write(b"FLSH") # Flush cache
self.cd.restore_stack_and_jump(0x020c0000)
assert self.usb_read(0x200) == b"GiAs", "Failed to relocate debugger"
self.cd.relocate_debugger(0x020c7000, 0x020c0000, 0x020c4000)
def dumb_interact(self, dump_imems=False):
'''
Room for playing around with the debugger on the phone.
@ -599,8 +574,9 @@ class ExynosDevice():
logger.debug('State after setting up initial debugger')
self.cd.arch_dbg.state.print_ctx()
# self.relocate_debugger()
DEBUGGER_ADDR = 0x2069000 #0x020c0000
# dumped = self.dump_memory(0x20000, 0x2070000)
DEBUGGER_ADDR = 0x2069000
### Overwrite boot_usb_ra to our debugger
self.cd.test_connection()
@ -638,13 +614,13 @@ class ExynosDevice():
# BL1 is loaded, now authenticat and patch it
auth_bl1(DEBUGGER_ADDR)
self.usb_write(b"FLSH") # Flush cache
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"))
jump_bl1(DEBUGGER_ADDR)
# ==== BL31 ====
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
@ -658,45 +634,42 @@ class ExynosDevice():
time.sleep(2)
self.usb_read(0x200) # GiAs
# lr = self.cd.arch_dbg.state.LR
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # Resore oginal boot flow
# TODO patch verification
# self.cd.memwrite_region(0x0202010c - 52, p32(GADGET_RET0))
# self.cd.memwrite_region(0x02024774, self.cd.arch_dbg.sc.mov_0_w0_ins + self.cd.arch_dbg.sc.ret_ins)
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
# self.cd.arch_dbg.state.X0 = 0x020347f0
# self.cd.arch_dbg.state.X1 = 0
# self.cd.restore_stack_and_jump(0x02030464)
self.cd.restore_stack_and_jump(lr)
time.sleep(2)
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
# ====== PATCHES TO BL31 here! ======
self.cd.memwrite_region(0x02031008, b"ELH")
# Jump into BL31
time.sleep(2)
self.usb_read(0x200) # GiAs
self.cd.memwrite_region(0x02031008, b"ELH")
# ====== PATCHES TO BL31 here! ======
# Jump BL31
self.cd.restore_stack_and_jump(0x02024010)
time.sleep(2)
self.connect_device()
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
# print(self.cd.memdump_region(0x020200dc, 4))
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) #Sets jump/X1 address at X0 0x2048000 -> Entry point of BL2
# Boot mode? Not sure whether its important (related to boot type at function 02023800?)
# self.cd.memwrite_region(0x02020, p32(DEBUGGER_ADDR)) # Restore original boot flow
# Jump into USB download function
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
# WORKS
self.cd.restore_stack_and_jump(hijacked_fun)
# WORKING UNTIL HERE
# self.usb_read(0x200) # GiAs
# self.cd.restore_stack_and_jump(hijacked_fun)
# ==== Stage 3 BL2 ====
BL2_FUN = 0x2048000
bl2 = open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read()
# bl2 = bl2[:(0x02052bf4-0x02048000)] + b"00000000" + bl2[(0x02052bf4-0x02048000)+8:]
self.send_normal_stage(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())
time.sleep(2)
self.connect_device()
@ -704,6 +677,7 @@ class ExynosDevice():
# ==== 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")))