add winusb hook and usbio board skeletons

This commit is contained in:
Hay1tsme
2025-02-04 04:09:19 -05:00
parent 61ba10ccb8
commit 75f171663c
23 changed files with 775 additions and 97 deletions
+3
View File
@@ -4,6 +4,7 @@ hooklib_lib = static_library(
implicit_include_directories : false,
dependencies : [
capnhook.get_variable('hook_dep'),
winusb_lib,
],
sources : [
'cursor.c',
@@ -28,5 +29,7 @@ hooklib_lib = static_library(
'setupapi.h',
'spike.c',
'spike.h',
'winusb.c',
'winusb.h',
],
)
+146
View File
@@ -23,6 +23,12 @@ static void setupapi_hook_init(void);
/* API hooks */
static HDEVINFO WINAPI my_SetupDiGetClassDevsA(
const GUID *ClassGuid,
char *Enumerator,
HWND hwndParent,
DWORD Flags);
static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
const GUID *ClassGuid,
wchar_t *Enumerator,
@@ -44,10 +50,24 @@ static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailW(
DWORD *RequiredSize,
SP_DEVINFO_DATA *DeviceInfoData);
static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailA(
HDEVINFO DeviceInfoSet,
SP_DEVICE_INTERFACE_DATA *DeviceInterfaceData,
SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData,
DWORD DeviceInterfaceDetailDataSize,
DWORD *RequiredSize,
SP_DEVINFO_DATA *DeviceInfoData);
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet);
/* Links */
static HDEVINFO (WINAPI *next_SetupDiGetClassDevsA)(
const GUID *ClassGuid,
char *Enumerator,
HWND hwndParent,
DWORD Flags);
static HDEVINFO (WINAPI *next_SetupDiGetClassDevsW)(
const GUID *ClassGuid,
wchar_t *Enumerator,
@@ -69,12 +89,24 @@ static BOOL (WINAPI *next_SetupDiGetDeviceInterfaceDetailW)(
DWORD *RequiredSize,
SP_DEVINFO_DATA *DeviceInfoData);
static BOOL (WINAPI *next_SetupDiGetDeviceInterfaceDetailA)(
HDEVINFO DeviceInfoSet,
SP_DEVICE_INTERFACE_DATA *DeviceInterfaceData,
SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData,
DWORD DeviceInterfaceDetailDataSize,
DWORD *RequiredSize,
SP_DEVINFO_DATA *DeviceInfoData);
static BOOL (WINAPI *next_SetupDiDestroyDeviceInfoList)(HDEVINFO DeviceInfoSet);
/* Hook tbl */
static const struct hook_symbol setupapi_syms[] = {
{
.name = "SetupDiGetClassDevsA",
.patch = my_SetupDiGetClassDevsA,
.link = (void *) &next_SetupDiGetClassDevsA,
}, {
.name = "SetupDiGetClassDevsW",
.patch = my_SetupDiGetClassDevsW,
.link = (void *) &next_SetupDiGetClassDevsW,
@@ -86,6 +118,10 @@ static const struct hook_symbol setupapi_syms[] = {
.name = "SetupDiGetDeviceInterfaceDetailW",
.patch = my_SetupDiGetDeviceInterfaceDetailW,
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailW,
}, {
.name = "SetupDiGetDeviceInterfaceDetailA",
.patch = my_SetupDiGetDeviceInterfaceDetailA,
.link = (void *) &next_SetupDiGetDeviceInterfaceDetailA,
}, {
.name = "SetupDiDestroyDeviceInfoList",
.patch = my_SetupDiDestroyDeviceInfoList,
@@ -155,6 +191,40 @@ void setupapi_hook_insert_hooks(HMODULE target)
_countof(setupapi_syms));
}
static HDEVINFO WINAPI my_SetupDiGetClassDevsA(
const GUID *ClassGuid,
char *Enumerator,
HWND hwndParent,
DWORD Flags)
{
struct setupapi_class *class_;
HDEVINFO result;
size_t i;
result = next_SetupDiGetClassDevsA(
ClassGuid,
Enumerator,
hwndParent,
Flags);
if (result == INVALID_HANDLE_VALUE || ClassGuid == NULL) {
return result;
}
EnterCriticalSection(&setupapi_lock);
for (i = 0 ; i < setupapi_nclasses ; i++) {
class_ = &setupapi_classes[i];
if (memcmp(ClassGuid, class_->guid, sizeof(*ClassGuid)) == 0) {
class_->cur_handle = result;
}
}
LeaveCriticalSection(&setupapi_lock);
return result;
}
static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
const GUID *ClassGuid,
wchar_t *Enumerator,
@@ -322,6 +392,82 @@ pass:
DeviceInfoData);
}
static BOOL WINAPI my_SetupDiGetDeviceInterfaceDetailA(
HDEVINFO DeviceInfoSet,
SP_DEVICE_INTERFACE_DATA *DeviceInterfaceData,
SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData,
DWORD DeviceInterfaceDetailDataSize,
DWORD *RequiredSize,
SP_DEVINFO_DATA *DeviceInfoData)
{
const wchar_t *wstr;
char path_ch[MAX_PATH];
size_t nbytes_wstr;
size_t nbytes_str;
size_t nbytes_total;
size_t i;
bool match;
if (DeviceInfoSet == INVALID_HANDLE_VALUE || DeviceInterfaceData == NULL) {
goto pass;
}
EnterCriticalSection(&setupapi_lock);
for ( i = 0, match = false ;
i < setupapi_nclasses && !match ;
i++) {
if ( DeviceInfoSet == setupapi_classes[i].cur_handle &&
DeviceInterfaceData->Reserved == (ULONG_PTR) setupapi_classes[i].path) {
match = true;
}
}
LeaveCriticalSection(&setupapi_lock);
if (!match) {
goto pass;
}
wstr = (const wchar_t *) DeviceInterfaceData->Reserved;
nbytes_wstr = (wcslen(wstr) + 1) * sizeof(wchar_t);
wcstombs_s(&nbytes_str, path_ch, MAX_PATH, (wchar_t *) DeviceInterfaceData->Reserved, MAX_PATH);
nbytes_total = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath);
nbytes_total += nbytes_str;
if (RequiredSize != NULL) {
*RequiredSize = (DWORD) nbytes_total;
}
if ( DeviceInterfaceDetailData == NULL &&
DeviceInterfaceDetailDataSize < nbytes_total) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
if (DeviceInterfaceDetailData->cbSize!=sizeof(*DeviceInterfaceDetailData)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
memcpy(DeviceInterfaceDetailData->DevicePath, path_ch, nbytes_str);
SetLastError(ERROR_SUCCESS);
return TRUE;
pass:
return next_SetupDiGetDeviceInterfaceDetailA(
DeviceInfoSet,
DeviceInterfaceData,
DeviceInterfaceDetailData,
DeviceInterfaceDetailDataSize,
RequiredSize,
DeviceInfoData);
}
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet)
{
size_t i;
+223
View File
@@ -0,0 +1,223 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "hook/table.h"
#include "hooklib/winusb.h"
#include "util/dprintf.h"
static bool winusb_initted;
static CRITICAL_SECTION winusb_lock;
static struct winusb_dev *winusb_classes;
static size_t winusb_nclasses;
static void winusb_hook_init();
BOOL my_WinUsb_QueryPipe(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber,
UCHAR PipeIndex,
PWINUSB_PIPE_INFORMATION PipeInformation
);
BOOL my_WinUsb_QueryInterfaceSettings(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber,
PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
);
BOOL my_WinUsb_GetDescriptor(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR DescriptorType,
UCHAR Index,
USHORT LanguageID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred
);
BOOL my_WinUsb_WritePipe(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
BOOL my_WinUsb_QueryDeviceInformation(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG InformationType,
PULONG BufferLength,
PVOID Buffer
);
BOOL my_WinUsb_ReadPipe(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
BOOL my_WinUsb_Initialize(
HANDLE DeviceHandle,
PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
BOOL my_WinUsb_Free(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
BOOL (*next_WinUsb_QueryPipe)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber,
UCHAR PipeIndex,
PWINUSB_PIPE_INFORMATION PipeInformation
);
BOOL (*next_WinUsb_QueryInterfaceSettings)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber,
PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
);
BOOL (*next_WinUsb_GetDescriptor)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR DescriptorType,
UCHAR Index,
USHORT LanguageID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred
);
BOOL (*next_WinUsb_WritePipe)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
BOOL (*next_WinUsb_QueryDeviceInformation)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG InformationType,
PULONG BufferLength,
PVOID Buffer
);
BOOL (*next_WinUsb_ReadPipe)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
BOOL (*next_WinUsb_Initialize)(
HANDLE DeviceHandle,
PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
BOOL (*next_WinUsb_Free)(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
static const struct hook_symbol winusb_syms[] = {
{
.name = "WinUsb_QueryPipe",
.patch = my_WinUsb_QueryPipe,
.link = (void *) &next_WinUsb_QueryPipe,
}, {
.name = "WinUsb_QueryInterfaceSettings",
.patch = my_WinUsb_QueryInterfaceSettings,
.link = (void *) &next_WinUsb_QueryInterfaceSettings,
}, {
.name = "WinUsb_GetDescriptor",
.patch = my_WinUsb_GetDescriptor,
.link = (void *) &next_WinUsb_GetDescriptor,
}, {
.name = "WinUsb_WritePipe",
.patch = my_WinUsb_WritePipe,
.link = (void *) &next_WinUsb_WritePipe,
}, {
.name = "WinUsb_QueryDeviceInformation",
.patch = my_WinUsb_QueryDeviceInformation,
.link = (void *) &next_WinUsb_QueryDeviceInformation,
}, {
.name = "WinUsb_ReadPipe",
.patch = my_WinUsb_ReadPipe,
.link = (void *) &next_WinUsb_ReadPipe,
}, {
.name = "WinUsb_Initialize",
.patch = my_WinUsb_Initialize,
.link = (void *) &next_WinUsb_Initialize,
}, {
.name = "WinUsb_Free",
.patch = my_WinUsb_Free,
.link = (void *) &next_WinUsb_Free,
}
};
HRESULT winusb_add_phantom_dev(const struct winusb_dev *dev)
{
struct winusb_dev *class_;
struct winusb_dev *new_array;
HRESULT hr;
assert(dev != NULL);
winusb_hook_init();
EnterCriticalSection(&winusb_lock);
new_array = realloc(
winusb_classes,
(winusb_nclasses + 1) * sizeof(struct winusb_dev));
if (new_array == NULL) {
hr = E_OUTOFMEMORY;
goto end;
}
winusb_classes = new_array;
// TODO: Copy the dev class to the new slot in the array
class_ = &winusb_classes[winusb_nclasses++];
hr = S_OK;
end:
LeaveCriticalSection(&winusb_lock);
return hr;
}
static void winusb_hook_init()
{
if (winusb_initted) {
return;
}
winusb_hook_insert_hooks(NULL);
InitializeCriticalSection(&winusb_lock);
winusb_initted = true;
}
void winusb_hook_insert_hooks(HMODULE target)
{
hook_table_apply(
target,
"winusb.dll",
winusb_syms,
_countof(winusb_syms));
}
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include <windows.h>
#include <stdint.h>
#include <winusb.h>
#pragma pack(push,1)
// winusb - hooks for winusb ident, read and write passed to device
// usio - providor for winusb, passes along read/write
// ll3io - gives usio the data to write
struct winusb_dev {
HANDLE fd;
GUID class_guid;
const wchar_t *path;
//uint8_t read_pipe_id; // duno if this ever needs to change?
//uint8_t write_pipe_id;
struct _USB_DEVICE_DESCRIPTOR descriptor;
void (*read_pipe)(void *ctx, uint8_t pipe_id, uint8_t *bfr, uint32_t bfr_len);
void (*write_pipe)(void *ctx, uint8_t pipe_id, uint8_t *bfr, uint32_t bfr_len);
};
#pragma pack(pop)
HRESULT winusb_add_phantom_dev(const struct winusb_dev *dev);
void winusb_hook_insert_hooks(HMODULE target);