update
This commit is contained in:
parent
8cb5f2e151
commit
2d0557c5c7
@ -11,15 +11,48 @@ TODO document normal samsung boot chain
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: bash
|
||||
@ -256,6 +289,7 @@ bl1 interacts with several pheriperals, from the DTB these are:
|
||||
clock-names = "gate_rtc";
|
||||
};
|
||||
|
||||
Probably the only thing it does is set some clocks and prepare for 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="CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
|
||||
<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_TYPE" TYPE="int" VALUE="0" />
|
||||
<STATE NAME="LOCAL_CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
|
||||
|
@ -1,9 +1,7 @@
|
||||
VERSION=1
|
||||
/
|
||||
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
||||
0000000a:8890_bootrom.bin.1:7f011a6853998629050259
|
||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||
0000000a:8890_bootrom_bl31_loaded:7f011a6853998629050259
|
||||
/dump
|
||||
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
||||
/mib3
|
||||
@ -13,5 +11,8 @@ VERSION=1
|
||||
00000003:bl31.bin:7f011ab837995028720085
|
||||
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
||||
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
||||
/s7/dump
|
||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||
NEXT-ID:b
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -1,9 +1,7 @@
|
||||
VERSION=1
|
||||
/
|
||||
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||
0000000a:8890_bootrom_bl31_loaded:7f011a6853998629050259
|
||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||
/dump
|
||||
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
||||
/mib3
|
||||
@ -13,5 +11,8 @@ VERSION=1
|
||||
00000003:bl31.bin:7f011ab837995028720085
|
||||
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
||||
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
||||
/s7/dump
|
||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||
NEXT-ID:b
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -4,7 +4,8 @@ VERSION=1
|
||||
00000004:udf_7f011842b8231996037592:7f01190f112184430945139
|
||||
00000003:udf_7f011872b8163836628792:7f011a9478217161533597
|
||||
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
||||
00000006:udf_7f0119bd531451643843511:7f011a1c131523520933550
|
||||
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
||||
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
||||
NEXT-ID:6
|
||||
NEXT-ID:7
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -6,6 +6,7 @@ VERSION=1
|
||||
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
||||
00000006:udf_7f0119bd531451643843511:7f011a1c131523520933550
|
||||
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
||||
00000007:udf_7f011a6853998629050259:7f011a98934430536471611
|
||||
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
||||
NEXT-ID:7
|
||||
NEXT-ID:8
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -1,2 +1,2 @@
|
||||
IADD:00000006:/udf_7f0119bd531451643843511
|
||||
IDSET:/udf_7f0119bd531451643843511:7f011a1c131523520933550
|
||||
IADD:00000007:/udf_7f011a6853998629050259
|
||||
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"
|
||||
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):
|
||||
'''
|
||||
@ -612,15 +629,43 @@ class ExynosDevice():
|
||||
|
||||
# ==== BL31 ====
|
||||
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)
|
||||
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)
|
||||
self.connect_device()
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
# self.usb_read(0x200) # GiAs
|
||||
# self.cd.restore_stack_and_jump(hijacked_fun)
|
||||
|
||||
# ==== Stage 3 BL2 ====
|
||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read())
|
||||
@ -629,9 +674,17 @@ class ExynosDevice():
|
||||
|
||||
|
||||
# ==== 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)
|
||||
self.connect_device()
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
@ -25,8 +25,8 @@ int mystrlen(char *data) {
|
||||
#define recv_buffer 0x020c6200
|
||||
#define data_received 0x020c6000
|
||||
#else
|
||||
#define recv_buffer 0x206fe00 //0x02021800 + 0x3000
|
||||
#define data_received 0x206fd00
|
||||
#define recv_buffer 0x206f000 //0x02021800 + 0x3000
|
||||
#define data_received 0x206f100
|
||||
#endif
|
||||
|
||||
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