modifies pointers to also debug boot MIB3

This commit is contained in:
Jonathan Herrewijnen 2024-11-05 17:30:09 +01:00
parent 44ebe96d86
commit 1e040cbea9
3 changed files with 35 additions and 13 deletions

View File

@ -37,7 +37,7 @@
"program": "exploit.py", "program": "exploit.py",
"console": "integratedTerminal", "console": "integratedTerminal",
"justMyCode": false, "justMyCode": false,
"args": ["--debugger-boot"], "args": ["--debugger-boot", "--MIB3"],
}, },
{ {
"name": "Debug current file", "name": "Debug current file",

View File

@ -649,6 +649,17 @@ class ExynosDevice():
self.relocate_debugger(debugger=debugger, entry=0x11200000, storage=0x11203000, g_data_received=0x11204000) self.relocate_debugger(debugger=debugger, entry=0x11200000, storage=0x11203000, g_data_received=0x11204000)
DEBUGGER_ADDR = 0x11200000 DEBUGGER_ADDR = 0x11200000
# Load bootloader stages
bl1 = open("../S7/g930f_latest/fwbl1_a.bin", "rb").read()
bl31 = open("../S7/g930f_latest/el3_mon_a.bin", "rb").read()
bl2 = open("../S7/g930f_latest/bl2_a.bin", "rb").read()
bl33 = open("../S7/g930f_latest/u-boot.bin", "rb").read()
if args.MIB3:
bl1 = open("../S7/g930f_latest/g930f_sboot.bin.1.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()
bl33 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
# Test debugger connection # Test debugger connection
self.cd.test_connection() self.cd.test_connection()
@ -667,7 +678,6 @@ class ExynosDevice():
self.connect_device() self.connect_device()
# Send boot stage 1 # Send boot stage 1
bl1 = open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read()
self.send_normal_stage(bl1) self.send_normal_stage(bl1)
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"
@ -690,7 +700,12 @@ class ExynosDevice():
# Hijack ROM download function # 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"))
BL1_POINTER = 0x02021880
if args.MIB3:
BL1_POINTER = 0x02021890
self.cd.memwrite_region(BL1_POINTER, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
# Write a patch to BL1 in memory # Write a patch to BL1 in memory
# self.cd.memwrite_region(0x2021800+bl1.find(b'2015'), b'2014') # self.cd.memwrite_region(0x2021800+bl1.find(b'2015'), b'2014')
@ -716,7 +731,7 @@ class ExynosDevice():
# After downloading the next stage, make sure the device reconnects # 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(bl31)
time.sleep(2) time.sleep(2)
# Assure that the debugger is returning (obligatory assuration) # Assure that the debugger is returning (obligatory assuration)
@ -730,19 +745,25 @@ class ExynosDevice():
# 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")
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!?)
self.cd.memwrite_region(0x020244e8, struct.pack('>I', 0x1f0c00f1)) # Change check to always be false MMU_CHECK = 0x020244e8
if args.MIB3:
MMU_CHECK = 0x0202a314
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
self.cd.restore_stack_and_jump(0x02024010) BL31_POINTER = 0x02024010
if args.MIB3:
BL31_POINTER = 0x020c0000
self.cd.restore_stack_and_jump(BL31_POINTER)
# Obligatory reconnect and check of debugger # Obligatory reconnect and check of debugger
time.sleep(2) time.sleep(2)
@ -767,7 +788,6 @@ class ExynosDevice():
self.cd.restore_stack_and_jump(hijacked_fun) self.cd.restore_stack_and_jump(hijacked_fun)
# ==== Stage 4 BL2 ==== # ==== Stage 4 BL2 ====
bl2 = open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read()
self.send_normal_stage(bl2) self.send_normal_stage(bl2)
time.sleep(2) time.sleep(2)
self.connect_device() self.connect_device()
@ -794,15 +814,11 @@ class ExynosDevice():
self.cd.restore_stack_and_jump(hijacked_fun) self.cd.restore_stack_and_jump(hijacked_fun)
# ==== Stage 5 ====
# Sends stage 5 (BL33) but returns to debugger after sending.
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
# print_payload = open("/home/jonathan/projects/samsung_s7/source/screen_print/print.bin", "rb").read() # print_payload = open("/home/jonathan/projects/samsung_s7/source/screen_print/print.bin", "rb").read()
# off = stage4.find(bytes.fromhex("fd 7b bd a9 fd 03 00 91 f3 53 01 a9 d4 08 00 d0 f3 03 01 2a a0 17 00 f9")) # off = stage4.find(bytes.fromhex("fd 7b bd a9 fd 03 00 91 f3 53 01 a9 d4 08 00 d0 f3 03 01 2a a0 17 00 f9"))
# stage4 = stage4[off:] + print_payload + stage4[off+len(print_payload):] # stage4 = stage4[off:] + print_payload + stage4[off+len(print_payload):]
self.send_normal_stage(stage4) self.send_normal_stage(bl33)
self.connect_device() self.connect_device()
self.usb_read(0x200) # GiAs self.usb_read(0x200) # GiAs
@ -810,6 +826,11 @@ class ExynosDevice():
self.cd.memwrite_region(0x8f01dbdc, struct.pack('>I', 0x03030035)) self.cd.memwrite_region(0x8f01dbdc, struct.pack('>I', 0x03030035))
self.cd.memwrite_region(0x8f01dbe0, struct.pack('>I', 0x80f9ff34)) self.cd.memwrite_region(0x8f01dbe0, struct.pack('>I', 0x80f9ff34))
# Move default values into registers
self.cd.memwrite_region(0x8f021bac, struct.pack('>I', 0x20008052))
self.cd.memwrite_region(0x8f021bdc, struct.pack('>I', 0x20008052))
self.cd.memwrite_region(0x8f021bbc, struct.pack('>I', 0x20008052))
# Jump into a different function that continues the boot flow (different than BL33_LR) # Jump into a different function that continues the boot flow (different than BL33_LR)
self.cd.restore_stack_and_jump(0x02024e5c) self.cd.restore_stack_and_jump(0x02024e5c)
@ -822,6 +843,7 @@ if __name__ == "__main__":
arg.add_argument("--debug", action="store_true", help="Debug USB stack", default=False) arg.add_argument("--debug", action="store_true", help="Debug USB stack", default=False)
arg.add_argument("--unsecure-boot", action="store_true", help="Unsecure boot", default=False) arg.add_argument("--unsecure-boot", action="store_true", help="Unsecure boot", default=False)
arg.add_argument("--debugger-boot", action="store_true", help="Unsecure boot", default=False) arg.add_argument("--debugger-boot", action="store_true", help="Unsecure boot", default=False)
arg.add_argument("--MIB3", action="store_true", help="Whether boot is on a MIB3", default=False)
args = arg.parse_args() args = arg.parse_args()
exynos = ExynosDevice() exynos = ExynosDevice()

Binary file not shown.