Better boot memory overview. Boots into recovery.
This commit is contained in:
parent
fb2c105bf3
commit
5044941619
Binary file not shown.
@ -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.
|
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.
|
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()
|
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).
|
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
@ -1,11 +1,13 @@
|
|||||||
start,end,name,order,comment
|
start,end,name,order,comment
|
||||||
0,131072,BootROM,,
|
0x00000000,0x00020000,BootROM,,
|
||||||
704,21184,BL1 boot entry point,ENTRY,
|
0x02020f60,0x02020f68,_boot_usb_ra,,
|
||||||
25824,46304,Boot USB function,,
|
0x00012848,0x000128e8,auth_bl1,,
|
||||||
75848,96328,bootrom authentication function,,
|
0x000064e0,0x0000658c,_boot_usb,,
|
||||||
103184,123664,BL1 boot function,,
|
0x020c0000,0x020c0004,_frederic_dest_ptr,,
|
||||||
2146304,2166784,Frederic Destination pointer,,
|
0x000002c0,0x000002c4,_jump_bl1,,
|
||||||
33689440,33689448,Boot USB return address,,
|
0x02022000,0x02024000,BL1,,
|
||||||
33691000,33711480,Event buffer pointer,,
|
0x02024000,0x02048000,BL31,,
|
||||||
33984512,34004992,First debugger location,,
|
0x02048000,0x0206ed10,BL2,,
|
||||||
33992704,34013184,End of memory stack,,
|
0x02069000,0x0206f000,Debugger,,
|
||||||
|
0x020c0000,0x020c7000,Debugger relocated,,
|
||||||
|
0x0206ed10,0x02070000,End of readable memory space in buffer,,
|
|
@ -306,25 +306,20 @@ class ExynosDevice():
|
|||||||
count += 1
|
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.
|
Dumps memory from the device.
|
||||||
|
|
||||||
Transfer XFER_BUFFER at 0x02021800, to: 0x02020F08. End of memory at 0x0206ffff.
|
Transfer XFER_BUFFER at 0x02021800, to: 0x02020F08. End of memory at 0x0206ffff.
|
||||||
"""
|
"""
|
||||||
# NOT WORKING YET
|
|
||||||
transferred = ctypes.c_int()
|
|
||||||
dumped = b""
|
dumped = b""
|
||||||
# Read data from memory
|
# Read data from memory
|
||||||
for block in tqdm.tqdm(range(start, end, 0x200)):
|
try:
|
||||||
self.usb_write(p32(block-0x200))
|
for block in tqdm.tqdm(range(start, end, 0x6000)):
|
||||||
res = self.usb_read(0x200)
|
dump = self.cd.memdump_region(block, 0x6000)
|
||||||
dumped += res
|
dumped += dump
|
||||||
|
except:
|
||||||
if write:
|
print("Error reading memory, at block: ", hex(block))
|
||||||
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)
|
|
||||||
return dumped
|
return dumped
|
||||||
|
|
||||||
|
|
||||||
@ -402,26 +397,6 @@ class ExynosDevice():
|
|||||||
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(0x020c7000, 0x020c0000, 0x020c4000)
|
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):
|
def dumb_interact(self, dump_imems=False):
|
||||||
'''
|
'''
|
||||||
Room for playing around with the debugger on the phone.
|
Room for playing around with the debugger on the phone.
|
||||||
@ -599,8 +574,9 @@ 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()
|
||||||
|
|
||||||
# self.relocate_debugger()
|
# dumped = self.dump_memory(0x20000, 0x2070000)
|
||||||
DEBUGGER_ADDR = 0x2069000 #0x020c0000
|
|
||||||
|
DEBUGGER_ADDR = 0x2069000
|
||||||
|
|
||||||
### Overwrite boot_usb_ra to our debugger
|
### Overwrite boot_usb_ra to our debugger
|
||||||
self.cd.test_connection()
|
self.cd.test_connection()
|
||||||
@ -638,13 +614,13 @@ class ExynosDevice():
|
|||||||
# BL1 is loaded, now authenticat and patch it
|
# BL1 is loaded, now authenticat 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
|
||||||
|
|
||||||
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"))
|
||||||
jump_bl1(DEBUGGER_ADDR)
|
jump_bl1(DEBUGGER_ADDR)
|
||||||
|
|
||||||
|
|
||||||
# ==== BL31 ====
|
# ==== BL31 ====
|
||||||
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"
|
||||||
|
|
||||||
@ -658,45 +634,42 @@ class ExynosDevice():
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
self.usb_read(0x200) # GiAs
|
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.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.LR = DEBUGGER_ADDR
|
||||||
# self.cd.arch_dbg.state.X0 = 0x020347f0
|
# self.cd.arch_dbg.state.X0 = 0x020347f0
|
||||||
# self.cd.arch_dbg.state.X1 = 0
|
# self.cd.arch_dbg.state.X1 = 0
|
||||||
# self.cd.restore_stack_and_jump(0x02030464)
|
# self.cd.restore_stack_and_jump(0x02030464)
|
||||||
self.cd.restore_stack_and_jump(lr)
|
self.cd.restore_stack_and_jump(lr)
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
self.usb_read(0x200) # GiAs
|
||||||
|
|
||||||
# ====== PATCHES TO BL31 here! ======
|
|
||||||
self.cd.memwrite_region(0x02031008, b"ELH")
|
self.cd.memwrite_region(0x02031008, b"ELH")
|
||||||
|
# ====== PATCHES TO BL31 here! ======
|
||||||
|
|
||||||
# Jump into BL31
|
|
||||||
|
# Jump BL31
|
||||||
self.cd.restore_stack_and_jump(0x02024010)
|
self.cd.restore_stack_and_jump(0x02024010)
|
||||||
|
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
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.usb_read(0x200) # GiAs
|
||||||
# self.cd.memwrite_region(0x02020, p32(DEBUGGER_ADDR)) # Restore original boot flow
|
# self.cd.restore_stack_and_jump(hijacked_fun)
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# ==== Stage 3 BL2 ====
|
# ==== Stage 3 BL2 ====
|
||||||
BL2_FUN = 0x2048000
|
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read())
|
||||||
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())
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
|
|
||||||
@ -704,6 +677,7 @@ class ExynosDevice():
|
|||||||
# ==== 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")))
|
||||||
|
Loading…
Reference in New Issue
Block a user