Compare commits

2 Commits

Author SHA1 Message Date
1b28624336 taiko: dongle and card reader fixes.
FIXME: Crash on entering testmode
2025-01-19 17:57:20 -05:00
3ce5a09aa2 taiko: initial tries to get some stuff working 2025-01-19 22:56:24 +01:00
6 changed files with 338 additions and 9 deletions

View File

@ -79,6 +79,12 @@ HRESULT dns_platform_hook_init(const struct dns_config *cfg)
return hr;
}
hr = dns_hook_push(L"stable.garm.nbgi-amnet.jp", cfg->startup);
if (FAILED(hr)) {
return hr;
}
// if your ISP resolves bad domains, it will kill the network. These 2
// *cannot* resolve

View File

@ -7,11 +7,12 @@
#include "hook/table.h"
#include "hook/iohook.h"
#include "hook/procaddr.h"
#include "hooklib/setupapi.h"
#include "util/dprintf.h"
#include "util/str.h"
#include "es3sec.h"
#include "platform/es3sec.h"
#define DONGLE_STR_IDX_MANUFACTURER 1
#define DONGLE_STR_IDX_PRODUCT 2
@ -50,6 +51,35 @@ static HRESULT es3sec_hub_get_string_descriptor(struct irp *irp, PUSB_DESCRIPTOR
static CONFIGRET my_CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
static CONFIGRET (*next_CM_Get_Child)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
static CONFIGRET my_CM_Get_Parent(
PDEVINST pdnDevInst,
DEVINST dnDevInst,
ULONG ulFlags
);
static CONFIGRET (*next_CM_Get_Parent)(
PDEVINST pdnDevInst,
DEVINST dnDevInst,
ULONG ulFlags
);
static CONFIGRET my_CM_Get_DevNode_Registry_PropertyA(
DEVINST dnDevInst,
ULONG ulProperty,
PULONG pulRegDataType,
PVOID Buffer,
PULONG pulLength,
ULONG ulFlags
);
static CONFIGRET (*next_CM_Get_DevNode_Registry_PropertyA)(
DEVINST dnDevInst,
ULONG ulProperty,
PULONG pulRegDataType,
PVOID Buffer,
PULONG pulLength,
ULONG ulFlags
);
static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
DEVINST dnDevInst,
ULONG ulProperty,
@ -67,17 +97,73 @@ static CONFIGRET (*next_CM_Get_DevNode_Registry_PropertyW)(
ULONG ulFlags
);
static CONFIGRET my_CM_Get_DevNode_Status(
PULONG pulStatus,
PULONG pulProblemNumber,
DEVINST dnDevInst,
ULONG ulFlags
);
static CONFIGRET (*next_CM_Get_DevNode_Status)(
PULONG pulStatus,
PULONG pulProblemNumber,
DEVINST dnDevInst,
ULONG ulFlags
);
static CONFIGRET my_CM_Get_Device_IDA(
DEVINST dnDevInst,
PSTR Buffer,
ULONG BufferLen,
ULONG ulFlags
);
static CONFIGRET (*next_CM_Get_Device_IDA)(
DEVINST dnDevInst,
PSTR Buffer,
ULONG BufferLen,
ULONG ulFlags
);
static CONFIGRET my_CM_Get_Device_ID_Size(
PULONG pulLen,
DEVINST dnDevInst,
ULONG ulFlags
);
static CONFIGRET (*next_CM_Get_Device_ID_Size)(
PULONG pulLen,
DEVINST dnDevInst,
ULONG ulFlags
);
static const struct hook_symbol cm_syms[] = {
{
.name = "CM_Get_DevNode_Registry_PropertyA",
.patch = my_CM_Get_DevNode_Registry_PropertyA,
.link = (void **) &next_CM_Get_DevNode_Registry_PropertyA
}, {
.name = "CM_Get_DevNode_Registry_PropertyW",
.patch = my_CM_Get_DevNode_Registry_PropertyW,
.link = (void **) &next_CM_Get_DevNode_Registry_PropertyW
},
{
}, {
.name = "CM_Get_Child",
.patch = my_CM_Get_Child,
.link = (void **) &next_CM_Get_Child
},
}, {
.name = "CM_Get_Parent",
.patch = my_CM_Get_Parent,
.link = (void **) &next_CM_Get_Parent
}, {
.name = "CM_Get_DevNode_Status",
.patch = my_CM_Get_DevNode_Status,
.link = (void **) &next_CM_Get_DevNode_Status
}, {
.name = "CM_Get_Device_IDA",
.patch = my_CM_Get_Device_IDA,
.link = (void **) &next_CM_Get_Device_IDA
}
};
HRESULT es3sec_hook_init(
@ -110,7 +196,9 @@ HRESULT es3sec_hook_init(
return hr;
}
hook_table_apply(NULL, "setupapi.dll", cm_syms, _countof(cm_syms));
es3sec_insert_hooks(NULL);
//hook_table_apply(NULL, "setupapi.dll", cm_syms, _countof(cm_syms));
proc_addr_table_push(NULL, "setupapi.dll", cm_syms, _countof(cm_syms));
CM_Locate_DevNodeW(&root_dev_inst, NULL, CM_LOCATE_DEVNODE_NORMAL);
@ -130,6 +218,14 @@ HRESULT es3sec_hook_init(
return S_OK;
}
void es3sec_insert_hooks(HMODULE target) {
hook_table_apply(
target,
"setupapi.dll",
cm_syms,
_countof(cm_syms));
}
static HRESULT es3sec_handle_hub_irp(struct irp *irp)
{
assert(irp != NULL);
@ -247,6 +343,8 @@ 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;
dprintf("ES3 Dongle: Request root hub\n");
if (irp->read.nbytes == sizeof(USB_ROOT_HUB_NAME)) { // Root hub name size
USB_ROOT_HUB_NAME rhub;
@ -489,6 +587,19 @@ static HRESULT es3sec_hub_connection_driver_key_name(struct irp *irp)
return hr;
}
static CONFIGRET my_CM_Get_DevNode_Registry_PropertyA(
DEVINST dnDevInst,
ULONG ulProperty,
PULONG pulRegDataType,
PVOID Buffer,
PULONG pulLength,
ULONG ulFlags)
{
dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyA\n");
return next_CM_Get_DevNode_Registry_PropertyA(dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
// return my_CM_Get_DevNode_Registry_PropertyW(dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
}
static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
DEVINST dnDevInst,
ULONG ulProperty,
@ -497,6 +608,8 @@ static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
PULONG pulLength,
ULONG ulFlags)
{
dprintf("ES3 Dongle: my_CM_Get_DevNode_Registry_PropertyW\n");
CONFIGRET cr = next_CM_Get_DevNode_Registry_PropertyW(dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
if (dnDevInst != HUB_DEVINST)
{
@ -525,6 +638,8 @@ static CONFIGRET my_CM_Get_DevNode_Registry_PropertyW(
static CONFIGRET my_CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
{
dprintf("ES3 Dongle: my_CM_Get_Child\n");
if (dnDevInst != root_dev_inst)
{
return next_CM_Get_Child(pdnDevInst, dnDevInst, ulFlags);
@ -533,3 +648,74 @@ static CONFIGRET my_CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG u
*pdnDevInst = HUB_DEVINST;
return CR_SUCCESS;
}
static CONFIGRET my_CM_Get_Parent(
PDEVINST pdnDevInst,
DEVINST dnDevInst,
ULONG ulFlags
)
{
dprintf("ES3 Dongle: my_CM_Get_Parent\n");
if (dnDevInst != HUB_DEVINST)
{
return next_CM_Get_Parent(pdnDevInst, dnDevInst, ulFlags);
}
*pdnDevInst = root_dev_inst;
return CR_SUCCESS;
}
static CONFIGRET my_CM_Get_DevNode_Status(
PULONG pulStatus,
PULONG pulProblemNumber,
DEVINST dnDevInst,
ULONG ulFlags
)
{
dprintf("ES3 Dongle: my_CM_Get_DevNode_Status\n");
if (dnDevInst != HUB_DEVINST)
{
return next_CM_Get_DevNode_Status(pulStatus, pulProblemNumber, dnDevInst, ulFlags);
}
*pulStatus = DN_DRIVER_LOADED;
*pulProblemNumber = 0;
return CR_SUCCESS;
}
static CONFIGRET my_CM_Get_Device_IDA(
DEVINST dnDevInst,
PSTR Buffer,
ULONG BufferLen,
ULONG ulFlags
)
{
dprintf("ES3 Dongle: my_CM_Get_Device_IDA\n");
if (dnDevInst != HUB_DEVINST)
{
return next_CM_Get_Device_IDA(dnDevInst, Buffer, BufferLen, ulFlags);
}
strcpy_s(Buffer, BufferLen, "USB\\ROOT_HUB");
return CR_SUCCESS;
}
static CONFIGRET my_CM_Get_Device_ID_Size(
PULONG pulLen,
DEVINST dnDevInst,
ULONG ulFlags
)
{
dprintf("ES3 Dongle: my_CM_Get_Device_ID_Size\n");
if (dnDevInst != HUB_DEVINST)
{
return next_CM_Get_Device_ID_Size(pulLen, dnDevInst, ulFlags);
}
*pulLen = 11;
return CR_SUCCESS;
}

View File

@ -13,3 +13,5 @@ HRESULT es3sec_hook_init(
USHORT pid,
const wchar_t *manufacturer,
const wchar_t *product);
void es3sec_insert_hooks(HMODULE target);

View File

@ -1,9 +1,16 @@
#include <windows.h>
#include "taikohook/config.h"
#include <stdlib.h>
#include "platform/es3sec.h"
#include "hook/table.h"
#include "hook/iohook.h"
#include "hooklib/dll.h"
#include "hooklib/path.h"
#include "hooklib/setupapi.h"
#include "hooklib/serial.h"
#include "hook/procaddr.h"
#include "util/dprintf.h"
@ -15,12 +22,41 @@
* that AMFW uses and let it talk to the game for us.
*/
HRESULT amfw_hook_init(wchar_t serial[13])
static const wchar_t *target_modules[] = {
L"nbamUsbfinder.dll",
L"bngrw.dll",
};
static const size_t target_modules_len = _countof(target_modules);
static void dll_hook_insert_hooks(HMODULE target);
static HMODULE WINAPI hook_LoadLibraryA(const char *name);
static HMODULE (WINAPI *next_LoadLibraryA)(const char *name);
static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name);
static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name);
static const struct hook_symbol kernel32_syms[] = {
{
.name = "LoadLibraryA",
.patch = hook_LoadLibraryA,
.link = (void **) &next_LoadLibraryA,
}, {
.name = "LoadLibraryW",
.patch = hook_LoadLibraryW,
.link = (void **) &next_LoadLibraryW,
}
};
HRESULT amfw_hook_init()
{
HANDLE hMod;
dprintf("AMFW: Init\n");
dll_hook_insert_hooks(NULL);
hMod = GetModuleHandle("AMFrameWork.dll");
if (hMod == NULL) {
@ -31,6 +67,105 @@ HRESULT amfw_hook_init(wchar_t serial[13])
dprintf("AMFW: Found AMFrameWork Handle\n");
path_hook_insert_hooks(hMod);
setupapi_hook_insert_hooks(hMod);
proc_addr_insert_hooks(hMod);
serial_hook_apply_hooks(hMod);
iohook_apply_hooks(hMod);
return S_OK;
}
static void dll_hook_insert_hooks(HMODULE target) {
hook_table_apply(
target,
"kernel32.dll",
kernel32_syms,
_countof(kernel32_syms));
}
static HMODULE WINAPI hook_LoadLibraryA(const char *name)
{
HMODULE result;
wchar_t *name_w;
size_t name_c;
if (name == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
mbstowcs_s(&name_c, NULL, 0, name, 0);
name_w = malloc(name_c * sizeof(wchar_t));
if (name_w == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return NULL;
}
mbstowcs_s(NULL, name_w, name_c, name, name_c - 1);
result = hook_LoadLibraryW(name_w);
free(name_w);
return result;
}
static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name)
{
const wchar_t *name_end;
const wchar_t *target_module;
bool already_loaded;
HMODULE result;
size_t name_len;
size_t target_module_len;
if (name == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
// Check if the module is already loaded
already_loaded = GetModuleHandleW(name) != NULL;
// Must call the next handler so the DLL reference count is incremented
result = next_LoadLibraryW(name);
if (!already_loaded && result != NULL) {
name_len = wcslen(name);
for (size_t i = 0; i < target_modules_len; i++) {
target_module = target_modules[i];
target_module_len = wcslen(target_module);
// Check if the newly loaded library is at least the length of
// the name of the target module
if (name_len < target_module_len) {
continue;
}
name_end = &name[name_len - target_module_len];
// Check if the name of the newly loaded library is one of the
// modules the path hooks should be injected into
if (_wcsicmp(name_end, target_module) != 0) {
continue;
}
dprintf("Taiko: Hooked %S\n", target_module);
dll_hook_insert_hooks(result);
path_hook_insert_hooks(result);
setupapi_hook_insert_hooks(result);
es3sec_insert_hooks(result);
serial_hook_apply_hooks(result);
iohook_apply_hooks(result);
}
}
return result;
}

View File

@ -1,4 +1,4 @@
#pragma once
#include <windows.h>
HRESULT amfw_hook_init(wchar_t *serial);
HRESULT amfw_hook_init();

View File

@ -71,7 +71,7 @@ static DWORD CALLBACK taiko_pre_startup(void)
ExitProcess(EXIT_FAILURE);
}
hr = amfw_hook_init(taiko_hook_cfg.platform.dongle.serial);
hr = amfw_hook_init();
if (FAILED(hr)) {
ExitProcess(EXIT_FAILURE);