diff --git a/c8_libpayload/pl/src/aes_sw.c b/c8_libpayload/pl/src/aes_sw.c index b30525c..d6dd1fb 100644 --- a/c8_libpayload/pl/src/aes_sw.c +++ b/c8_libpayload/pl/src/aes_sw.c @@ -162,24 +162,21 @@ void aes128_encrypt_ecb(unsigned char *msg, unsigned int msg_len, unsigned char TEXT_SECTION unsigned long long _start(unsigned char *msg, unsigned int msg_len, unsigned char *key, - unsigned char sbox[16][16], unsigned char rc_lookup[11], - unsigned char mul2[256], unsigned char mul3[256]) + 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 long long timer_deadline_enter = 0x10000b874; unsigned long long halt = 0x1000004fc; - while(1) - { - __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)); + __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)); - if(2 * end - start - 64 > 0) - { - ((BOOTROM_FUNC) timer_deadline_enter)(2 * end - start - 64, ((BOOTROM_FUNC) 0x10000b924)); - ((BOOTROM_FUNC) halt)(); - } + if(2 * end - start - 64 > 0) + { + ((BOOTROM_FUNC) timer_deadline_enter)(2 * end - start - 64, ((BOOTROM_FUNC) 0x10000b924)); + ((BOOTROM_FUNC) halt)(); } return end - start; diff --git a/c8_remote/include/command.h b/c8_remote/include/command.h index 42c5f54..4a4dbaf 100644 --- a/c8_remote/include/command.h +++ b/c8_remote/include/command.h @@ -14,12 +14,12 @@ struct dev_cmd_resp int len; }; -struct dev_cmd_resp *dev_memset(struct pwned_device *dev, long long addr, unsigned char c, int len); -struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, long long dest, long long src, int len); +struct dev_cmd_resp *dev_memset(struct pwned_device *dev, unsigned long long addr, unsigned char c, int len); +struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, unsigned long long dest, unsigned long long src, int len); struct dev_cmd_resp *dev_exec(struct pwned_device *dev, int response_len, int nargs, unsigned long long *args); -struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, long long addr, int len); -struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, long long addr, unsigned char *data, int len); +struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, unsigned long long addr, int len); +struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, unsigned long long addr, unsigned char *data, int len); void free_dev_cmd_resp(struct dev_cmd_resp *resp); diff --git a/c8_remote/include/payload.h b/c8_remote/include/payload.h index c12cb6d..cc958a8 100644 --- a/c8_remote/include/payload.h +++ b/c8_remote/include/payload.h @@ -26,8 +26,11 @@ 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, ...); -struct dev_cmd_resp *read_gadget(struct pwned_device *dev, long long addr, int len); -struct dev_cmd_resp *write_gadget(struct pwned_device *dev, long long addr, unsigned char *data, int len); -struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, long long addr, int response_len, int nargs, ...); +unsigned long long install_data(struct pwned_device *dev, LOCATION_T loc, unsigned char *data, int len); +int uninstall_data(struct pwned_device *dev, unsigned long long ptr); + +struct dev_cmd_resp *read_gadget(struct pwned_device *dev, unsigned long long addr, int len); +struct dev_cmd_resp *write_gadget(struct pwned_device *dev, unsigned long long addr, unsigned char *data, int len); +struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, unsigned long long addr, int response_len, int nargs, ...); #endif //CHECKM8_TOOL_PAYLOAD_H diff --git a/c8_remote/main.c b/c8_remote/main.c index c2a6695..b7ec658 100644 --- a/c8_remote/main.c +++ b/c8_remote/main.c @@ -98,8 +98,17 @@ int floppysleep(struct pwned_device *dev) free_device(dev); } -void write_aes_utils(struct pwned_device *dev) +void aes_sw(struct pwned_device *dev) { + int i = 0; + struct dev_cmd_resp *resp; + unsigned long long addr_sbox, addr_rc, addr_mul2, addr_mul3, addr_key, addr_data; + + unsigned char key[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}; + unsigned char data[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}; + unsigned char sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, @@ -162,101 +171,81 @@ void write_aes_utils(struct pwned_device *dev) 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a }; - struct dev_cmd_resp *resp; + if(IS_CHECKM8_FAIL(open_device_session(dev))) + { + printf("failed to open device session\n"); + return; + } - resp = write_gadget(dev, 0x180154000, sbox, 256); - if(IS_CHECKM8_FAIL(resp->ret)) + addr_sbox = install_data(dev, SRAM, sbox, 256); + if(addr_sbox == -1) { printf("failed to write sbox\n"); return; } - free_dev_cmd_resp(resp); - resp = write_gadget(dev, 0x180154000 + 256, rc_lookup, 11); - if(IS_CHECKM8_FAIL(resp->ret)) + addr_rc = install_data(dev, SRAM, rc_lookup, 11); + if(addr_rc == -1) { printf("failed to write rc lookup\n"); return; } - free_dev_cmd_resp(resp); - resp = write_gadget(dev, 0x180154000 + 256 + 16, mul2_lookup, 256); - if(IS_CHECKM8_FAIL(resp->ret)) + addr_mul2 = install_data(dev, SRAM, mul2_lookup, 256); + if(addr_mul2 == -1) { printf("failed to write mul2 lookup\n"); return; } - free_dev_cmd_resp(resp); - resp = write_gadget(dev, 0x180154000 + 512 + 16, mul3_lookup, 256); - if(IS_CHECKM8_FAIL(resp->ret)) + addr_mul3 = install_data(dev, SRAM, mul3_lookup, 256); + if(addr_mul3 == -1) { printf("failed to write mul3 lookup\n"); return; } -} -int aes_sw(struct pwned_device *dev) -{ - int i = 0; - struct dev_cmd_resp *resp; - unsigned char key[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}; - unsigned char data[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, - 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}; - - if(IS_CHECKM8_FAIL(open_device_session(dev))) + addr_key = install_data(dev, SRAM, key, 16); + if(addr_key == -1) { - printf("failed to open device session\n"); - return -1; + printf("failed to write key\n"); + return; + } + + addr_data = install_data(dev, SRAM, data, 16); + if(addr_data == -1) + { + printf("failed to write data\n"); + 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_AES_SW, SRAM))) { printf("failed to install task sleep payload\n"); - return -1; + return; } - resp = write_gadget(dev, 0x180152000, key, 16); - if(IS_CHECKM8_FAIL(resp->ret)) - { - printf("failed to write key to device\n"); - return -1; - } - - free_dev_cmd_resp(resp); - resp = write_gadget(dev, 0x180153000, data, 16); - if(IS_CHECKM8_FAIL(resp->ret)) - { - printf("failed to write aes data\n"); - return -1; - } - - free_dev_cmd_resp(resp); - write_aes_utils(dev); - - while(1) + for(int i = 0; i < 100; i++) { resp = execute_payload(dev, PAYLOAD_AES_SW, 0, 7, - 0x180153000, 16, 0x180152000, - 0x180154000, 0x180154000 + 256, - 0x180154000 + 256 + 16, 0x180154000 + 512 + 16); + addr_data, 16, addr_key, + addr_sbox, addr_rc, addr_mul2, addr_mul3); if(IS_CHECKM8_FAIL(resp->ret)) { printf("failed to execute sw AES payload\n"); - return -1; + return; } printf("%i) op took %llu\n", i++, resp->retval); free_dev_cmd_resp(resp); - resp = read_gadget(dev, 0x180153000, 16); + resp = read_gadget(dev, addr_data, 16); if(IS_CHECKM8_FAIL(resp->ret)) { printf("failed to read encrypted data from memory\n"); @@ -273,8 +262,17 @@ int aes_sw(struct pwned_device *dev) usleep(1000000); } + uninstall_payload(dev, PAYLOAD_AES_SW); + uninstall_payload(dev, PAYLOAD_SYNC); + + uninstall_data(dev, addr_data); + uninstall_data(dev, addr_key); + uninstall_data(dev, addr_mul3); + uninstall_data(dev, addr_mul2); + uninstall_data(dev, addr_rc); + uninstall_data(dev, addr_sbox); + close_device_session(dev); - free_device(dev); } int main() diff --git a/c8_remote/src/command.c b/c8_remote/src/command.c index e02e11e..66f3c7f 100644 --- a/c8_remote/src/command.c +++ b/c8_remote/src/command.c @@ -157,7 +157,7 @@ struct dev_cmd_resp *command(struct pwned_device *dev, #define MEMS_MAGIC 0x6d656d736d656d73ull // 'memsmems'[::-1] #define DONE_MAGIC 0x646f6e65646f6e65ull // 'donedone'[::-1] -struct dev_cmd_resp *dev_memset(struct pwned_device *dev, long long addr, unsigned char c, int len) +struct dev_cmd_resp *dev_memset(struct pwned_device *dev, unsigned long long addr, unsigned char c, int len) { checkm8_debug_indent("dev_memset(dev = %p, addr = %lx, c = %x, len = %li)\n", dev, addr, c, len); unsigned long long cmd_args[5]; @@ -170,7 +170,7 @@ struct dev_cmd_resp *dev_memset(struct pwned_device *dev, long long addr, unsign return command(dev, (unsigned char *) &cmd_args, 5 * sizeof(unsigned long long), 8); } -struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, long long dest, long long src, int len) +struct dev_cmd_resp *dev_memcpy(struct pwned_device *dev, unsigned long long dest, unsigned long long src, int len) { checkm8_debug_indent("dev_memset(dev = %p, dest = %lx, src = %lx, len = %li)\n", dev, dest, src, len); unsigned long long cmd_args[5]; @@ -205,7 +205,7 @@ struct dev_cmd_resp *dev_exec(struct pwned_device *dev, int response_len, int na return command(dev, (unsigned char *) cmd_args, (1 + nargs) * sizeof(unsigned long long), 16 + response_len); } -struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, long long addr, int len) +struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, unsigned long long addr, int len) { checkm8_debug_indent("dev_read_memory(dev = %p, addr = %lx, len = %i)\n", dev, addr, len); long long index = 0, amount; @@ -254,7 +254,7 @@ struct dev_cmd_resp *dev_read_memory(struct pwned_device *dev, long long addr, i return ret; } -struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, long long addr, unsigned char *data, int len) +struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, unsigned long long addr, unsigned char *data, int len) { checkm8_debug_indent("dev_write_memory(dev = %p, addr = %lx, data = %p, len = %i)\n", dev, addr, data, len); diff --git a/c8_remote/src/payload.c b/c8_remote/src/payload.c index 819640e..8a10595 100644 --- a/c8_remote/src/payload.c +++ b/c8_remote/src/payload.c @@ -15,7 +15,7 @@ struct payload const unsigned char *data; int len; - long long install_base; + unsigned long long install_base; struct payload *next; struct payload *prev; }; @@ -96,13 +96,25 @@ void free_payload(struct payload *p) free(p); } -long long curr_address = 0x180150000; -long long get_address(struct pwned_device *dev, LOCATION_T l) +unsigned long long get_address(struct pwned_device *dev, LOCATION_T l, int len) { - //TODO: make an actual memory allocator - long long ret = curr_address; - curr_address += 0x1000; - return ret; + checkm8_debug_indent("get_address(dev = %p, loc = %i, len = %i)\n"); + unsigned long long addr_malloc = 0x10000efe0, retval; + unsigned long long malloc_args[2] = {addr_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 -1; + } + + retval = resp->retval; + free_dev_cmd_resp(resp); + + checkm8_debug_indent("\tgot address %X\n", retval); + return retval; } @@ -157,7 +169,7 @@ int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc) struct dev_cmd_resp *resp = NULL; struct payload *pl = get_payload(p); - long long addr = get_address(dev, loc); + unsigned long long addr = get_address(dev, loc, pl->len); if(pl == NULL || addr == -1) { @@ -182,7 +194,72 @@ int install_payload(struct pwned_device *dev, PAYLOAD_T p, LOCATION_T loc) int uninstall_payload(struct pwned_device *dev, PAYLOAD_T p) { - //TODO: free memory in memory allocator + checkm8_debug_indent("uninstall payload(dev = %p, p = %i)\n", dev, p); + unsigned long long addr_free = 0x10000f1b0; + unsigned long long free_args[2]; + struct dev_cmd_resp *resp; + struct payload *pl = dev_retrieve_payload(dev, p); + + if(pl == NULL) + { + checkm8_debug_indent("\tinvalid args (payload)\n"); + return CHECKM8_FAIL_INVARGS; + } + + free_args[0] = addr_free; + free_args[1] = pl->install_base; + + 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; + } + + dev_unlink_payload(dev, pl); + free_payload(pl); + return CHECKM8_SUCCESS; +} + +unsigned long long 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"); + struct dev_cmd_resp *resp; + unsigned long long addr = get_address(dev, loc, len); + + if(addr == -1) + { + checkm8_debug_indent("\tfailed to get an address\n"); + return -1; + } + + 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, unsigned long long addr) +{ + checkm8_debug_indent("uninstall_data(dev = %p, addr = %X)\n", dev, addr); + struct dev_cmd_resp *resp; + unsigned long long addr_free = 0x10000f1b0; + unsigned long long free_args[2] = {addr_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; } @@ -217,19 +294,19 @@ struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int return dev_exec(dev, response_len, nargs + 1, args); } -struct dev_cmd_resp *read_gadget(struct pwned_device *dev, long long addr, int len) +struct dev_cmd_resp *read_gadget(struct pwned_device *dev, unsigned long long addr, int len) { checkm8_debug_indent("read_gadget(dev = %p, addr = %lx, len = %i)\n", dev, addr, len); return dev_read_memory(dev, addr, len); } -struct dev_cmd_resp *write_gadget(struct pwned_device *dev, long long addr, unsigned char *data, int len) +struct dev_cmd_resp *write_gadget(struct pwned_device *dev, unsigned long long addr, unsigned char *data, int len) { checkm8_debug_indent("write_gadget(dev = %p, addr = %lx, data = %p, len = %i)\n", dev, addr, data, len); return dev_write_memory(dev, addr, data, len); } -struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, long long addr, int response_len, int nargs, ...) +struct dev_cmd_resp *execute_gadget(struct pwned_device *dev, unsigned long long addr, int response_len, int nargs, ...) { checkm8_debug_indent("execute_gadget(dev = %p, addr = %lx, nargs = %i)\n", dev, addr, nargs); int i;