From fd99f8956a5f3d0f189d4dae2c2cf3a1edc0372b Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Wed, 25 Jan 2023 21:09:38 -0500 Subject: [PATCH] dongle: add vid and pid arguments --- ferrumhook/dllmain.c | 6 +- platform/es3sec.c | 212 ++++++++++++++++++++++++++++++++++++++----- platform/es3sec.h | 2 +- platform/platform.c | 5 +- platform/platform.h | 8 +- taikohook/dllmain.c | 6 +- 6 files changed, 211 insertions(+), 28 deletions(-) diff --git a/ferrumhook/dllmain.c b/ferrumhook/dllmain.c index a83fec0..08d1357 100644 --- a/ferrumhook/dllmain.c +++ b/ferrumhook/dllmain.c @@ -34,7 +34,11 @@ static DWORD CALLBACK ferrum_pre_startup(void) serial_hook_init(); - hr = platform_hook_init(&ferrum_hook_cfg.platform, PLATFORM_ES3, ferrum_jvs_init, ferrum_hook_mod); + struct dongle_info dinfo; + dinfo.vid = 2970; + dinfo.pid = 3088; + + hr = platform_hook_init(&ferrum_hook_cfg.platform, PLATFORM_ES3, ferrum_jvs_init, ferrum_hook_mod, dinfo); if (FAILED(hr)) { ExitProcess(EXIT_FAILURE); diff --git a/platform/es3sec.c b/platform/es3sec.c index b85c929..0d95c30 100644 --- a/platform/es3sec.c +++ b/platform/es3sec.c @@ -10,15 +10,20 @@ #include "util/str.h" #include "es3sec.h" -const wchar_t *DEVNAME_HUB = L"$hub"; -const wchar_t *DEVNAME_DONGLE = L"$dongle"; -const wchar_t HUB_DRIVER_KEY[] = L"{36fc9e60-c465-11cf-8056-444553540000}\\0001"; -const DEVINST HUB_DEVINST = 573; +static const wchar_t DEVNAME_HUB[] = L"$hub"; +static const wchar_t DEVNAME_HUB_[] = L"\\\\.\\$hub"; +static const wchar_t DEVNAME_DONGLE[] = L"$dongle"; +static const wchar_t HUB_DRIVER_KEY[] = L"{36fc9e60-c465-11cf-8056-444553540000}\\0001"; +static const wchar_t root_hub_name[] = L"Fake Root Hub"; +static const DEVINST HUB_DEVINST = 573; +static const DEVINST DONGLE_DEVINST = 5730; static struct es3sec_config config; static HANDLE dongle_fd; static HANDLE hub_fd; static IID hubs_iid; -DEVINST root_dev_inst; +static DEVINST root_dev_inst; +static USHORT dongle_vid; +static USHORT dongle_pid; static HRESULT es3sec_handle_hub_irp(struct irp *irp); static HRESULT es3sec_handle_hub_open(struct irp *irp); @@ -30,6 +35,10 @@ static HRESULT es3sec_handle_dongle_close(struct irp *irp); static HRESULT es3sec_handle_dongle_ioctl(struct irp *irp); static HRESULT es3sec_hub_handle_driverkey(struct irp *irp); +static HRESULT es3sec_hub_handle_roothub(struct irp *irp); +static HRESULT es3sec_hub_handle_nodeinfo(struct irp *irp); +static HRESULT es3sec_hub_connection_info_ex(struct irp *irp); +static HRESULT es3sec_hub_descriptor_from_node(struct irp *irp); static CONFIGRET my_CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags); static CONFIGRET (*next_CM_Get_Child)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags); @@ -64,7 +73,7 @@ static const struct hook_symbol cm_syms[] = { }, }; -HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid) +HRESULT es3sec_hook_init(const struct es3sec_config *cfg, USHORT vid, USHORT pid) { HRESULT hr; assert(cfg != NULL); @@ -94,7 +103,9 @@ HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid) CM_Locate_DevNodeW(&root_dev_inst, NULL, CM_LOCATE_DEVNODE_NORMAL); - dprintf("ES3 Dongle: init with VID %s PID %s (root node DEVINST %lx)\n", vid, pid, root_dev_inst); + dprintf("ES3 Dongle: init with VID %d PID %d\n", vid, pid); + dongle_vid = vid; + dongle_pid = pid; memcpy(&config, cfg, sizeof(*cfg)); return S_OK; @@ -117,7 +128,7 @@ static HRESULT es3sec_handle_hub_irp(struct irp *irp) static HRESULT es3sec_handle_hub_open(struct irp *irp) { - if (!wstr_ieq(irp->open_filename, DEVNAME_HUB)) { + if (!wstr_ieq(irp->open_filename, DEVNAME_HUB) && !wstr_ieq(irp->open_filename, DEVNAME_HUB_)) { return iohook_invoke_next(irp); } @@ -136,18 +147,48 @@ static HRESULT es3sec_handle_hub_ioctl(struct irp *irp) { switch (irp->ioctl) { case 0x220424: return es3sec_hub_handle_driverkey(irp); + case 0x220448: return es3sec_hub_connection_info_ex(irp); + case 0x220410: return es3sec_hub_descriptor_from_node(irp); + case 0x220408: + if (irp->read.nbytes == sizeof(USB_NODE_INFORMATION)) + return es3sec_hub_handle_nodeinfo(irp); + + else if (irp->read.nbytes >= sizeof(USB_ROOT_HUB_NAME)) + return es3sec_hub_handle_roothub(irp); + + else { + dprintf("ES3 Dongle: Bad size for IOCTL %X\n", irp->ioctl); + return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); + } + default: dprintf("ES3 Dongle: Unknown hub IOCTL %X\n", irp->ioctl); return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); } - - return iohook_invoke_next(irp); } static HRESULT es3sec_hub_handle_driverkey(struct irp *irp) -{ - int actual_length = sizeof(HUB_DRIVER_KEY); - PUSB_HCD_DRIVERKEY_NAME usb_hcd_driver_key_name = (PUSB_HCD_DRIVERKEY_NAME) malloc(sizeof(USB_HCD_DRIVERKEY_NAME) + 2 * actual_length); +{ + size_t size_of_driver_key = sizeof(HUB_DRIVER_KEY); + ULONG actual_length = size_of_driver_key + sizeof(USB_ROOT_HUB_NAME); + HRESULT hr; + + if (irp->write.nbytes == sizeof(USB_HCD_DRIVERKEY_NAME)) { + dprintf("ES3 Dongle: Get Hub Driver Key size\n"); + USB_HCD_DRIVERKEY_NAME usb_hcd_driver_key_name; + usb_hcd_driver_key_name.ActualLength = actual_length; + hr = iobuf_write(&irp->read, &usb_hcd_driver_key_name, sizeof(usb_hcd_driver_key_name)); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr); + } + + return hr; + } + + dprintf("ES3 Dongle: Get Hub Driver Key\n"); + PUSB_HCD_DRIVERKEY_NAME usb_hcd_driver_key_name = (PUSB_HCD_DRIVERKEY_NAME)malloc(sizeof(USB_HCD_DRIVERKEY_NAME) + actual_length); usb_hcd_driver_key_name->ActualLength = actual_length; + errno_t err = wcscpy_s( usb_hcd_driver_key_name->DriverKeyName, _countof(HUB_DRIVER_KEY), @@ -159,10 +200,130 @@ static HRESULT es3sec_hub_handle_driverkey(struct irp *irp) return E_FAIL; } - iobuf_write(&irp->read, usb_hcd_driver_key_name, sizeof(usb_hcd_driver_key_name)); + hr = iobuf_write(&irp->read, usb_hcd_driver_key_name, actual_length); - dprintf("ES3 Dongle: Get Hub Driver Key\n"); - return S_OK; + if (FAILED(hr)) { + dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr); + } + + return hr; +} + +static HRESULT es3sec_hub_handle_roothub(struct irp *irp) +{ + size_t size_of_hub_name = sizeof(DEVNAME_HUB); + ULONG actual_length = size_of_hub_name + sizeof(USB_ROOT_HUB_NAME); + HRESULT hr; + + if (irp->read.nbytes == sizeof(USB_ROOT_HUB_NAME)) { + dprintf("ES3 Dongle: Get Hub Root Hub Name size\n"); + USB_ROOT_HUB_NAME rhub; + rhub.ActualLength = actual_length; + hr = iobuf_write(&irp->read, &rhub, sizeof(rhub)); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr); + } + + return hr; + } + + dprintf("ES3 Dongle: Get Hub Root Hub Name\n"); + PUSB_ROOT_HUB_NAME rhub = (PUSB_ROOT_HUB_NAME)malloc(actual_length); + rhub->ActualLength = actual_length; + + errno_t err = wcscpy_s( + rhub->RootHubName, + _countof(DEVNAME_HUB), + DEVNAME_HUB + ); + + if (err) { + dprintf("ES3 Dongle: es3sec_hub_handle_roothub wcscpy_s failed with %X", err); + return E_FAIL; + } + + hr = iobuf_write(&irp->read, rhub, sizeof(USB_ROOT_HUB_NAME) + size_of_hub_name); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: iobuf_write failed! %lx\n", hr); + } + + return hr; +} + +static HRESULT es3sec_hub_handle_nodeinfo(struct irp *irp) +{ + dprintf("ES3 Dongle: Get Hub Node Information\n"); + USB_NODE_INFORMATION node_info; + node_info.NodeType = UsbHub; + node_info.u.HubInformation.HubDescriptor.bNumberOfPorts = 1; + HRESULT hr = iobuf_write(&irp->read, &node_info, sizeof(node_info)); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: es3sec_hub_handle_nodeinfo iobuf_write failed! 0x%lX\n", hr); + } + + return hr; +} + +static HRESULT es3sec_hub_connection_info_ex(struct irp *irp) +{ + HRESULT hr; + PUSB_NODE_CONNECTION_INFORMATION_EX conn_info = (PUSB_NODE_CONNECTION_INFORMATION_EX) malloc(irp->write.nbytes); + hr = iobuf_read(&irp->write, conn_info, irp->write.nbytes); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: es3sec_hub_connection_info_ex Failed to read IRP %lx\n", hr); + return hr; + } + + dprintf("ES3 Dongle: Get Hub Connection Info EX\tConnectionIndex %ld\n", conn_info->ConnectionIndex); + conn_info->ConnectionStatus = DeviceConnected; + conn_info->DeviceIsHub = false; + + conn_info->DeviceDescriptor.idVendor = dongle_vid; + conn_info->DeviceDescriptor.idProduct = dongle_pid; + conn_info->DeviceDescriptor.bLength = sizeof(conn_info->DeviceDescriptor); + + hr = iobuf_write(&irp->read, conn_info, irp->read.nbytes); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: es3sec_hub_connection_info_ex Failed to write IRP %lx\n", hr); + } + + return hr; +} + +static HRESULT es3sec_hub_descriptor_from_node(struct irp *irp) +{ + HRESULT hr; + UCHAR req_type; + UCHAR req_data_requested; + PUSB_DESCRIPTOR_REQUEST req = (PUSB_DESCRIPTOR_REQUEST) malloc(irp->write.nbytes); + hr = iobuf_read(&irp->write, req, irp->write.nbytes); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: es3sec_hub_descriptor_from_node Failed to read IRP %lx\n", hr); + return hr; + } + + req_type = req->SetupPacket.wValue >> 8; + req_data_requested = req->SetupPacket.wValue & 0xFF; + dprintf("ES3 Dongle: Get Hub Descriptor from Node Connection\treq_type %02X req_data_requested %02X\n", req_type, req_data_requested); + switch (req_type) { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: req->Data[2] = irp->write.nbytes - 12; break; + case USB_STRING_DESCRIPTOR_TYPE: break; + default: + dprintf("ES3 Dongle: es3sec_hub_descriptor_from_node Unknown request type %x\n", req_type); + return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); + } + hr = iobuf_write(&irp->read, req, irp->read.nbytes); + + if (FAILED(hr)) { + dprintf("ES3 Dongle: es3sec_hub_descriptor_from_node Failed to write IRP %lx\n", hr); + } + return hr; } static HRESULT es3sec_handle_dongle_irp(struct irp *irp) @@ -199,8 +360,9 @@ static HRESULT es3sec_handle_dongle_close(struct irp *irp) static HRESULT es3sec_handle_dongle_ioctl(struct irp *irp) { - dprintf("ES3 Dongle: IOCTL %X\n", irp->ioctl); - return iohook_invoke_next(irp); + switch (irp->ioctl) { + default: dprintf("ES3 Dongle: Unknown dongle IOCTL %X\n", irp->ioctl); return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); + } } static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW( @@ -218,16 +380,22 @@ static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW( } switch (ulProperty) { - case CM_DRP_DEVICEDESC: wcscpy_s(Buffer, _countof(L"Disk drive"), L"Disk drive"); break; + case CM_DRP_DEVICEDESC: + dprintf("ES3 Dongle: Get hub device description\n"); + // wcscpy_s(Buffer, _countof(L"Disk drive"), L"Disk drive"); + wcscpy_s(Buffer, _countof(L"Fake USB Hub"), L"Fake USB Hub"); + break; - case CM_DRP_DRIVER: wcscpy_s(Buffer, _countof(HUB_DRIVER_KEY), HUB_DRIVER_KEY); break; + case CM_DRP_DRIVER: + dprintf("ES3 Dongle: Get hub driver\n"); + wcscpy_s(Buffer, _countof(HUB_DRIVER_KEY), HUB_DRIVER_KEY); + break; default: - dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW Unhandled property %lX\n", ulProperty); + dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW Unhandled property 0x%lX\n", ulProperty); return CR_FAILURE; } - dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW %lX\n", ulProperty); return CR_SUCCESS; } diff --git a/platform/es3sec.h b/platform/es3sec.h index f520043..862962e 100644 --- a/platform/es3sec.h +++ b/platform/es3sec.h @@ -9,4 +9,4 @@ struct es3sec_config { wchar_t pid[5]; }; -HRESULT es3sec_hook_init(const struct es3sec_config *cfg, char *vid, char *pid); +HRESULT es3sec_hook_init(const struct es3sec_config *cfg, USHORT vid, USHORT pid); diff --git a/platform/platform.c b/platform/platform.c index ac2cdc6..2805ff5 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -4,7 +4,8 @@ HRESULT platform_hook_init( const struct platform_config *cfg, enum platform_type type, jvs_provider_t jvs, - HMODULE redir_mod + HMODULE redir_mod, + struct dongle_info d_info ) { HRESULT hr; @@ -56,7 +57,7 @@ HRESULT platform_hook_init( return hr; } - hr = es3sec_hook_init(&cfg->dongle, "", ""); + hr = es3sec_hook_init(&cfg->dongle, d_info.vid, d_info.pid); if (FAILED(hr)) { return hr; diff --git a/platform/platform.h b/platform/platform.h index 9e5047a..1c0b503 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -9,6 +9,11 @@ #include "platform/vfs.h" #include "platform/es3sec.h" +struct dongle_info { + USHORT pid; + USHORT vid; +}; + struct platform_config { struct clock_config clock; struct netenv_config netenv; @@ -30,5 +35,6 @@ HRESULT platform_hook_init( const struct platform_config *cfg, enum platform_type type, jvs_provider_t jvs, - HMODULE redir_mod + HMODULE redir_mod, + struct dongle_info d_info ); \ No newline at end of file diff --git a/taikohook/dllmain.c b/taikohook/dllmain.c index de4574a..c2e9065 100644 --- a/taikohook/dllmain.c +++ b/taikohook/dllmain.c @@ -35,7 +35,11 @@ static DWORD CALLBACK taiko_pre_startup(void) serial_hook_init(); - hr = platform_hook_init(&taiko_hook_cfg.platform, PLATFORM_BNA1, NULL, taiko_hook_mod); + struct dongle_info dinfo; + dinfo.pid = 0; + dinfo.vid = 0; + + hr = platform_hook_init(&taiko_hook_cfg.platform, PLATFORM_BNA1, NULL, taiko_hook_mod, dinfo); if (FAILED(hr)) { ExitProcess(EXIT_FAILURE);