Revert changes in exploit.py
This commit is contained in:
parent
34ca995109
commit
416521c8c7
@ -12,7 +12,9 @@ pages:
|
||||
- python -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip install -r <(head -n -1 requirements.txt)
|
||||
- documentation/make html
|
||||
- cd documentation
|
||||
- make html
|
||||
- cd ..
|
||||
- cp -r documentation/build/* .public
|
||||
- mv .public public
|
||||
artifacts:
|
||||
|
@ -17,8 +17,6 @@ After exploitation the goal is to fully boot the device. The following part desc
|
||||
|
||||
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:
|
||||
@ -36,8 +34,6 @@ Booting an authenticated and patched BL1:
|
||||
|
||||
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
|
||||
@ -127,8 +123,9 @@ The processor state reported then is:
|
||||
X21 : 0x0 | X22 : 0x0 | X23 : 0x0 | X24 : 0x0 | X25 : 0x0 | X26 : 0x0 | X27 : 0x1 |
|
||||
X28 : 0x0 | X29 : 0x2020f00 | LR/X30 : 0x20c0000 | SP/X31 : 0x2020ef0
|
||||
|
||||
Initial boot function
|
||||
---
|
||||
Initial boot function (BL1)
|
||||
---------------------
|
||||
|
||||
.. figure:: images/initial_boot_function.png
|
||||
:align: center
|
||||
|
||||
@ -186,9 +183,79 @@ BL1 is laoded at the download buffer and self copies to ``0x02024000`` and resum
|
||||
|
||||
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).
|
||||
|
||||
By adding the IMEM to ghidra, we can have a look at what is going here. (How is this done in Ghidra?). We seem to lose control of our debugger once we step into the `some_weird_brom_function`.
|
||||
By adding the IMEM to ghidra, we can have a look at what is going here. After having modified the LR to jump back to the debugger and jumping into auth_bl1 at ``0x00012848`` we jump back to the debugger. Jumping into BL1 at ``2c0`` does not return us to the debugger. Here we need to hijack ``020200dc`` and ``02021880`` we're able to boot into BL1. We store the address of the hijacked function, to restore it later for a proper boot flow.
|
||||
|
||||
.. code:: python
|
||||
auth_bl1(DEBUGGER_ADDR)
|
||||
self.usb_write(b"FLSH") # Flush cache
|
||||
hijacked_fun = u32(self.cd.memdump_region(0x020200dc, 4))
|
||||
|
||||
# BL1 patches
|
||||
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"))
|
||||
|
||||
Authentication of BL1 seems to be done at ``0x0012848``. With return value '0' expected when this function is executed, to execute other functions.
|
||||
|
||||
.. figure:: images/bl1_auth_references.png
|
||||
:align: center
|
||||
|
||||
BL1 authentication.
|
||||
|
||||
purpose
|
||||
^^^^^^^
|
||||
bl1 interacts with several pheriperals, from the DTB these are:
|
||||
|
||||
.. code-block:: dtsi
|
||||
|
||||
/* FSYS0 */
|
||||
pinctrl_5: pinctrl@10E60000 {
|
||||
compatible = "samsung,exynos8890-pinctrl";
|
||||
reg = <0x0 0x10E60000 0x1000>;
|
||||
interrupts = <0 212 0>;
|
||||
};
|
||||
|
||||
/* FSYS1 */
|
||||
pinctrl_6: pinctrl@15690000 {
|
||||
compatible = "samsung,exynos8890-pinctrl";
|
||||
reg = <0x0 0x15690000 0x1000>;
|
||||
interrupts = <0 202 0>;
|
||||
};
|
||||
|
||||
/* PERIC1 */
|
||||
pinctrl_9: pinctrl@14CC0000 {
|
||||
compatible = "samsung,exynos8890-pinctrl";
|
||||
reg = <0x0 0x14CC0000 0x1000>;
|
||||
interrupts = <0 460 0>;
|
||||
};
|
||||
|
||||
pmu_system_controller: system-controller@105C0000 {
|
||||
compatible = "samsung,exynos8890-pmu", "syscon";
|
||||
reg = <0x0 0x105C0000 0x10000>;
|
||||
};
|
||||
|
||||
rtc@10070000 {
|
||||
compatible = "samsung,s3c6410-rtc";
|
||||
reg = <0x0 0x10070000 0x100>;
|
||||
interrupts = <0 73 0>, <0 74 0>;
|
||||
clocks = <&clock 157>;
|
||||
clock-names = "gate_rtc";
|
||||
};
|
||||
|
||||
Probably the only thing it does is set some clocks and prepare for BL31.
|
||||
|
||||
BL31
|
||||
----
|
||||
|
||||
BL31 is written at 0x02024000 with the entry point at 0x02024010.
|
||||
|
||||
BL2
|
||||
---
|
||||
|
||||
0x02e8dc mentions 'Onyx-OPR6-8511R1', which is likely sboot.
|
||||
|
||||
OLD
|
||||
---
|
||||
|
||||
TODO TODO TODO
|
||||
The reason for this is the following code in bl1:
|
||||
|
||||
.. code-block:: c
|
||||
@ -238,52 +305,3 @@ Replacing this function with our debugger makes us jump back:
|
||||
|
||||
However this does not fully run bl1, so we will have to dig a bit deeper to see the puropose and when to jump back to the debugger.
|
||||
|
||||
Authentication of BL1 seems to be done at ``0x0012848``. With return value '0' expected when this function is executed, to execute other functions.
|
||||
|
||||
.. figure:: images/bl1_auth_references.png
|
||||
:align: center
|
||||
|
||||
BL1 authentication.
|
||||
|
||||
purpose
|
||||
^^^^^^^
|
||||
bl1 interacts with several pheriperals, from the DTB these are:
|
||||
|
||||
.. code-block:: dtsi
|
||||
|
||||
/* FSYS0 */
|
||||
pinctrl_5: pinctrl@10E60000 {
|
||||
compatible = "samsung,exynos8890-pinctrl";
|
||||
reg = <0x0 0x10E60000 0x1000>;
|
||||
interrupts = <0 212 0>;
|
||||
};
|
||||
|
||||
/* FSYS1 */
|
||||
pinctrl_6: pinctrl@15690000 {
|
||||
compatible = "samsung,exynos8890-pinctrl";
|
||||
reg = <0x0 0x15690000 0x1000>;
|
||||
interrupts = <0 202 0>;
|
||||
};
|
||||
|
||||
/* PERIC1 */
|
||||
pinctrl_9: pinctrl@14CC0000 {
|
||||
compatible = "samsung,exynos8890-pinctrl";
|
||||
reg = <0x0 0x14CC0000 0x1000>;
|
||||
interrupts = <0 460 0>;
|
||||
};
|
||||
|
||||
pmu_system_controller: system-controller@105C0000 {
|
||||
compatible = "samsung,exynos8890-pmu", "syscon";
|
||||
reg = <0x0 0x105C0000 0x10000>;
|
||||
};
|
||||
|
||||
rtc@10070000 {
|
||||
compatible = "samsung,s3c6410-rtc";
|
||||
reg = <0x0 0x10070000 0x100>;
|
||||
interrupts = <0 73 0>, <0 74 0>;
|
||||
clocks = <&clock 157>;
|
||||
clock-names = "gate_rtc";
|
||||
};
|
||||
|
||||
Probably the only thing it does is set some clocks and prepare for BL31
|
||||
|
||||
|
@ -39,7 +39,13 @@ TODO make memory layout of ROM, IMEM and some devices @JONHE
|
||||
.. figure:: images/memory_layout.drawio.svg
|
||||
|
||||
The memory layout of the Exynos 8890
|
||||
|
||||
|
||||
- 0x00000000 to 0x00020000: BootROM
|
||||
- 0x000002c0: BL1 boot entry point
|
||||
- 0x00012848: bootrom authentication function
|
||||
- 0x00019310: BL1 boot function
|
||||
- 0x02069000: First debugger location
|
||||
|
||||
|
||||
Download protocol
|
||||
-----------------
|
||||
|
1380
documentation/source/_ignore/draw_boot.ipynb
Normal file
1380
documentation/source/_ignore/draw_boot.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,8 @@ extensions = [ 'myst_parser',
|
||||
templates_path = ['_templates']
|
||||
exclude_patterns = []
|
||||
|
||||
# Ignore
|
||||
exclude_patterns = ['_ignore']
|
||||
|
||||
# select the theme
|
||||
html_theme = 'sphinx_wagtail_theme'
|
||||
|
@ -12,4 +12,7 @@ pyhidra
|
||||
sphinxcontrib.confluencebuilder
|
||||
sphinxcontrib.drawio
|
||||
sphinx_wagtail_theme
|
||||
plotly
|
||||
numpy
|
||||
nbformat>4.2.0
|
||||
source/ghidra_assistant/ghidra_assistant-0.0.1-py3-none-any.whl
|
@ -625,18 +625,6 @@ class ExynosDevice():
|
||||
|
||||
self.cd.memwrite_region(0x02021880, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
|
||||
|
||||
# self.cd.memwrite_region(0x020200a0, p32(DEBUGGER_ADDR))
|
||||
# self.cd.memwrite_region(0x020200d0, p32(DEBUGGER_ADDR))
|
||||
# self.cd.memwrite_region(0x020200b4, p32(DEBUGGER_ADDR))
|
||||
# self.cd.memwrite_region(0x020200a4, p32(DEBUGGER_ADDR))
|
||||
|
||||
# self.cd.memwrite_region(0x0202297c, self.cd.arch_dbg.sc.mov_0_w0_ins + self.cd.arch_dbg.sc.ret_ins)
|
||||
|
||||
|
||||
GADGET_RET0 = 0x00000d58
|
||||
# self.cd.memwrite_region(0x20296da , p32(GADGET_RET0))
|
||||
# self.cd.memwrite_region(0x20296da + 4, p32(GADGET_RET0))
|
||||
|
||||
# END
|
||||
jump_bl1(DEBUGGER_ADDR)
|
||||
|
||||
@ -655,7 +643,9 @@ class ExynosDevice():
|
||||
|
||||
self.usb_read(0x200) # GiAs
|
||||
# lr = self.cd.arch_dbg.state.LR
|
||||
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # Resore oginal boot flow
|
||||
|
||||
|
||||
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # Resore oginal boot flow
|
||||
|
||||
# TODO patch verification
|
||||
|
||||
@ -677,13 +667,22 @@ class ExynosDevice():
|
||||
# ====== PATCHES TO BL31 here! ======
|
||||
|
||||
|
||||
# Jump BL31
|
||||
# Jump entry BL31
|
||||
self.cd.restore_stack_and_jump(0x02024010)
|
||||
|
||||
|
||||
time.sleep(2)
|
||||
self.connect_device()
|
||||
|
||||
# WORKING
|
||||
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) #Sets jump/X1 address at X0 0x2048000 -> Entry point of BL2
|
||||
|
||||
self.cd.memwrite_region(0x02020, p32(DEBUGGER_ADDR)) # Restore original boot flow
|
||||
|
||||
# Jump into BL2
|
||||
self.cd.restore_stack_and_jump(hijacked_fun)
|
||||
# END
|
||||
|
||||
# self.usb_read(0x200) # GiAs
|
||||
# self.cd.restore_stack_and_jump(hijacked_fun)
|
||||
@ -697,12 +696,12 @@ 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")))
|
||||
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"
|
||||
# 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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user