update
This commit is contained in:
parent
8cb5f2e151
commit
2d0557c5c7
@ -11,15 +11,48 @@ TODO document normal samsung boot chain
|
|||||||
Exploitation
|
Exploitation
|
||||||
============
|
============
|
||||||
|
|
||||||
After exploitation the goal is to fully boot the device.
|
After exploitation the goal is to fully boot the device. The following part describes the current boot chain
|
||||||
|
|
||||||
Current boot chain:
|
.. important::
|
||||||
|
|
||||||
.. figure:: images/boot_chain.drawio.svg
|
This is under development and will still change.
|
||||||
|
|
||||||
|
BL1
|
||||||
|
---
|
||||||
|
The first stage is downloading BL1, authenticating it and patching it after authentication.
|
||||||
|
This is done by overwriting the USB return address pointer and jumping back to the debugger.
|
||||||
|
In the debugger we can authenticate BL1, patch it and boot it. An overview of this process is shown below:
|
||||||
|
|
||||||
|
Booting an authenticated and patched BL1:
|
||||||
|
|
||||||
|
.. figure:: images/boot_chain_bl1.drawio.svg
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
Boot chain
|
Boot chain
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
git commit 8cb5f2e1 fully boots, you can use this commit to patch bl1 only.
|
||||||
|
|
||||||
|
Next up is BL31, which is loaded by BL1.
|
||||||
|
|
||||||
|
BL31
|
||||||
|
----
|
||||||
|
``BL31`` is the secure monitor. The monitor uses memory that is also being used by the debugger, so we will have to relocate it to keep code exeuction.
|
||||||
|
|
||||||
|
.. figure:: images/bl31_debugger_memory_example.png
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
Example of BL31 using debugger memory.
|
||||||
|
|
||||||
|
BL31 also configures the VBAR_EL3 and MMU so the memory mapping will probably change after this stage.
|
||||||
|
|
||||||
|
It would be nice to patch BL31 before it is being executed. However the current exploit boot flow does not allow this because the ROM function downloads the next stage.
|
||||||
|
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
|
||||||
As done by Frederic, the bootrom can be dumped using his provided scripts, and can the be split into different boots:
|
As done by Frederic, the bootrom can be dumped using his provided scripts, and can the be split into different boots:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
@ -256,6 +289,7 @@ bl1 interacts with several pheriperals, from the DTB these are:
|
|||||||
clock-names = "gate_rtc";
|
clock-names = "gate_rtc";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Probably the only thing it does is set some clocks and prepare for BL31
|
||||||
|
|
||||||
BL31
|
BL31
|
||||||
----
|
----
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 5.8 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 10 KiB |
16
documentation/source/BootROM_8890/notes.rst
Normal file
16
documentation/source/BootROM_8890/notes.rst
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
========
|
||||||
|
Emulator
|
||||||
|
========
|
||||||
|
What is interesting about the ROM is that it starts by checking MPIDR_EL1 register and doing a conditional branch to 0x20e0000.
|
||||||
|
|
||||||
|
.. code-block:: ghidra
|
||||||
|
|
||||||
|
|
||||||
|
undefined w0:1 <RETURN>
|
||||||
|
Reset XREF[1]: Entry Point(*)
|
||||||
|
00000000 bb 00 38 d5 mrs x27,mpidr_el1
|
||||||
|
00000004 7b 0f 78 92 and x27,x27,#0xf00
|
||||||
|
00000008 7f 03 00 f1 cmp x27,#0x0
|
||||||
|
0000000c 41 00 00 54 b.ne LAB_00000014
|
||||||
|
00000010 fc 7f 83 14 b LAB_020e0000
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
#Ghidra Lock File
|
|
||||||
#Thu Aug 15 13:43:49 CEST 2024
|
|
||||||
OS\ Name=Linux
|
|
||||||
OS\ Version=6.5.0-44-generic
|
|
||||||
Username=eljakim
|
|
||||||
Hostname=levith
|
|
||||||
<META>\ Supports\ File\ Channel\ Locking=Channel Lock
|
|
||||||
OS\ Architecture=amd64
|
|
||||||
Timestamp=8/15/24, 1\:43 PM
|
|
@ -4,7 +4,7 @@
|
|||||||
<STATE NAME="EXCLUSIVE" TYPE="boolean" VALUE="false" />
|
<STATE NAME="EXCLUSIVE" TYPE="boolean" VALUE="false" />
|
||||||
<STATE NAME="CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
|
<STATE NAME="CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
|
||||||
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
|
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
|
||||||
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
|
<STATE NAME="PARENT" TYPE="string" VALUE="/s7/dump" />
|
||||||
<STATE NAME="FILE_ID" TYPE="string" VALUE="7f011889d240069673442230" />
|
<STATE NAME="FILE_ID" TYPE="string" VALUE="7f011889d240069673442230" />
|
||||||
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
|
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
|
||||||
<STATE NAME="LOCAL_CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
|
<STATE NAME="LOCAL_CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
VERSION=1
|
VERSION=1
|
||||||
/
|
/
|
||||||
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
||||||
0000000a:8890_bootrom.bin.1:7f011a6853998629050259
|
0000000a:8890_bootrom_bl31_loaded:7f011a6853998629050259
|
||||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
|
||||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
|
||||||
/dump
|
/dump
|
||||||
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
||||||
/mib3
|
/mib3
|
||||||
@ -13,5 +11,8 @@ VERSION=1
|
|||||||
00000003:bl31.bin:7f011ab837995028720085
|
00000003:bl31.bin:7f011ab837995028720085
|
||||||
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
||||||
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
||||||
|
/s7/dump
|
||||||
|
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||||
|
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||||
NEXT-ID:b
|
NEXT-ID:b
|
||||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
VERSION=1
|
VERSION=1
|
||||||
/
|
/
|
||||||
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
||||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
|
||||||
0000000a:8890_bootrom_bl31_loaded:7f011a6853998629050259
|
0000000a:8890_bootrom_bl31_loaded:7f011a6853998629050259
|
||||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
|
||||||
/dump
|
/dump
|
||||||
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
||||||
/mib3
|
/mib3
|
||||||
@ -13,5 +11,8 @@ VERSION=1
|
|||||||
00000003:bl31.bin:7f011ab837995028720085
|
00000003:bl31.bin:7f011ab837995028720085
|
||||||
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
||||||
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
||||||
|
/s7/dump
|
||||||
|
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||||
|
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||||
NEXT-ID:b
|
NEXT-ID:b
|
||||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||||
|
@ -4,7 +4,8 @@ VERSION=1
|
|||||||
00000004:udf_7f011842b8231996037592:7f01190f112184430945139
|
00000004:udf_7f011842b8231996037592:7f01190f112184430945139
|
||||||
00000003:udf_7f011872b8163836628792:7f011a9478217161533597
|
00000003:udf_7f011872b8163836628792:7f011a9478217161533597
|
||||||
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
||||||
|
00000006:udf_7f0119bd531451643843511:7f011a1c131523520933550
|
||||||
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
||||||
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
||||||
NEXT-ID:6
|
NEXT-ID:7
|
||||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||||
|
@ -6,6 +6,7 @@ VERSION=1
|
|||||||
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
||||||
00000006:udf_7f0119bd531451643843511:7f011a1c131523520933550
|
00000006:udf_7f0119bd531451643843511:7f011a1c131523520933550
|
||||||
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
||||||
|
00000007:udf_7f011a6853998629050259:7f011a98934430536471611
|
||||||
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
||||||
NEXT-ID:7
|
NEXT-ID:8
|
||||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
IADD:00000006:/udf_7f0119bd531451643843511
|
IADD:00000007:/udf_7f011a6853998629050259
|
||||||
IDSET:/udf_7f0119bd531451643843511:7f011a1c131523520933550
|
IDSET:/udf_7f011a6853998629050259:7f011a98934430536471611
|
||||||
|
15
source/emulator/.vscode/launch.json
vendored
Normal file
15
source/emulator/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Exynos Emultor",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "emulator.py",
|
||||||
|
"console": "integratedTerminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
36
source/emulator/emulator.py
Normal file
36
source/emulator/emulator.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from ghidra_assistant.utils.utils import *
|
||||||
|
from ghidra_assistant.utils.archs.arm64.arm64_emulator import ARM64UC_Emulator
|
||||||
|
from unicorn.arm64_const import *
|
||||||
|
from unicorn.unicorn_const import *
|
||||||
|
|
||||||
|
class ExynosEmulator(ARM64UC_Emulator):
|
||||||
|
def __init__(self, rom_path):
|
||||||
|
super().__init__()
|
||||||
|
self.rom_path = rom_path
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
self.setup_memory()
|
||||||
|
self.setup_registers()
|
||||||
|
|
||||||
|
def setup_memory(self):
|
||||||
|
#ROM
|
||||||
|
self.uc.mem_map(0x0, 128 * KB, UC_PROT_READ | UC_PROT_EXEC)
|
||||||
|
self.uc.mem_write(0x0, open(self.rom_path, "rb").read())
|
||||||
|
pass
|
||||||
|
|
||||||
|
def setup_registers(self):
|
||||||
|
self.pc = 0x0
|
||||||
|
self.uc.reg_write(UC_ARM64_REG_PC, self.pc)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
self.uc.emu_start(self.pc, self.pc + 1)
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
self.print_ctx(print)
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
emulator = ExynosEmulator("../S7/rom.bin")
|
||||||
|
emulator.run()
|
@ -385,6 +385,23 @@ 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_2(self):
|
||||||
|
# Seems to be cleared upon cache clearing??
|
||||||
|
if os.getenv("USER") == "eljakim":
|
||||||
|
debugger_reloc = open("/home/eljakim/Source/gupje/source/bin/samsung_s7/reloc_debugger.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.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):
|
||||||
'''
|
'''
|
||||||
@ -612,15 +629,43 @@ class ExynosDevice():
|
|||||||
|
|
||||||
# ==== 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"
|
||||||
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # To continue booting next stages
|
|
||||||
self.cd.restore_stack_and_jump(hijacked_fun)
|
self.cd.memwrite_region(self.cd.arch_dbg.state.X0, open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read())
|
||||||
|
|
||||||
|
|
||||||
|
lr = self.cd.arch_dbg.state.LR
|
||||||
|
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
|
||||||
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()[:0x10])
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
self.usb_read(0x200) # GiAs
|
||||||
|
# lr = self.cd.arch_dbg.state.LR
|
||||||
|
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun))
|
||||||
|
GADGET_RET0 = 0x00000d58
|
||||||
|
self.cd.memwrite_region(0x020200e4, p32(GADGET_RET0))
|
||||||
|
|
||||||
|
# ====== PATCHES TO BL31 here! ======
|
||||||
|
# TODO fix not checking signatures
|
||||||
|
# self.cd.memwrite_region(0x02031008, b"ELH")
|
||||||
|
# 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)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
# self.usb_read(0x200) # GiAs
|
||||||
|
# self.cd.restore_stack_and_jump(hijacked_fun)
|
||||||
|
|
||||||
# ==== Stage 3 BL2 ====
|
# ==== Stage 3 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())
|
||||||
@ -629,9 +674,17 @@ class ExynosDevice():
|
|||||||
|
|
||||||
|
|
||||||
# ==== Stage 4 ====
|
# ==== Stage 4 ====
|
||||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read())
|
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")))
|
||||||
|
# patch_offset = stage4.find(b"USB RECOVERY MODE")
|
||||||
|
# stage4 = stage4[:patch_offset] + patch + stage4[patch_len + patch_offset:]
|
||||||
|
# assert len(stage4) == stage4_len, "Invalid stage4 length"
|
||||||
|
self.send_normal_stage(stage4)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ int mystrlen(char *data) {
|
|||||||
#define recv_buffer 0x020c6200
|
#define recv_buffer 0x020c6200
|
||||||
#define data_received 0x020c6000
|
#define data_received 0x020c6000
|
||||||
#else
|
#else
|
||||||
#define recv_buffer 0x206fe00 //0x02021800 + 0x3000
|
#define recv_buffer 0x206f000 //0x02021800 + 0x3000
|
||||||
#define data_received 0x206fd00
|
#define data_received 0x206f100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void recv_data_cb(uint32_t endpoint, uint32_t len){
|
void recv_data_cb(uint32_t endpoint, uint32_t len){
|
||||||
|
14
source/gupje_device/reloc2_linkscript.ld
Normal file
14
source/gupje_device/reloc2_linkscript.ld
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
MEMORY {
|
||||||
|
ROM (rwx): ORIGIN = 0x020c0000, LENGTH = 0x1000
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x020c0000;
|
||||||
|
.text . : {
|
||||||
|
*(.text*)
|
||||||
|
*(.data*)
|
||||||
|
*(.rodata*)
|
||||||
|
} >ROM
|
||||||
|
|
||||||
|
}
|
12
source/gupje_device/reloc2_symbols.txt
Normal file
12
source/gupje_device/reloc2_symbols.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
debugger_storage = 0x020c4000;
|
||||||
|
debugger_stack = 0x020c2000;
|
||||||
|
debugger_entry = 0x020c0000;
|
||||||
|
|
||||||
|
maybe_usb_setup_read = 0x00006f88;
|
||||||
|
dwc3_ep0_start_trans = 0x0000791c;
|
||||||
|
usb_event_handler = 0x00007bac;
|
||||||
|
get_endpoint_recv_buffer = 0x00007a7c;
|
||||||
|
exynos_sleep = 0x000027c8;
|
||||||
|
|
||||||
|
g_recv_buffer = 0x020c6200;
|
||||||
|
g_data_received = 0x020c6000;
|
Loading…
Reference in New Issue
Block a user