From d407c17c0f68dd7ec6490c32e3191556098795fa Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 14:38:53 -0500 Subject: [PATCH 01/10] implement basics of async execution (still need to test) --- c8_remote/include/payload.h | 7 +- c8_remote/src/payload.c | 275 ++++++++++++++++++++++++++---------- 2 files changed, 205 insertions(+), 77 deletions(-) diff --git a/c8_remote/include/payload.h b/c8_remote/include/payload.h index c07d74c..0fcb68e 100644 --- a/c8_remote/include/payload.h +++ b/c8_remote/include/payload.h @@ -23,10 +23,13 @@ typedef unsigned long long DEV_PTR_T; int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc); int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p); -struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...); -DEV_PTR_T execute_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...); DEV_PTR_T get_payload_address(struct pwned_device *dev, PAYLOAD_T p); +struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...); +DEV_PTR_T setup_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...); +int run_payload_async(struct pwned_device *dev, PAYLOAD_T p); +int kill_payload_async(struct pwned_device *dev, PAYLOAD_T p, DEV_PTR_T buf_addr); + DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len); int uninstall_data(struct pwned_device *dev, DEV_PTR_T ptr); diff --git a/c8_remote/src/payload.c b/c8_remote/src/payload.c index ee7c526..5b534cf 100644 --- a/c8_remote/src/payload.c +++ b/c8_remote/src/payload.c @@ -17,6 +17,8 @@ struct payload int len; DEV_PTR_T install_base; + DEV_PTR_T async_base; + struct payload *next; struct payload *prev; }; @@ -66,6 +68,7 @@ struct payload *get_payload(PAYLOAD_T p) res->len = len; res->data = pl; res->install_base = DEV_PTR_NULL; + res->async_base = DEV_PTR_NULL; res->next = NULL; res->prev = NULL; @@ -77,28 +80,6 @@ void free_payload(struct payload *p) free(p); } -DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len) -{ - checkm8_debug_indent("get_address(dev = %p, loc = %i, len = %i)\n", dev, l, len); - DEV_PTR_T retval; - unsigned long long malloc_args[2] = {ADDR_DEV_MALLOC, (unsigned long long) len}; - - struct dev_cmd_resp *resp = dev_exec(dev, 0, 2, malloc_args); - if(IS_CHECKM8_FAIL(resp->ret)) - { - free_dev_cmd_resp(resp); - checkm8_debug_indent("\tfailed to malloc an address\n"); - return DEV_PTR_NULL; - } - - retval = resp->retval; - free_dev_cmd_resp(resp); - - checkm8_debug_indent("\tgot address %llX\n", retval); - return retval; -} - - struct payload *dev_retrieve_payload(struct pwned_device *dev, PAYLOAD_T p) { struct payload *curr; @@ -145,6 +126,43 @@ int *dev_unlink_payload(struct pwned_device *dev, struct payload *pl) } } +DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len) +{ + checkm8_debug_indent("get_address(dev = %p, loc = %i, len = %i)\n", dev, l, len); + DEV_PTR_T retval; + unsigned long long malloc_args[2] = {ADDR_DEV_MALLOC, (unsigned long long) len}; + + struct dev_cmd_resp *resp = dev_exec(dev, 0, 2, malloc_args); + if(IS_CHECKM8_FAIL(resp->ret)) + { + free_dev_cmd_resp(resp); + checkm8_debug_indent("\tfailed to malloc an address\n"); + return DEV_PTR_NULL; + } + + retval = resp->retval; + free_dev_cmd_resp(resp); + + checkm8_debug_indent("\tgot address %llX\n", retval); + return retval; +} + +int free_address(struct pwned_device *dev, LOCATION_T l, DEV_PTR_T ptr) +{ + struct dev_cmd_resp *resp; + unsigned long long free_args[2] = {ADDR_DEV_FREE, ptr}; + + resp = dev_exec(dev, 0, 2, free_args); + if(IS_CHECKM8_FAIL(resp->ret)) + { + free_dev_cmd_resp(resp); + checkm8_debug_indent("\tfailed to free allocated payload memory\n"); + return CHECKM8_FAIL_XFER; + } + + free_dev_cmd_resp(resp); + return CHECKM8_SUCCESS; +} int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc) { @@ -178,8 +196,6 @@ int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc) int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p) { checkm8_debug_indent("uninstall payload(dev = %p, p = %i)\n", dev, p); - unsigned long long free_args[2]; - struct dev_cmd_resp *resp; struct payload *pl = dev_retrieve_payload(dev, p); if(pl == NULL) @@ -188,14 +204,9 @@ int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p) return CHECKM8_FAIL_INVARGS; } - free_args[0] = ADDR_DEV_FREE; - free_args[1] = pl->install_base; - - resp = dev_exec(dev, 0, 2, free_args); - if(IS_CHECKM8_FAIL(resp->ret)) + if(IS_CHECKM8_FAIL(free_address(dev, SRAM, pl->install_base))) { - free_dev_cmd_resp(resp); - checkm8_debug_indent("\tfailed to free allocated payload memory\n"); + checkm8_debug_indent("\tfailed to free memory used by payload!\n"); return CHECKM8_FAIL_XFER; } @@ -217,47 +228,6 @@ DEV_PTR_T get_payload_address(struct pwned_device *dev, PAYLOAD_T p) } } - -DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len) -{ - checkm8_debug_indent("install_data(dev = %p, loc = %i, data = %p, len = %i)\n", dev, loc, data, len); - struct dev_cmd_resp *resp; - DEV_PTR_T addr = get_address(dev, loc, len); - - if(addr == -1) - { - checkm8_debug_indent("\tfailed to get an address\n"); - return DEV_PTR_NULL; - } - - checkm8_debug_indent("\twriting data to address %X\n", addr); - resp = dev_write_memory(dev, addr, data, len); - if(IS_CHECKM8_FAIL(resp->ret)) - { - checkm8_debug_indent("\tfailed to write data\n"); - return -1; - } - - free_dev_cmd_resp(resp); - return addr; -} - -int uninstall_data(struct pwned_device *dev, DEV_PTR_T addr) -{ - checkm8_debug_indent("uninstall_data(dev = %p, addr = %X)\n", dev, addr); - struct dev_cmd_resp *resp; - unsigned long long free_args[2] = {ADDR_DEV_FREE, addr}; - - resp = dev_exec(dev, 0, 2, free_args); - if(IS_CHECKM8_FAIL(resp->ret)) - { - checkm8_debug_indent("failed to free memory at %x\n", addr); - return CHECKM8_FAIL_XFER; - } - - return CHECKM8_SUCCESS; -} - struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...) { checkm8_debug_indent("execute_payload(dev = %p, p = %i, response_len = %i, nargs = %i, ...)\n", @@ -290,13 +260,15 @@ struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int return dev_exec(dev, response_len, nargs + 1, args); } -unsigned long long execute_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...) +unsigned long long setup_payload_async(struct pwned_device *dev, PAYLOAD_T p, int bufsize, int nargs, ...) { - checkm8_debug_indent("execute_payload_async(dev = %p, p = %i, bufsize = %i, nargs = %i, ...)\n", + checkm8_debug_indent("setup_payload_async(dev = %p, p = %i, bufsize = %i, nargs = %i, ...)\n", dev, p, bufsize, bufsize, nargs); int i; struct dev_cmd_resp *resp; struct payload *pl; + DEV_PTR_T buf_addr; + unsigned long long buf_args[nargs], task_args[5]; if((pl = dev_retrieve_payload(dev, p)) == NULL) { @@ -304,13 +276,166 @@ unsigned long long execute_payload_async(struct pwned_device *dev, PAYLOAD_T p, return DEV_PTR_NULL; } + checkm8_debug_indent("\tadjusting buffer size (if necessary)\n"); if(bufsize < nargs * sizeof(unsigned long long)) { checkm8_debug_indent("\texpanding buffer to fit (at least) provided arguments\n"); bufsize = nargs * sizeof(unsigned long long); } - + buf_addr = get_address(dev, SRAM, bufsize); + if(buf_addr == DEV_PTR_NULL) + { + checkm8_debug_indent("\tfailed to get a shared buffer for the payload\n"); + return DEV_PTR_NULL; + } + + va_list arg_list; + va_start(arg_list, nargs); + for(i = 0; i < nargs; i++) + { + buf_args[i] = va_arg(arg_list, unsigned long long); + checkm8_debug_indent("\textracted arg %lx\n", buf_args[i]); + } + va_end(arg_list); + + resp = dev_write_memory(dev, buf_addr, (unsigned char *) buf_args, nargs * sizeof(unsigned long long)); + if(IS_CHECKM8_FAIL(resp->ret)) + { + checkm8_debug_indent("\tfailed to write args to shared buffer\n"); + if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr))) + { + checkm8_debug_indent("\talso failed to free buffer (something is really wrong)\n"); + } + + free_dev_cmd_resp(resp); + return DEV_PTR_NULL; + } + + task_args[0] = ADDR_TASK_NEW; + task_args[1] = 0; // todo: name pointer + task_args[2] = pl->install_base; + task_args[3] = buf_addr; + task_args[4] = 0x4000; + + resp = dev_exec(dev, 0, 4, task_args); + if(IS_CHECKM8_FAIL(resp->ret)) + { + checkm8_debug_indent("\tfailed to create a new task\n"); + if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr))) + { + checkm8_debug_indent("\talso failed to free buffer (something is really wrong)\n"); + } + + free_dev_cmd_resp(resp); + return DEV_PTR_NULL; + } + + pl->async_base = resp->retval; + free_dev_cmd_resp(resp); + return buf_addr; +} + +int run_payload_async(struct pwned_device *dev, PAYLOAD_T p) +{ + checkm8_debug_indent("run_payload_async(dev = %p, payload = %i)\n", dev, p); + struct payload *pl; + struct dev_cmd_resp *resp; + unsigned long long args[2]; + int retval; + + if((pl = dev_retrieve_payload(dev, p)) == NULL) + { + checkm8_debug_indent("\tpayload is not installed!\n"); + return CHECKM8_FAIL_NOINST; + } + + if(pl->async_base == DEV_PTR_NULL) + { + checkm8_debug_indent("\tasync payload is not set up correctly!\n"); + return CHECKM8_FAIL_NOINST; + } + + args[0] = ADDR_TASK_RUN; + args[1] = pl->async_base; + + resp = dev_exec(dev, 0, 2, args); + retval = resp->ret; + free_dev_cmd_resp(resp); + + return retval; +} + +int kill_payload_async(struct pwned_device *dev, PAYLOAD_T p, DEV_PTR_T buf_addr) +{ + checkm8_debug_indent("kill_payload_async(dev = %p, p = %i, buf_addr = %llx)\n", dev, p, buf_addr); + struct payload *pl; + struct dev_cmd_resp *resp; + unsigned long long args[2]; + + if((pl = dev_retrieve_payload(dev, p)) == NULL) + { + checkm8_debug_indent("\tpayload is not installed\n"); + return CHECKM8_FAIL_NOINST; + } + + if(pl->async_base == DEV_PTR_NULL) + { + checkm8_debug_indent("\tasync payload is not set up correctly\n"); + return CHECKM8_FAIL_NOINST; + } + + args[0] = ADDR_TASK_FREE; + args[1] = pl->async_base; + + resp = dev_exec(dev, 0, 2, args); + pl->async_base = DEV_PTR_NULL; + + if(IS_CHECKM8_FAIL(resp->ret)) + { + checkm8_debug_indent("\tfailed to kill payload\n"); + free_dev_cmd_resp(resp); + return CHECKM8_FAIL_XFER; + } + + free_dev_cmd_resp(resp); + if(IS_CHECKM8_FAIL(free_address(dev, SRAM, buf_addr))) + { + checkm8_debug_indent("\tfailed to free shared buffer\n"); + return CHECKM8_FAIL_XFER; + } + + return CHECKM8_SUCCESS; +} + +DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len) +{ + checkm8_debug_indent("install_data(dev = %p, loc = %i, data = %p, len = %i)\n", dev, loc, data, len); + struct dev_cmd_resp *resp; + DEV_PTR_T addr = get_address(dev, loc, len); + + if(addr == -1) + { + checkm8_debug_indent("\tfailed to get an address\n"); + return DEV_PTR_NULL; + } + + checkm8_debug_indent("\twriting data to address %X\n", addr); + resp = dev_write_memory(dev, addr, data, len); + if(IS_CHECKM8_FAIL(resp->ret)) + { + checkm8_debug_indent("\tfailed to write data\n"); + return -1; + } + + free_dev_cmd_resp(resp); + return addr; +} + +int uninstall_data(struct pwned_device *dev, DEV_PTR_T addr) +{ + checkm8_debug_indent("uninstall_data(dev = %p, addr = %X)\n", dev, addr); + return free_address(dev, SRAM, addr); } struct dev_cmd_resp *read_gadget(struct pwned_device *dev, DEV_PTR_T addr, int len) From 8b25a00bd4c0b39837933883c716a891f8189f9a Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 15:10:35 -0500 Subject: [PATCH 02/10] synchronous payloads seem to work well --- c8_remote/include/bootrom_addr.h | 1 + c8_remote/lib/payload/payload_entry.c | 3 +- c8_remote/main.c | 11 +++- c8_remote/src/exploit.c | 92 ++++++++++++++++++--------- 4 files changed, 74 insertions(+), 33 deletions(-) diff --git a/c8_remote/include/bootrom_addr.h b/c8_remote/include/bootrom_addr.h index 678e6ce..9150529 100644 --- a/c8_remote/include/bootrom_addr.h +++ b/c8_remote/include/bootrom_addr.h @@ -36,6 +36,7 @@ /* Misc */ #define ADDR_RANDOM_RET 0x10000b924 +#define ADDR_SYNC_ENTRY 0x1800afc84 #define ADDR_DFU_RETVAL (int *) 0x180088ac8 #define ADDR_DFU_STATUS (unsigned char *) 0x180088ac0 diff --git a/c8_remote/lib/payload/payload_entry.c b/c8_remote/lib/payload/payload_entry.c index 09d6e2d..20dc157 100644 --- a/c8_remote/lib/payload/payload_entry.c +++ b/c8_remote/lib/payload/payload_entry.c @@ -1,3 +1,4 @@ +#include "bootrom_addr.h" #include "dev_util.h" extern uint64_t entry_sync(uint64_t *args); @@ -10,7 +11,7 @@ uint64_t _start(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t entry, args[8]; __asm__ volatile ("mov %0, x30" : "=r" (entry)); - if(entry == 0xbea /* todo: correct entry */) + if(entry == ADDR_SYNC_ENTRY /* todo: correct entry */) { args[0] = arg0; args[1] = arg1; diff --git a/c8_remote/main.c b/c8_remote/main.c index 52997f4..ad8e954 100644 --- a/c8_remote/main.c +++ b/c8_remote/main.c @@ -235,6 +235,13 @@ void aes_sw(struct pwned_device *dev) return; } + resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0); + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("failed to execute sync payload\n"); + return; + } + for(i = 0; i < 100; i++) { resp = execute_payload(dev, PAYLOAD_AES_SW, 0, 7, @@ -341,9 +348,7 @@ int main() demote_device(dev); - // usb_task_exit(dev); - - floppysleep(dev); + aes_sw(dev); free_device(dev); } diff --git a/c8_remote/src/exploit.c b/c8_remote/src/exploit.c index 494c5d7..cf2350d 100644 --- a/c8_remote/src/exploit.c +++ b/c8_remote/src/exploit.c @@ -294,6 +294,13 @@ int demote_device(struct pwned_device *dev) { checkm8_debug_indent("demote_device(dev = %p)\n", dev); unsigned int oldval, newval; + int retval; + + if(IS_CHECKM8_FAIL(open_device_session(dev))) + { + checkm8_debug_indent("\tfailed to open a device session\n"); + return CHECKM8_FAIL_XFER; + } struct dev_cmd_resp *resp = dev_read_memory(dev, DEMOTE_REG, 4); if(IS_CHECKM8_FAIL(resp->ret)) @@ -305,46 +312,73 @@ int demote_device(struct pwned_device *dev) oldval = *((unsigned int *) resp->data); free_dev_cmd_resp(resp); - if(oldval & 1u) + if(!(oldval & 1u)) { - oldval &= 0xFFFFFFFE; + checkm8_debug_block("\tdevice already demoted\n"); + if(IS_CHECKM8_FAIL(close_device_session(dev))) + { + checkm8_debug_indent("\tfailed to close device session\n"); + return CHECKM8_FAIL_XFER; + } - checkm8_debug_indent("\tattempting to demote device\n"); - resp = dev_write_memory(dev, DEMOTE_REG, (unsigned char *) &oldval, 4); + return CHECKM8_SUCCESS; + } + + oldval &= 0xFFFFFFFE; + + checkm8_debug_indent("\tattempting to demote device\n"); + resp = dev_write_memory(dev, DEMOTE_REG, (unsigned char *) &oldval, 4); + free_dev_cmd_resp(resp); + if(IS_CHECKM8_FAIL(resp->ret)) + { + checkm8_debug_block("\tfailed to write to demotion reg\n"); + + if(IS_CHECKM8_FAIL(close_device_session(dev))) + { + checkm8_debug_indent("\tfailed to close device session\n"); + return CHECKM8_FAIL_XFER; + } + + return CHECKM8_FAIL_INVARGS; + } + + // verify + resp = dev_read_memory(dev, DEMOTE_REG, 4); + if(IS_CHECKM8_FAIL(resp->ret)) + { free_dev_cmd_resp(resp); - if(IS_CHECKM8_FAIL(resp->ret)) + checkm8_debug_block("\tfailed to verify demotion reg\n"); + + if(IS_CHECKM8_FAIL(close_device_session(dev))) { - checkm8_debug_block("\tfailed to write to demotion reg\n"); - return CHECKM8_FAIL_INVARGS; + checkm8_debug_indent("\tfailed to close device session\n"); + return CHECKM8_FAIL_XFER; } - // verify - resp = dev_read_memory(dev, DEMOTE_REG, 4); - if(IS_CHECKM8_FAIL(resp->ret)) - { - free_dev_cmd_resp(resp); - checkm8_debug_block("\tfailed to verify demotion reg\n"); - return CHECKM8_FAIL_INVARGS; - } + return CHECKM8_FAIL_INVARGS; + } - newval = *((unsigned int *) resp->data); - free_dev_cmd_resp(resp); - if(oldval == newval) - { - checkm8_debug_block("\tdemotion success!\n"); - return CHECKM8_SUCCESS; - } - else - { - checkm8_debug_block("\tdemotion register did not change!\n"); - return CHECKM8_FAIL_INVARGS; - } + newval = *((unsigned int *) resp->data); + free_dev_cmd_resp(resp); + + if(oldval == newval) + { + checkm8_debug_block("\tdemotion success!\n"); + retval = CHECKM8_SUCCESS; } else { - checkm8_debug_block("\tdevice already demoted\n"); - return CHECKM8_SUCCESS; + checkm8_debug_block("\tdemotion register did not change!\n"); + retval = CHECKM8_FAIL_INVARGS; } + + if(IS_CHECKM8_FAIL(close_device_session(dev))) + { + checkm8_debug_indent("\tfailed to close device session\n"); + return CHECKM8_FAIL_XFER; + } + + return retval; } void free_device(struct pwned_device *dev) From 823c914e84a60778908fafca6357cf5c96e7542d Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 15:34:47 -0500 Subject: [PATCH 03/10] better data housekeeping since we're using the on-device heap now... don't want to leave a mess --- c8_remote/include/checkm8.h | 3 +- c8_remote/include/payload.h | 2 + c8_remote/main.c | 37 +++++------ c8_remote/src/payload.c | 128 ++++++++++++++++++++++++++++++++---- 4 files changed, 135 insertions(+), 35 deletions(-) diff --git a/c8_remote/include/checkm8.h b/c8_remote/include/checkm8.h index bce3103..70727d0 100644 --- a/c8_remote/include/checkm8.h +++ b/c8_remote/include/checkm8.h @@ -36,7 +36,8 @@ struct pwned_device unsigned int idVendor; unsigned int idProduct; - struct payload *installed; + struct payload *inst_pl; + struct data *inst_data; #ifdef WITH_ARDUINO int ard_fd; diff --git a/c8_remote/include/payload.h b/c8_remote/include/payload.h index 0fcb68e..55fa8c8 100644 --- a/c8_remote/include/payload.h +++ b/c8_remote/include/payload.h @@ -23,6 +23,7 @@ typedef unsigned long long DEV_PTR_T; int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc); int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p); +int uninstall_all_payloads(struct pwned_device *dev); DEV_PTR_T get_payload_address(struct pwned_device *dev, PAYLOAD_T p); struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int response_len, int nargs, ...); @@ -32,6 +33,7 @@ int kill_payload_async(struct pwned_device *dev, PAYLOAD_T p, DEV_PTR_T buf_addr DEV_PTR_T install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len); int uninstall_data(struct pwned_device *dev, DEV_PTR_T ptr); +int uninstall_all_data(struct pwned_device *dev); struct dev_cmd_resp *read_gadget(struct pwned_device *dev, DEV_PTR_T addr, int len); struct dev_cmd_resp *write_gadget(struct pwned_device *dev, DEV_PTR_T addr, unsigned char *data, int len); diff --git a/c8_remote/main.c b/c8_remote/main.c index ad8e954..2b1db3b 100644 --- a/c8_remote/main.c +++ b/c8_remote/main.c @@ -44,62 +44,55 @@ void checkm8_debug_block(const char *format, ...) #endif } -int floppysleep(struct pwned_device *dev) +void floppysleep(struct pwned_device *dev) { struct dev_cmd_resp *resp; if(IS_CHECKM8_FAIL(open_device_session(dev))) { printf("failed to open device session\n"); - return -1; + return; } if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM))) { printf("failed to install sync payload\n"); - return -1; + return; } if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_FLOPPYSLEEP, SRAM))) { printf("failed to install task sleep payload\n"); - return -1; + return; } float init_a = -7.504355E-39f; - unsigned long long init_a_ptr = install_data(dev, SRAM, (unsigned char *) &init_a, sizeof(float)); + DEV_PTR_T init_a_ptr = install_data(dev, SRAM, (unsigned char *) &init_a, sizeof(float)); if(init_a_ptr == DEV_PTR_NULL) { printf("failed to write initial data\n"); - return -1; + return; } resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0); if(IS_CHECKM8_FAIL(resp->ret)) { printf("failed to execute bootstrap\n"); - return -1; + return; } free_dev_cmd_resp(resp); - while(1) + resp = execute_payload(dev, PAYLOAD_FLOPPYSLEEP, 0, 1, init_a_ptr); + if(IS_CHECKM8_FAIL(resp->ret)) { - resp = execute_payload(dev, PAYLOAD_FLOPPYSLEEP, 0, 1, init_a_ptr); - if(IS_CHECKM8_FAIL(resp->ret)) - { - printf("failed to execute flopsleep payload\n"); - return -1; - } - - printf("retval is %08lli\n", resp->retval); - free_dev_cmd_resp(resp); - - usleep(2000000); + printf("failed to execute flopsleep payload\n"); + return; } + printf("retval is %08lli\n", resp->retval); + free_dev_cmd_resp(resp); close_device_session(dev); - free_device(dev); } void aes_sw(struct pwned_device *dev) @@ -347,8 +340,10 @@ int main() } demote_device(dev); + floppysleep(dev); - aes_sw(dev); + uninstall_all_payloads(dev); + uninstall_all_data(dev); free_device(dev); } diff --git a/c8_remote/src/payload.c b/c8_remote/src/payload.c index 5b534cf..1d9623f 100644 --- a/c8_remote/src/payload.c +++ b/c8_remote/src/payload.c @@ -23,6 +23,15 @@ struct payload struct payload *prev; }; +struct data +{ + DEV_PTR_T addr; + int len; + + struct data *next; + struct data *prev; +}; + struct payload *get_payload(PAYLOAD_T p) { struct payload *res; @@ -75,15 +84,10 @@ struct payload *get_payload(PAYLOAD_T p) return res; } -void free_payload(struct payload *p) -{ - free(p); -} - struct payload *dev_retrieve_payload(struct pwned_device *dev, PAYLOAD_T p) { struct payload *curr; - for(curr = dev->installed; curr != NULL; curr = curr->next) + for(curr = dev->inst_pl; curr != NULL; curr = curr->next) { if(curr->type == p) return curr; } @@ -94,14 +98,14 @@ struct payload *dev_retrieve_payload(struct pwned_device *dev, PAYLOAD_T p) int dev_link_payload(struct pwned_device *dev, struct payload *pl) { struct payload *curr; - if(dev->installed == NULL) + if(dev->inst_pl == NULL) { - dev->installed = pl; + dev->inst_pl = pl; return CHECKM8_SUCCESS; } else { - for(curr = dev->installed; curr->next != NULL; curr = curr->next); + for(curr = dev->inst_pl; curr->next != NULL; curr = curr->next); curr->next = pl; pl->prev = curr; @@ -109,11 +113,11 @@ int dev_link_payload(struct pwned_device *dev, struct payload *pl) } } -int *dev_unlink_payload(struct pwned_device *dev, struct payload *pl) +int dev_unlink_payload(struct pwned_device *dev, struct payload *pl) { - if(dev->installed == pl) + if(dev->inst_pl == pl) { - dev->installed = pl->next; + dev->inst_pl = pl->next; return CHECKM8_SUCCESS; } else @@ -126,11 +130,58 @@ int *dev_unlink_payload(struct pwned_device *dev, struct payload *pl) } } +struct data *dev_retrieve_data(struct pwned_device *dev, DEV_PTR_T addr) +{ + struct data *curr; + for(curr = dev->inst_data; curr != NULL; curr = curr->next) + { + if(curr->addr == addr) return curr; + } + + return NULL; +} + +int dev_link_data(struct pwned_device *dev, struct data *data) +{ + struct data *curr; + if(dev->inst_data == NULL) + { + dev->inst_data = data; + return CHECKM8_SUCCESS; + } + else + { + for(curr = dev->inst_data; curr->next != NULL; curr = curr->next); + + curr->next = data; + data->prev = curr; + return CHECKM8_SUCCESS; + } +} + +int dev_unlink_data(struct pwned_device *dev, struct data *data) +{ + if(dev->inst_data == data) + { + dev->inst_data = data->next; + return CHECKM8_SUCCESS; + } + else + { + data->prev->next = data->next; + if(data->next != NULL) + data->next->prev = data->prev; + + return CHECKM8_SUCCESS; + } +} + DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len) { checkm8_debug_indent("get_address(dev = %p, loc = %i, len = %i)\n", dev, l, len); DEV_PTR_T retval; unsigned long long malloc_args[2] = {ADDR_DEV_MALLOC, (unsigned long long) len}; + struct data *new_entry; struct dev_cmd_resp *resp = dev_exec(dev, 0, 2, malloc_args); if(IS_CHECKM8_FAIL(resp->ret)) @@ -143,6 +194,11 @@ DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len) retval = resp->retval; free_dev_cmd_resp(resp); + new_entry = malloc(sizeof(struct data)); + new_entry->addr = retval; + new_entry->len = len; + dev_link_data(dev, new_entry); + checkm8_debug_indent("\tgot address %llX\n", retval); return retval; } @@ -150,8 +206,16 @@ DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len) int free_address(struct pwned_device *dev, LOCATION_T l, DEV_PTR_T ptr) { struct dev_cmd_resp *resp; + struct data *entry; unsigned long long free_args[2] = {ADDR_DEV_FREE, ptr}; + entry = dev_retrieve_data(dev, ptr); + if(entry == NULL) + { + checkm8_debug_indent("\tthis pointer was not allocated through the payload interface, not freeing\n"); + return CHECKM8_FAIL_NOINST; + } + resp = dev_exec(dev, 0, 2, free_args); if(IS_CHECKM8_FAIL(resp->ret)) { @@ -161,6 +225,9 @@ int free_address(struct pwned_device *dev, LOCATION_T l, DEV_PTR_T ptr) } free_dev_cmd_resp(resp); + dev_unlink_data(dev, entry); + free(entry); + return CHECKM8_SUCCESS; } @@ -211,7 +278,24 @@ int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p) } dev_unlink_payload(dev, pl); - free_payload(pl); + free(pl); + return CHECKM8_SUCCESS; +} + +int uninstall_all_payloads(struct pwned_device *dev) +{ + checkm8_debug_indent("uninstall_all_payloads(dev = %p)\n"); + int ret; + while(dev->inst_pl != NULL) + { + ret = uninstall_payload(dev, dev->inst_pl->type); + if(IS_CHECKM8_FAIL(ret)) + { + checkm8_debug_indent("\terror while uninstalling\n"); + return ret; + } + } + return CHECKM8_SUCCESS; } @@ -438,6 +522,24 @@ int uninstall_data(struct pwned_device *dev, DEV_PTR_T addr) return free_address(dev, SRAM, addr); } +int uninstall_all_data(struct pwned_device *dev) +{ + checkm8_debug_indent("uninstall_all_data(dev = %p)\n", dev); + int retval; + + while(dev->inst_data != NULL) + { + retval = uninstall_data(dev, dev->inst_data->addr); + if(IS_CHECKM8_FAIL(retval)) + { + checkm8_debug_indent("\terror while uninstalling data\n"); + return retval; + } + } + + return CHECKM8_SUCCESS; +} + struct dev_cmd_resp *read_gadget(struct pwned_device *dev, DEV_PTR_T addr, int len) { checkm8_debug_indent("read_gadget(dev = %p, addr = %lx, len = %i)\n", dev, addr, len); From 33f3ab9a0d90af8b20a706d6d210ac0aaec3deab Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 15:41:31 -0500 Subject: [PATCH 04/10] fix segfault --- c8_remote/src/payload.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/c8_remote/src/payload.c b/c8_remote/src/payload.c index 1d9623f..506f272 100644 --- a/c8_remote/src/payload.c +++ b/c8_remote/src/payload.c @@ -197,6 +197,8 @@ DEV_PTR_T get_address(struct pwned_device *dev, LOCATION_T l, int len) new_entry = malloc(sizeof(struct data)); new_entry->addr = retval; new_entry->len = len; + new_entry->prev = NULL; + new_entry->next = NULL; dev_link_data(dev, new_entry); checkm8_debug_indent("\tgot address %llX\n", retval); From a6ddec511a4b02a94f6239393ca9d39ea597995c Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 20:51:04 -0500 Subject: [PATCH 05/10] improved generic payload entry point --- c8_remote/lib/payload/CMakeLists.txt | 12 +++++---- c8_remote/lib/payload/payload_entry.S | 17 ++++++++++++ c8_remote/lib/payload/payload_entry.c | 32 ++++++----------------- c8_remote/lib/payload/src/aes_busy.c | 14 ++-------- c8_remote/lib/payload/src/aes_sw.c | 14 +++------- c8_remote/lib/payload/src/exit_usb_task.c | 8 ++---- c8_remote/lib/payload/src/floppysleep.c | 8 +++--- c8_remote/lib/payload/src/sync.c | 9 ++----- 8 files changed, 46 insertions(+), 68 deletions(-) create mode 100644 c8_remote/lib/payload/payload_entry.S diff --git a/c8_remote/lib/payload/CMakeLists.txt b/c8_remote/lib/payload/CMakeLists.txt index e3ca1d1..e032c13 100644 --- a/c8_remote/lib/payload/CMakeLists.txt +++ b/c8_remote/lib/payload/CMakeLists.txt @@ -20,12 +20,14 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) foreach(NAME ${PL_NAMES}) if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.S) - add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/payload_entry.c - ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.c - ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.S) + add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/payload_entry.S + ${CMAKE_CURRENT_LIST_DIR}/payload_entry.c + ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.c + ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.S) else() - add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/payload_entry.c - ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.c) + add_executable(payload_${NAME} ${CMAKE_CURRENT_LIST_DIR}/payload_entry.S + ${CMAKE_CURRENT_LIST_DIR}/payload_entry.c + ${CMAKE_CURRENT_LIST_DIR}/src/${NAME}.c) endif() add_custom_command(TARGET payload_${NAME} POST_BUILD diff --git a/c8_remote/lib/payload/payload_entry.S b/c8_remote/lib/payload/payload_entry.S new file mode 100644 index 0000000..8b56f58 --- /dev/null +++ b/c8_remote/lib/payload/payload_entry.S @@ -0,0 +1,17 @@ +.extern entry_sync +.extern entry_async +.extern load_sync_entry + +.global _start +.section .text +_start: + mov x10, x30 + bl load_sync_entry + mov x30, x10 + + # if we came from the synchronous entry point, branch to entry_sync + cmp x9, x10 + b.eq entry_sync + + # else branch to the payload's async entry points + b entry_async diff --git a/c8_remote/lib/payload/payload_entry.c b/c8_remote/lib/payload/payload_entry.c index 20dc157..cd9c2f1 100644 --- a/c8_remote/lib/payload/payload_entry.c +++ b/c8_remote/lib/payload/payload_entry.c @@ -1,29 +1,13 @@ -#include "bootrom_addr.h" #include "dev_util.h" +#include "bootrom_addr.h" -extern uint64_t entry_sync(uint64_t *args); -extern uint64_t entry_async(uint64_t *base); - -TEXT_SECTION -uint64_t _start(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, - uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7) +PAYLOAD_SECTION +void load_sync_entry() { - uint64_t entry, args[8]; - __asm__ volatile ("mov %0, x30" : "=r" (entry)); + uint64_t addr = ADDR_SYNC_ENTRY; + __asm__ volatile("mov x9, %0" :: "i" (addr & 0xFFFFu)); + __asm__ volatile("movk x9, %0, LSL #16" :: "i" ((addr & 0xFFFF0000u) >> 16u)); + __asm__ volatile("movk x9, %0, LSL #32" :: "i" ((addr & 0xFFFF00000000u) >> 32u)); + __asm__ volatile("movk x9, %0, LSL #48" :: "i" ((addr & 0xFFFF000000000000u) >> 48u)); - if(entry == ADDR_SYNC_ENTRY /* todo: correct entry */) - { - args[0] = arg0; - args[1] = arg1; - args[2] = arg2; - args[3] = arg3; - args[4] = arg4; - args[5] = arg5; - args[6] = arg6; - args[7] = arg7; - - return entry_sync(args); - } - else - return entry_async((uint64_t *) arg0); } \ No newline at end of file diff --git a/c8_remote/lib/payload/src/aes_busy.c b/c8_remote/lib/payload/src/aes_busy.c index 2d63661..fc354d3 100644 --- a/c8_remote/lib/payload/src/aes_busy.c +++ b/c8_remote/lib/payload/src/aes_busy.c @@ -1,16 +1,11 @@ #include "bootrom_func.h" PAYLOAD_SECTION -uint64_t entry_sync(uint64_t *args) +void entry_sync(uint8_t *src, uint8_t *dst, uint8_t *key, int32_t rep) { int i, j; unsigned char src_data[16]; - unsigned char *src = (unsigned char *) args[0]; - unsigned char *dst = (unsigned char *) args[1]; - unsigned char *key = (unsigned char *) args[2]; - int rep = (int) args[3]; - for(j = 0; j < 16; j++) { src_data[j] = src[j]; @@ -21,12 +16,7 @@ uint64_t entry_sync(uint64_t *args) if(i % 2 == 0) hardware_aes(16, src_data, dst, 16, 0, key, 0); else hardware_aes(16, dst, src_data, 16, 0, key, 0); } - - return 0; } PAYLOAD_SECTION -uint64_t entry_async(uint64_t *base) -{ - return 0; -} \ No newline at end of file +void entry_async(uint64_t *base){} \ No newline at end of file diff --git a/c8_remote/lib/payload/src/aes_sw.c b/c8_remote/lib/payload/src/aes_sw.c index eda50e5..1636122 100644 --- a/c8_remote/lib/payload/src/aes_sw.c +++ b/c8_remote/lib/payload/src/aes_sw.c @@ -141,18 +141,12 @@ void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len, unsigned char } PAYLOAD_SECTION -uint64_t entry_sync(uint64_t *args) +uint64_t entry_sync(unsigned char *msg, unsigned int msg_len, unsigned char key[16], + unsigned char sbox[16][16], unsigned char rc_lookup[11], + unsigned char mul2[256], unsigned char mul3[256]) { unsigned long long start = 0, end = 0; - unsigned char *msg = (unsigned char *) args[0]; - unsigned int msg_len = (unsigned int) args[1]; - unsigned char *key = (unsigned char *) args[2]; - unsigned char *sbox = (unsigned char *) args[3]; - unsigned char *rc_lookup = (unsigned char *) args[4]; - unsigned char *mul2 = (unsigned char *) args[5]; - unsigned char *mul3 = (unsigned char *) args[6]; - __asm__ volatile ("mrs %0, cntpct_el0" : "=r" (start)); aes128_encrypt_ecb(msg, msg_len, key, sbox, rc_lookup, mul2, mul3); __asm__ volatile ("mrs %0, cntpct_el0" : "=r" (end)); @@ -167,7 +161,7 @@ uint64_t entry_sync(uint64_t *args) } PAYLOAD_SECTION -uint64_t entry_async(uint64_t *base) +void entry_async(uint64_t *base) { unsigned long long start = 0, end = 0; diff --git a/c8_remote/lib/payload/src/exit_usb_task.c b/c8_remote/lib/payload/src/exit_usb_task.c index 59f19f3..95d23b8 100644 --- a/c8_remote/lib/payload/src/exit_usb_task.c +++ b/c8_remote/lib/payload/src/exit_usb_task.c @@ -39,7 +39,7 @@ void fix_heap() check_all_chksums(); } -extern uint64_t entry_sync(uint64_t *args) +void entry_sync() { fix_heap(); @@ -47,10 +47,6 @@ extern uint64_t entry_sync(uint64_t *args) *(ADDR_DFU_STATUS) = 1; event_notify(ADDR_DFU_EVENT); - return 0; } -extern uint64_t entry_async(uint64_t *base) -{ - return 0; -} \ No newline at end of file +void entry_async(uint64_t *base){} \ No newline at end of file diff --git a/c8_remote/lib/payload/src/floppysleep.c b/c8_remote/lib/payload/src/floppysleep.c index 2b19e9c..02f83fe 100644 --- a/c8_remote/lib/payload/src/floppysleep.c +++ b/c8_remote/lib/payload/src/floppysleep.c @@ -39,13 +39,13 @@ uint64_t floppysleep_iteration(float *init) } PAYLOAD_SECTION -uint64_t entry_sync(uint64_t *args) +uint64_t entry_sync(float *init_ptr) { - return floppysleep_iteration((float *) args[0]); + return floppysleep_iteration(init_ptr); } PAYLOAD_SECTION -uint64_t entry_async(uint64_t *args) +void entry_async(uint64_t *args) { float *init_ptr = (float *) args[0]; args[0] = 0; @@ -54,7 +54,7 @@ uint64_t entry_async(uint64_t *args) { floppysleep_iteration(init_ptr); + if(args[0] % 1000000 == 0) task_resched(); args[0]++; - if(args[0] % 100000 == 0) task_resched(); } } diff --git a/c8_remote/lib/payload/src/sync.c b/c8_remote/lib/payload/src/sync.c index 21c120e..d826ab7 100644 --- a/c8_remote/lib/payload/src/sync.c +++ b/c8_remote/lib/payload/src/sync.c @@ -1,18 +1,13 @@ #include "dev_util.h" PAYLOAD_SECTION -extern uint64_t entry_sync(uint64_t *args) +void entry_sync() { __asm__("dmb sy"); __asm__("ic iallu"); __asm__("dsb sy"); __asm__("isb"); - - return 0; } PAYLOAD_SECTION -extern uint64_t entry_async(uint64_t *base) -{ - return 0; -} \ No newline at end of file +void entry_async(){} \ No newline at end of file From 3e64bd8babe0f3ae4af100affce60e116949e494 Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 20:51:50 -0500 Subject: [PATCH 06/10] added a function to fix the heap --- c8_remote/include/checkm8.h | 1 + c8_remote/src/exploit.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/c8_remote/include/checkm8.h b/c8_remote/include/checkm8.h index 70727d0..7e69b24 100644 --- a/c8_remote/include/checkm8.h +++ b/c8_remote/include/checkm8.h @@ -48,6 +48,7 @@ struct pwned_device struct pwned_device *exploit_device(); int demote_device(struct pwned_device *dev); +int fix_heap(struct pwned_device *dev); void free_device(struct pwned_device *dev); #endif //CHECKM8_TOOL_CHECKM8_H diff --git a/c8_remote/src/exploit.c b/c8_remote/src/exploit.c index cf2350d..90ebe42 100644 --- a/c8_remote/src/exploit.c +++ b/c8_remote/src/exploit.c @@ -7,6 +7,7 @@ #include "usb_helpers.h" #include "command.h" +#include "bootrom_addr.h" static unsigned char data_0xA_0xC0_buf[192] = { @@ -381,6 +382,33 @@ int demote_device(struct pwned_device *dev) return retval; } +int fix_heap(struct pwned_device *dev) +{ + checkm8_debug_indent("fix_heap(dev = %p)\n", dev); +#if CHECKM8_PLATFORM == 8010 + unsigned long long block1_data[4] = {0x80 / 0x40, ((0x840u / 0x40) << 2u), 0x80, 0}; + unsigned long long block2_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0}; + unsigned long long block3_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0}; + + unsigned long long calc1_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9180, 0x1801b91a0, 32, 0x180080640}; + unsigned long long calc2_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9200, 0x1801b9220, 32, 0x180080640}; + unsigned long long calc3_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9280, 0x1801b92a0, 32, 0x180080640}; + + dev_write_memory(dev, 0x1801b91a0, (unsigned char *) block1_data, 64); + dev_write_memory(dev, 0x1801b9220, (unsigned char *) block2_data, 64); + dev_write_memory(dev, 0x1801b92a0, (unsigned char *) block3_data, 64); + + dev_exec(dev, 0, 5, calc1_args); + dev_exec(dev, 0, 5, calc2_args); + dev_exec(dev, 0, 5, calc3_args); + +#else +#error "Can't fix heap for unknown platform" +#endif + + return CHECKM8_SUCCESS; +} + void free_device(struct pwned_device *dev) { checkm8_debug_indent("free_device(dev = %p)\n", dev); From 059461ccbd0a61b68dfefae396c2e8707dd21fc7 Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 20:52:23 -0500 Subject: [PATCH 07/10] fixed an async payload bug and implemented an async floppysleep (works!) --- c8_remote/main.c | 63 ++++++++++++++++++++++++++++++++++++++--- c8_remote/src/payload.c | 4 +-- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/c8_remote/main.c b/c8_remote/main.c index 2b1db3b..335d004 100644 --- a/c8_remote/main.c +++ b/c8_remote/main.c @@ -95,6 +95,59 @@ void floppysleep(struct pwned_device *dev) close_device_session(dev); } +void floppysleep_async(struct pwned_device *dev) +{ + float init_a = -7.504355E-39f; + DEV_PTR_T init_a_ptr, async_buf_ptr; + struct dev_cmd_resp *resp; + + if(IS_CHECKM8_FAIL(open_device_session(dev))) + { + printf("failed to open device session\n"); + return; + } + + if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_SYNC, SRAM))) + { + printf("failed to install sync payload\n"); + return; + } + + if(IS_CHECKM8_FAIL(install_payload(dev, PAYLOAD_FLOPPYSLEEP, SRAM))) + { + printf("failed to install task sleep payload\n"); + return; + } + + init_a_ptr = install_data(dev, SRAM, (unsigned char *) &init_a, sizeof(float)); + if(init_a_ptr == DEV_PTR_NULL) + { + printf("failed to write initial data\n"); + return; + } + + resp = execute_payload(dev, PAYLOAD_SYNC, 0, 0); + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("failed to execute bootstrap\n"); + return; + } + + free_dev_cmd_resp(resp); + + async_buf_ptr = setup_payload_async(dev, PAYLOAD_FLOPPYSLEEP, 32, 1, init_a_ptr); + run_payload_async(dev, PAYLOAD_FLOPPYSLEEP); + close_device_session(dev); + + printf("async buf pointer is %llX\n", async_buf_ptr); + +// sleep(10); +// +// open_device_session(dev); +// resp = read_gadget(dev, async_buf_ptr, 8); +// close_device_session(dev); +} + void aes_sw(struct pwned_device *dev) { int i = 0; @@ -339,12 +392,14 @@ int main() return -1; } + fix_heap(dev); demote_device(dev); - floppysleep(dev); + floppysleep_async(dev); - uninstall_all_payloads(dev); - uninstall_all_data(dev); - free_device(dev); +// open_device_session(dev); +// uninstall_all_payloads(dev); +// uninstall_all_data(dev); +// free_device(dev); } diff --git a/c8_remote/src/payload.c b/c8_remote/src/payload.c index 506f272..6bbeacf 100644 --- a/c8_remote/src/payload.c +++ b/c8_remote/src/payload.c @@ -399,12 +399,12 @@ unsigned long long setup_payload_async(struct pwned_device *dev, PAYLOAD_T p, in } task_args[0] = ADDR_TASK_NEW; - task_args[1] = 0; // todo: name pointer + task_args[1] = 0x10001943b; // todo: name pointer task_args[2] = pl->install_base; task_args[3] = buf_addr; task_args[4] = 0x4000; - resp = dev_exec(dev, 0, 4, task_args); + resp = dev_exec(dev, 0, 5, task_args); if(IS_CHECKM8_FAIL(resp->ret)) { checkm8_debug_indent("\tfailed to create a new task\n"); From ab93d7263394a756a3285e44b1590de5e3c30947 Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Tue, 11 Feb 2020 21:27:14 -0500 Subject: [PATCH 08/10] Finally incorporated arduino code into main program (somewhat) --- CMakeLists.txt | 18 +++++++++++++++++- c8_remote/lib/CMakeLists.txt | 2 -- c8_remote/lib/payload/CMakeLists.txt | 4 +--- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faf8138..65070d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,25 @@ cmake_minimum_required(VERSION 3.10) project(checkm8_tool) -enable_language(C) +enable_language(C ASM) + +include(${CMAKE_ROOT}/Modules/ExternalProject.cmake) include_directories(c8_remote/include) include_directories(include) +ExternalProject_Add(checkm8_arduino + PREFIX c8_arduino/ + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/c8_arduino/ + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/checkm8_arduino + INSTALL_COMMAND "") + +ExternalProject_Add_Step(checkm8_arduino upload + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/checkm8_arduino/ + COMMAND cmake --build . --target upload + DEPENDEES build + EXCLUDE_FROM_MAIN true) + +ExternalProject_add_StepTargets(checkm8_arduino upload build) + add_subdirectory(c8_remote/lib) add_subdirectory(c8_remote) diff --git a/c8_remote/lib/CMakeLists.txt b/c8_remote/lib/CMakeLists.txt index f6c3411..eb375aa 100644 --- a/c8_remote/lib/CMakeLists.txt +++ b/c8_remote/lib/CMakeLists.txt @@ -1,5 +1,3 @@ -project(checkm8_libpayload) - set(PL_NAMES aes_busy aes_sw diff --git a/c8_remote/lib/payload/CMakeLists.txt b/c8_remote/lib/payload/CMakeLists.txt index e032c13..2d09bab 100644 --- a/c8_remote/lib/payload/CMakeLists.txt +++ b/c8_remote/lib/payload/CMakeLists.txt @@ -1,8 +1,6 @@ -project(checkm8_libpayload_sources C ASM) include_directories(${CMAKE_CURRENT_LIST_DIR}/include) - - set(CMAKE_SYSTEM_PROCESSOR arm) + if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64") # regular desktop set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc) From 34703b958e74c30d23c7678ca3263e75a0abb65e Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Wed, 12 Feb 2020 14:40:36 -0500 Subject: [PATCH 09/10] Undo arduino incorporation (dumb) --- CMakeLists.txt | 14 -------------- include/checkm8_config.h | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65070d6..326151a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,19 +7,5 @@ include(${CMAKE_ROOT}/Modules/ExternalProject.cmake) include_directories(c8_remote/include) include_directories(include) -ExternalProject_Add(checkm8_arduino - PREFIX c8_arduino/ - SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/c8_arduino/ - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/checkm8_arduino - INSTALL_COMMAND "") - -ExternalProject_Add_Step(checkm8_arduino upload - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/checkm8_arduino/ - COMMAND cmake --build . --target upload - DEPENDEES build - EXCLUDE_FROM_MAIN true) - -ExternalProject_add_StepTargets(checkm8_arduino upload build) - add_subdirectory(c8_remote/lib) add_subdirectory(c8_remote) diff --git a/include/checkm8_config.h b/include/checkm8_config.h index 83d8ca9..56033f0 100644 --- a/include/checkm8_config.h +++ b/include/checkm8_config.h @@ -3,7 +3,7 @@ #define CHECKM8_LOGGING -//#define WITH_ARDUINO +#define WITH_ARDUINO #define ARDUINO_DEV "/dev/ttyACM0" #define ARDUINO_BAUD 115200 From d04b884487db62abfd6d33f9a1ad03e73c67120b Mon Sep 17 00:00:00 2001 From: Gregor Haas Date: Mon, 17 Feb 2020 15:37:57 -0500 Subject: [PATCH 10/10] Copy over some adjustments from other branch ... overwrite --- c8_remote/lib/payload/src/exit_usb_task.c | 3 ++- c8_remote/src/exploit.c | 20 ++++++++++++++++++-- c8_remote/src/usb_helpers.c | 6 ++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/c8_remote/lib/payload/src/exit_usb_task.c b/c8_remote/lib/payload/src/exit_usb_task.c index 95d23b8..fd45580 100644 --- a/c8_remote/lib/payload/src/exit_usb_task.c +++ b/c8_remote/lib/payload/src/exit_usb_task.c @@ -39,7 +39,7 @@ void fix_heap() check_all_chksums(); } -void entry_sync() +void entry_sync(unsigned long long *self) { fix_heap(); @@ -47,6 +47,7 @@ void entry_sync() *(ADDR_DFU_STATUS) = 1; event_notify(ADDR_DFU_EVENT); + dev_free(self); } void entry_async(uint64_t *base){} \ No newline at end of file diff --git a/c8_remote/src/exploit.c b/c8_remote/src/exploit.c index 90ebe42..de3e195 100644 --- a/c8_remote/src/exploit.c +++ b/c8_remote/src/exploit.c @@ -329,10 +329,10 @@ int demote_device(struct pwned_device *dev) checkm8_debug_indent("\tattempting to demote device\n"); resp = dev_write_memory(dev, DEMOTE_REG, (unsigned char *) &oldval, 4); - free_dev_cmd_resp(resp); if(IS_CHECKM8_FAIL(resp->ret)) { checkm8_debug_block("\tfailed to write to demotion reg\n"); + free_dev_cmd_resp(resp); if(IS_CHECKM8_FAIL(close_device_session(dev))) { @@ -342,6 +342,7 @@ int demote_device(struct pwned_device *dev) return CHECKM8_FAIL_INVARGS; } + free_dev_cmd_resp(resp); // verify resp = dev_read_memory(dev, DEMOTE_REG, 4); @@ -385,7 +386,9 @@ int demote_device(struct pwned_device *dev) int fix_heap(struct pwned_device *dev) { checkm8_debug_indent("fix_heap(dev = %p)\n", dev); -#if CHECKM8_PLATFORM == 8010 + int close; + + #if CHECKM8_PLATFORM == 8010 unsigned long long block1_data[4] = {0x80 / 0x40, ((0x840u / 0x40) << 2u), 0x80, 0}; unsigned long long block2_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0}; unsigned long long block3_data[4] = {0x80 / 0x40, ((0x80u / 0x40) << 2u), 0x80, 0}; @@ -394,6 +397,17 @@ int fix_heap(struct pwned_device *dev) unsigned long long calc2_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9200, 0x1801b9220, 32, 0x180080640}; unsigned long long calc3_args[5] = {ADDR_CALC_CHKSUM, 0x1801b9280, 0x1801b92a0, 32, 0x180080640}; + if(is_device_session_open(dev)) close = 0; + else + { + close = 1; + if(IS_CHECKM8_FAIL(open_device_session(dev))) + { + checkm8_debug_indent("\tfailed to open a device session\n"); + return CHECKM8_FAIL_XFER; + } + } + dev_write_memory(dev, 0x1801b91a0, (unsigned char *) block1_data, 64); dev_write_memory(dev, 0x1801b9220, (unsigned char *) block2_data, 64); dev_write_memory(dev, 0x1801b92a0, (unsigned char *) block3_data, 64); @@ -402,6 +416,8 @@ int fix_heap(struct pwned_device *dev) dev_exec(dev, 0, 5, calc2_args); dev_exec(dev, 0, 5, calc3_args); + if(close) close_device_session(dev); + #else #error "Can't fix heap for unknown platform" #endif diff --git a/c8_remote/src/usb_helpers.c b/c8_remote/src/usb_helpers.c index 06e7027..fb70697 100644 --- a/c8_remote/src/usb_helpers.c +++ b/c8_remote/src/usb_helpers.c @@ -517,6 +517,12 @@ int ctrl_transfer(struct pwned_device *dev, // get the size of this chunk size = 0; ard_read(dev, (unsigned char *) &size, 2); + if(size > ARD_BUF_SIZE) + { + checkm8_debug_indent("\treceived bad chunk size %i\n", size); + return CHECKM8_FAIL_XFER; + } + checkm8_debug_indent("\treceiving data chunk of size %i\n", size); ard_read(dev, (unsigned char *) &data[amount], size);