From 416521c8c77538aa2a470540ed6e211fbc537d74 Mon Sep 17 00:00:00 2001 From: Jonathan Herrewijnen Date: Wed, 21 Aug 2024 19:00:18 +0200 Subject: [PATCH] Revert changes in exploit.py --- .gitlab-ci.yml | 4 +- .../source/BootROM_8890/boot_chain.rst | 132 +- documentation/source/BootROM_8890/index.rst | 8 +- documentation/source/_ignore/draw_boot.ipynb | 1380 +++++++++++++++++ documentation/source/conf.py | 2 + requirements.txt | 3 + source/exploit/exploit.py | 39 +- 7 files changed, 1489 insertions(+), 79 deletions(-) create mode 100644 documentation/source/_ignore/draw_boot.ipynb diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f4b5723..e7df100 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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: diff --git a/documentation/source/BootROM_8890/boot_chain.rst b/documentation/source/BootROM_8890/boot_chain.rst index 896dc96..6084f58 100644 --- a/documentation/source/BootROM_8890/boot_chain.rst +++ b/documentation/source/BootROM_8890/boot_chain.rst @@ -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 - diff --git a/documentation/source/BootROM_8890/index.rst b/documentation/source/BootROM_8890/index.rst index f245c9e..ca9ec99 100644 --- a/documentation/source/BootROM_8890/index.rst +++ b/documentation/source/BootROM_8890/index.rst @@ -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 ----------------- diff --git a/documentation/source/_ignore/draw_boot.ipynb b/documentation/source/_ignore/draw_boot.ipynb new file mode 100644 index 0000000..b06f804 --- /dev/null +++ b/documentation/source/_ignore/draw_boot.ipynb @@ -0,0 +1,1380 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Using plotly\n", + "import plotly.graph_objects as go\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Convert the following into an appropriate data object, which is searchable, from start, to end, to name and label\n", + "# - 0x00000000 to 0x00020000: BootROM\n", + "# - 0x000002c0: BL1 boot entry point\n", + "# - 0x00012848: bootrom authentication function\n", + "# - 0x00019310: BL1 boot function\n", + "# - 0x02069000: First debugger location\n", + "\n", + "data = [\n", + " {\"start\": 0x00000000, \"end\": 0x00020000, \"name\": \"BootROM\"},\n", + " {\"start\": 0x000002c0, \"name\": \"BL1 boot entry point\"},\n", + " {\"start\": 0x00012848, \"name\": \"bootrom authentication function\"},\n", + " {\"start\": 0x00019310, \"name\": \"BL1 boot function\"},\n", + " {\"start\": 0x02069000, \"name\": \"First debugger location\"}\n", + "]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create block diagram" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "mode": "text", + "text": "BootROM", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 0.5 + ] + }, + { + "mode": "text", + "text": "BL1 boot entry point", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 1.5 + ] + }, + { + "mode": "text", + "text": "Boot USB function", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 2.5 + ] + }, + { + "mode": "text", + "text": "bootrom authentication function", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 3.5 + ] + }, + { + "mode": "text", + "text": "BL1 boot function", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 4.5 + ] + }, + { + "mode": "text", + "text": "Boot USB return address", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 5.5 + ] + }, + { + "mode": "text", + "text": "Event buffer pointer", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 6.5 + ] + }, + { + "mode": "text", + "text": "BL1 pointer", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 7.5 + ] + }, + { + "mode": "text", + "text": "First debugger location", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 8.5 + ] + }, + { + "mode": "text", + "text": "End of memory stack", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 9.5 + ] + }, + { + "mode": "text", + "text": "Frederic Destination pointer", + "textposition": "middle center", + "type": "scatter", + "x": [ + 0.5 + ], + "y": [ + 10.5 + ] + } + ], + "layout": { + "autosize": true, + "height": 1200, + "margin": { + "b": 20, + "l": 200, + "r": 20, + "t": 20 + }, + "shapes": [ + { + "fillcolor": "#12e884", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 0, + "y1": 1 + }, + { + "fillcolor": "#db08ae", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 1, + "y1": 2 + }, + { + "fillcolor": "#50034a", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 2, + "y1": 3 + }, + { + "fillcolor": "#547ec9", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 3, + "y1": 4 + }, + { + "fillcolor": "#daac51", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 4, + "y1": 5 + }, + { + "fillcolor": "#8704ee", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 5, + "y1": 6 + }, + { + "fillcolor": "#86785f", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 6, + "y1": 7 + }, + { + "fillcolor": "#e33d72", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 7, + "y1": 8 + }, + { + "fillcolor": "#2f63f4", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 8, + "y1": 9 + }, + { + "fillcolor": "#1258f9", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 9, + "y1": 10 + }, + { + "fillcolor": "#109cff", + "layer": "below", + "line": { + "width": 2 + }, + "opacity": 0.5, + "type": "rect", + "x0": 0, + "x1": 1, + "y0": 10, + "y1": 11 + } + ], + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "width": 800, + "xaxis": { + "range": [ + 0, + 1 + ], + "tickvals": [ + 0, + 1 + ] + }, + "yaxis": { + "ticktext": [ + "0x0", + "0x2c0 \n 0x12c0", + "0x64e0 \n 0x74e0", + "0x12848 \n 0x13848", + "0x19310 \n 0x1a310", + "0x2020f60 \n 0x2021f60", + "0x2021578 \n 0x2022578", + "0x2021800 \n 0x2022800", + "0x2069000 \n 0x206a000", + "0x206f000 \n 0x2070000", + "0x20c0000 \n 0x20c1000", + "0x20c1000" + ], + "tickvals": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ] + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import plotly.graph_objects as go\n", + "\n", + "# Sample data structure\n", + "data = [\n", + " {'start': 0x00000000, 'end': 0x00020000, 'name': 'BootROM'},\n", + " {'start': 0x000002c0, 'name': 'BL1 boot entry point'},\n", + " {'start': 0x000064e0, 'name': 'Boot USB function'},\n", + " {'start': 0x00012848, 'name': 'bootrom authentication function'},\n", + " {'start': 0x00019310, 'name': 'BL1 boot function'},\n", + " {'start': 0x02069000, 'name': 'First debugger location'},\n", + " {'end': 0x02070000, 'name': 'End of memory stack'},\n", + " {'start': 0x02021578, 'name': 'Event buffer pointer'},\n", + " {'start': 0x02020f60, 'name': 'Boot USB return address'},\n", + " {'start': 0x02021800, 'name': 'BL1 pointer'},\n", + " {'start': 0x020c0000, 'name': 'Frederic Destination pointer'},\n", + "]\n", + "\n", + "# _evtbuf_ptr: .dword 0x02021578\n", + "# _boot_usb_ra: .dword 0x02020f60\n", + "# _bl1_ptr: .dword 0x02021800\n", + "# _original_ra: .dword 0x00007c68\n", + "# _boot_usb: .dword 0x000064e0\n", + "# _dst_ptr: .dword 0x020c0000\n", + "# _auth_bl1: .dword 0x00012848\n", + "# _jmp_bl1: .dword 0x000002c0\n", + "\n", + "# If there is no end, set it to start + 0x1000\n", + "for d in data:\n", + " if 'end' not in d:\n", + " d['end'] = d['start'] + 0x1000\n", + "\n", + "# If there is no start, set it to end - 0x1000\n", + "for d in data:\n", + " if 'start' not in d:\n", + " d['start'] = d['end'] - 0x1000\n", + "\n", + "# Sort the data by start\n", + "data = sorted(data, key=lambda x: x['start'])\n", + "\n", + "import random\n", + "\n", + "def random_color():\n", + " return f'#{random.randint(0, 0xFFFFFF):06x}'\n", + "\n", + "# Create a square for each index\n", + "fig = go.Figure()\n", + "for i, d in enumerate(data):\n", + " fig.add_shape(\n", + " type=\"rect\",\n", + " x0=0,\n", + " y0=i,\n", + " x1=0 + 1,\n", + " y1=i+1,\n", + " line=dict(width=2),\n", + " fillcolor=random_color(),\n", + " opacity=0.5,\n", + " layer=\"below\"\n", + " )\n", + "\n", + " fig.add_trace(go.Scatter\n", + " (\n", + " x=[0.5],\n", + " y=[i+ 0.5],\n", + " text=d['name'],\n", + " mode=\"text\",\n", + " textposition=\"middle center\"\n", + " ))\n", + "\n", + "fig.update_layout(\n", + " width=800,\n", + " height=1200,\n", + " autosize=True,\n", + " margin=dict(l=200, r=20, t=20, b=20)\n", + ")\n", + "\n", + "fig.update_xaxes(\n", + " range=[0, 1],\n", + " tickvals=[0, 1],\n", + ")\n", + "\n", + "labels = [hex(value) for d in data for value in (d.get('start'), d['end']) if 'end' in d]\n", + "\n", + "# If label is not the first in labels or the last entry, merge the label with the next label\n", + "labelset = []\n", + "for i in range(0, len(labels), 2):\n", + " if i == 0:\n", + " labelset.append(labels[i])\n", + " elif i == len(labels) - 1:\n", + " labelset.append(labels[i])\n", + " else:\n", + " labelset.append(f\"{labels[i]} \\n {labels[i+1]}\")\n", + "labelset.append(labels[-1])\n", + "\n", + "fig.update_yaxes(\n", + " tickvals=[i for i in range(len(data)+1)], \n", + " ticktext=labelset\n", + ")\n", + "\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['0x0',\n", + " '0x2c0 - 0x12c0',\n", + " '0x12848 - 0x13848',\n", + " '0x19310 - 0x1a310',\n", + " '0x2069000 - 0x206a000',\n", + " '0x206f000 - 0x2070000']" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0x2070000'" + ] + }, + "execution_count": 115, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labels[-1]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/documentation/source/conf.py b/documentation/source/conf.py index 6238d8d..8078cce 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -23,6 +23,8 @@ extensions = [ 'myst_parser', templates_path = ['_templates'] exclude_patterns = [] +# Ignore +exclude_patterns = ['_ignore'] # select the theme html_theme = 'sphinx_wagtail_theme' diff --git a/requirements.txt b/requirements.txt index 9f5804c..67292be 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 \ No newline at end of file diff --git a/source/exploit/exploit.py b/source/exploit/exploit.py index 133b76f..d351f59 100644 --- a/source/exploit/exploit.py +++ b/source/exploit/exploit.py @@ -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)