diff --git a/saohook/config.c b/saohook/config.c index 5210e01..a541321 100644 --- a/saohook/config.c +++ b/saohook/config.c @@ -21,6 +21,37 @@ void sao_dll_config_load( filename); } +void systype_config_load( + struct systype_config *cfg, + const wchar_t *filename) +{ + cfg->enable = GetPrivateProfileIntW( + L"systype", + L"enable", + 1, + filename + ); + + cfg->type = GetPrivateProfileIntW( + L"systype", + L"type", + 0, + filename + ); +} + +void sao_touch_config_load( + struct sao_touch_config *cfg, + const wchar_t *filename) +{ + cfg->enable = GetPrivateProfileIntW( + L"touch", + L"enable", + 1, + filename + ); +} + void sao_hook_config_load( struct sao_hook_config *cfg, const wchar_t *filename) @@ -34,5 +65,6 @@ void sao_hook_config_load( qr_config_load(&cfg->qr, filename); bpreader_config_load(&cfg->reader, filename); usio_config_load(&cfg->usio, filename); - + systype_config_load(&cfg->systype, filename); + sao_touch_config_load(&cfg->touch, filename); } diff --git a/saohook/config.h b/saohook/config.h index c8b98aa..e20ef77 100644 --- a/saohook/config.h +++ b/saohook/config.h @@ -8,6 +8,8 @@ #include "gfxhook/config.h" #include "amcus/config.h" #include "board/config.h" +#include "saohook/systype.h" +#include "saohook/touch.h" struct sao_hook_config { struct platform_config platform; @@ -18,6 +20,8 @@ struct sao_hook_config { struct qr_config qr; struct bpreader_config reader; struct usio_config usio; + struct systype_config systype; + struct sao_touch_config touch; }; void sao_dll_config_load( @@ -32,3 +36,11 @@ void sao_hook_config_load( struct sao_hook_config *cfg, const wchar_t *filename); +void systype_config_load( + struct systype_config *cfg, + const wchar_t *filename); + +void sao_touch_config_load( + struct sao_touch_config *cfg, + const wchar_t *filename); + diff --git a/saohook/dllmain.c b/saohook/dllmain.c index 0d6387d..e8dba61 100644 --- a/saohook/dllmain.c +++ b/saohook/dllmain.c @@ -5,6 +5,8 @@ #include "saohook/sao-dll.h" #include "saohook/usio.h" #include "saohook/unity.h" +#include "saohook/systype.h" +#include "saohook/touch.h" #include "amcus/amcus.h" @@ -75,6 +77,18 @@ static DWORD CALLBACK sao_pre_startup(void) ExitProcess(EXIT_FAILURE); } + hr = systype_hook_init(&sao_hook_cfg.systype, &sao_hook_cfg.platform.dongle); + + if (FAILED(hr)) { + ExitProcess(EXIT_FAILURE); + } + + hr = sao_touch_hook_init(&sao_hook_cfg.touch); + + if (FAILED(hr)) { + ExitProcess(EXIT_FAILURE); + } + unity_hook_init(); gfx_hook_init(&sao_hook_cfg.gfx); diff --git a/saohook/meson.build b/saohook/meson.build index 7f58ec9..e1ef0e8 100644 --- a/saohook/meson.build +++ b/saohook/meson.build @@ -26,6 +26,10 @@ shared_library( 'config.h', 'sao-dll.c', 'sao-dll.h', + 'systype.c', + 'systype.h', + 'touch.c', + 'touch.h', 'usio.c', 'usio.h', 'unity.c', diff --git a/saohook/systype.c b/saohook/systype.c new file mode 100644 index 0000000..1787316 --- /dev/null +++ b/saohook/systype.c @@ -0,0 +1,109 @@ +#include + +#include "hook/table.h" +#include "hooklib/reg.h" +#include "hooklib/procaddr.h" +#include "util/dprintf.h" +#include "saohook/systype.h" +#include "platform/es3sec.h" + +const wchar_t *cpu_name_client = L"Intel(R) Genuine Snake Oil"; +const wchar_t *cpu_name_terminal = L"AMD(R) Certified Abacus"; +static bool is_terminal = false; +static struct es3sec_config dong_config; +static HRESULT systype_read_cpu_name(void *bytes, uint32_t *nbytes); +static BOOL my_GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer); +static BOOL (*next_GlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer); + +static int my_GetSerialNumber(ULONG usercode, intptr_t serialnumber); +static int (*next_GetSerialNumber)(ULONG usercode, intptr_t serialnumber); + +const struct reg_hook_val sys_info_reg[] = { + { + .name = L"ProcessorNameString", + .type = REG_SZ, + .read = systype_read_cpu_name + } +}; + +static const struct hook_symbol systype_kernel32_syms[] = { + { + .name = "GlobalMemoryStatusEx", + .patch = my_GlobalMemoryStatusEx, + .link = (void **) &next_GlobalMemoryStatusEx, + }, +}; + +static struct hook_symbol procaddr_dong_syms[] = { + { + .name = "GetSerialNumber", + .patch = my_GetSerialNumber, + .link = (void **) &next_GetSerialNumber, + }, +}; + +HRESULT systype_hook_init(const struct systype_config *sys_cfg, const struct es3sec_config *dong_cfg) +{ + HRESULT hr = S_OK; + if (!sys_cfg->enable) { + return hr; + } + + is_terminal = sys_cfg->type; + memcpy(&dong_config, dong_cfg, sizeof(*dong_cfg)); + + hr = reg_hook_push_key( + HKEY_LOCAL_MACHINE, + L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", + sys_info_reg, + _countof(sys_info_reg)); + + hook_table_apply( + NULL, + "kernel32.dll", + systype_kernel32_syms, + _countof(systype_kernel32_syms)); + + proc_addr_table_push( + NULL, + "nbamUsbFinder_sup.dll", + procaddr_dong_syms, + _countof(procaddr_dong_syms) + ); + + dprintf("Systype: Init\n"); + return hr; +} + +static HRESULT systype_read_cpu_name(void *bytes, uint32_t *nbytes) +{ + dprintf("Systype: Read CPU Name\n"); + if (!is_terminal) { + return reg_hook_read_wstr(bytes, nbytes, cpu_name_client); + } + return reg_hook_read_wstr(bytes, nbytes, cpu_name_terminal); +} + +static BOOL my_GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) +{ + dprintf("Systype: Get RAM Size\n"); + BOOL ret = next_GlobalMemoryStatusEx(lpBuffer); + if (!ret) { + dprintf("Systype: next_GlobalMemoryStatusEx failed!\n"); + return ret; + } + + if (!is_terminal) { + lpBuffer->ullTotalPhys = (DWORDLONG) 8000 << 20; + } else { + lpBuffer->ullTotalPhys = (DWORDLONG) 4000 << 20; + } + return true; +} + +static int my_GetSerialNumber(ULONG usercode, intptr_t serialnumber) +{ + wcstombs((char *)serialnumber, dong_config.serial, 32); + dprintf("Systype: my_GetSerialNumber %ls\n", dong_config.serial); + return 0; +} \ No newline at end of file diff --git a/saohook/systype.h b/saohook/systype.h new file mode 100644 index 0000000..371e348 --- /dev/null +++ b/saohook/systype.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include +#include "platform/es3sec.h" + +enum SAO_SYS_TYPE { + CLIENT, + TERMINAL +}; + +struct systype_config { + bool enable; + enum SAO_SYS_TYPE type; +}; + +HRESULT systype_hook_init(const struct systype_config *sys_cfg, const struct es3sec_config *dong_cfg); diff --git a/saohook/touch.c b/saohook/touch.c new file mode 100644 index 0000000..3c6665d --- /dev/null +++ b/saohook/touch.c @@ -0,0 +1,40 @@ +#include + +#include "hook/table.h" +#include "hooklib/reg.h" +#include "util/dprintf.h" +#include "saohook/touch.h" + +static int WINAPI my_GetSystemMetrics(int nIndex); +static int (WINAPI *next_GetSystemMetrics)(int nIndex); + +static const struct hook_symbol touch_user32_syms[] = { + { + .name = "GetSystemMetrics", + .patch = my_GetSystemMetrics, + .link = (void **) &next_GetSystemMetrics, + }, +}; + +HRESULT sao_touch_hook_init(const struct sao_touch_config *cfg) +{ + if (!cfg->enable) { + return S_OK; + } + + hook_table_apply( + NULL, + "User32.dll", + touch_user32_syms, + _countof(touch_user32_syms)); + + return S_OK; +} + +static int WINAPI my_GetSystemMetrics(int nIndex) +{ + if (nIndex == SM_DIGITIZER) { + return NID_MULTI_INPUT; + } + return next_GetSystemMetrics(nIndex); +} diff --git a/saohook/touch.h b/saohook/touch.h new file mode 100644 index 0000000..8975d73 --- /dev/null +++ b/saohook/touch.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include + +struct sao_touch_config { + bool enable; +}; + +HRESULT sao_touch_hook_init(const struct sao_touch_config *cfg); \ No newline at end of file diff --git a/saohook/unity.c b/saohook/unity.c index ad65147..ec2014d 100644 --- a/saohook/unity.c +++ b/saohook/unity.c @@ -8,9 +8,12 @@ #include "hooklib/dll.h" #include "hooklib/path.h" #include "hooklib/serial.h" +#include "hooklib/reg.h" +#include "hooklib/procaddr.h" #include "amcus/amcus.h" #include "board/usio.h" +#include "platform/epay.h" #include "util/dprintf.h" @@ -33,7 +36,13 @@ static const wchar_t *target_modules[] = { L"bnAMPF.dll", L"bnReader.dll", }; + +static const wchar_t *dep_hooks[] = { + L"libamw.dll", +}; + static const size_t target_modules_len = _countof(target_modules); +static const size_t dep_hooks_len = _countof(dep_hooks); void unity_hook_init(void) { @@ -53,10 +62,13 @@ static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name) { const wchar_t *name_end; const wchar_t *target_module; + const wchar_t *target_dep; bool already_loaded; HMODULE result; + HMODULE dep_mod; size_t name_len; size_t target_module_len; + size_t dep_len; if (name == NULL) { SetLastError(ERROR_INVALID_PARAMETER); @@ -96,9 +108,22 @@ static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name) dll_hook_insert_hooks(result); path_hook_insert_hooks(result); amcus_insert_hooks(result); + reg_hook_apply_hooks(result); usio_hook_proc_addr(result); - iohook_apply_hooks(result); - serial_hook_apply_hooks(result); + proc_addr_insert_hooks(result); + } + + for (size_t i = 0; i < dep_hooks_len; i++) { + target_dep = dep_hooks[i]; + + dep_mod = GetModuleHandleW(target_dep); + if (dep_mod != NULL) { + dprintf("Unity: Hook dependency %ls\n", target_dep); + iohook_apply_hooks(dep_mod); + serial_hook_apply_hooks(dep_mod); + reg_hook_apply_hooks(dep_mod); + epay_insert_hook(dep_mod); + } } }