From 8081793a5fc732a6e0bfb52ea19360c172b1dc07 Mon Sep 17 00:00:00 2001 From: 2d9f8a0741a7573b189035dcb819847ecb5d981d <2d9f8a0741a7573b189035dcb819847ecb5d981d@redacted> Date: Mon, 13 Jun 2022 00:27:53 +0900 Subject: [PATCH] iidxhook4-cn: Add support for IIDX Resort Anthem CN * Exe based game * No network functionality * No card readers checked/used --- Module.mk | 17 ++ dist/iidx/gamestart-18-cn.bat | 14 ++ dist/iidx/iidxhook-18-cn.conf | 47 ++++++ doc/architecture.md | 18 ++ doc/iidxhook/README.md | 1 + doc/iidxhook/iidxhook4-cn.md | 13 ++ src/imports/import_32_1101_avs.def | 1 + src/main/iidxhook4-cn/Module.mk | 26 +++ src/main/iidxhook4-cn/avs-boot.c | 103 ++++++++++++ src/main/iidxhook4-cn/avs-boot.h | 10 ++ src/main/iidxhook4-cn/dllmain.c | 223 +++++++++++++++++++++++++ src/main/iidxhook4-cn/iidxhook4-cn.def | 4 + src/main/iidxhook4-cn/path.c | 156 +++++++++++++++++ src/main/iidxhook4-cn/path.h | 6 + 14 files changed, 639 insertions(+) create mode 100644 dist/iidx/gamestart-18-cn.bat create mode 100644 dist/iidx/iidxhook-18-cn.conf create mode 100644 doc/iidxhook/iidxhook4-cn.md create mode 100644 src/main/iidxhook4-cn/Module.mk create mode 100644 src/main/iidxhook4-cn/avs-boot.c create mode 100644 src/main/iidxhook4-cn/avs-boot.h create mode 100644 src/main/iidxhook4-cn/dllmain.c create mode 100644 src/main/iidxhook4-cn/iidxhook4-cn.def create mode 100644 src/main/iidxhook4-cn/path.c create mode 100644 src/main/iidxhook4-cn/path.h diff --git a/Module.mk b/Module.mk index d602984..7d4f9e8 100644 --- a/Module.mk +++ b/Module.mk @@ -136,6 +136,7 @@ include src/main/iidxhook1/Module.mk include src/main/iidxhook2/Module.mk include src/main/iidxhook3/Module.mk include src/main/iidxhook4/Module.mk +include src/main/iidxhook4-cn/Module.mk include src/main/iidxhook5/Module.mk include src/main/iidxhook5-cn/Module.mk include src/main/iidxhook6/Module.mk @@ -312,6 +313,21 @@ $(zipdir)/iidx-18.zip: \ $(V)echo ... $@ $(V)zip -j $@ $^ +$(zipdir)/iidx-18-cn.zip: \ + build/bin/avs2_1101-32/iidxhook4-cn.dll \ + build/bin/indep-32/config.exe \ + build/bin/indep-32/geninput.dll \ + build/bin/indep-32/iidxio.dll \ + build/bin/indep-32/vefxio.dll \ + build/bin/indep-32/inject.exe \ + dist/iidx/config.bat \ + dist/iidx/gamestart-18-cn.bat \ + dist/iidx/iidxhook-18-cn.conf \ + dist/iidx/vefx.txt \ + | $(zipdir)/ + $(V)echo ... $@ + $(V)zip -j $@ $^ + $(zipdir)/iidx-19.zip: \ build/bin/avs2_1304-32/iidxhook5.dll \ build/bin/avs2_1304-32/launcher.exe \ @@ -779,6 +795,7 @@ $(BUILDDIR)/bemanitools.zip: \ $(zipdir)/iidx-13.zip \ $(zipdir)/iidx-14-to-17.zip \ $(zipdir)/iidx-18.zip \ + $(zipdir)/iidx-18-cn.zip \ $(zipdir)/iidx-19.zip \ $(zipdir)/iidx-20.zip \ $(zipdir)/iidx-20-cn.zip \ diff --git a/dist/iidx/gamestart-18-cn.bat b/dist/iidx/gamestart-18-cn.bat new file mode 100644 index 0000000..4657184 --- /dev/null +++ b/dist/iidx/gamestart-18-cn.bat @@ -0,0 +1,14 @@ +@echo off + +cd /d %~dp0 + +if not exist d mkdir d +if not exist e mkdir e +if not exist f mkdir f + +if not exist e\avs_conf mkdir e\avs_conf +if not exist e\avs_conf\CONF mkdir e\avs_conf\CONF +if not exist e\avs_conf\CONF\NVRAM mkdir e\avs_conf\CONF\NVRAM +if not exist e\avs_conf\CONF\RAW mkdir e\avs_conf\CONF\RAW + +inject iidxhook4-cn.dll bm2dx.exe -D --config iidxhook-18-cn.conf %* diff --git a/dist/iidx/iidxhook-18-cn.conf b/dist/iidx/iidxhook-18-cn.conf new file mode 100644 index 0000000..e246f42 --- /dev/null +++ b/dist/iidx/iidxhook-18-cn.conf @@ -0,0 +1,47 @@ +# PCBID +eamuse.pcbid=0101020304050607086F + +# Fix stretched BG videos on newer GPUs. Might appear on Red and newer +gfx.bgvideo_uv_fix=false + +# Run the game in a framed window (requires windowed option) +gfx.framed=false + +# Software limit the frame rate of the rendering loop in hz, e.g. 60 or 59.95 (0.0 = no software limit) +gfx.frame_rate_limit=0.0 + +# Enable/disable software monitor check/auto timebase or set a pre-determined refresh value. -1 disables this feature. 0 enables auto detecting the current refresh rate on startup. Setting any positive value > 0 allows you to set a pre-determined refresh rate (e.g. retrieved from the monitor check on newer IIDX games). Either the auto detected value or pre-determined value is used to patch any chart files in-memory to fix song synchronization issues. Requires constant refresh rate!!! +gfx.monitor_check=-1.000000 + +# Patch the GPU device ID detection (leave empty to disable), format XXXX:YYYY, two 4 digit hex numbers (vid:pid). Examples: 1002:7146 (RV515, Radeon X1300), 1002:95C5 (RV620 LE, Radeon HD3450) +gfx.pci_id=1002:7146 + +# Run the game windowed +gfx.windowed=false + +# Windowed width, 0 for default size +gfx.window_width=0 + +# Windowed height, 0 for default size +gfx.window_height=0 + +# Up-/downscale the back buffer's width. This does not change the game's rendering resolution but scales the final frame. Use this to target the native resolution of your monitor/TV, e.g. to avoid over-/underscan, bad image quality or latency caused by the monitors internal upscaler. 0 to disable this feature. Must be set in combination with the corresponding height parameter. +gfx.scale_back_buffer_width=0 + +# Up-/downscale the back buffer's height. This does not change the game's rendering resolution but scales the final frame. Use this to target the native resolution of your monitor/TV, e.g. to avoid over-/underscan, bad image quality or latency caused by the monitors internal upscaler. 0 to disable this feature. Must be set in combination with the corresponding width parameter. +gfx.scale_back_buffer_height=0 + +# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation). +gfx.scale_back_buffer_filter=none + +# Forced refresh rate, -1 to not force any (try 59 or 60 if monitor check fails to lock on high refresh rate monitors) +gfx.forced_refresh_rate=-1 + +# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter +gfx.device_adapter=-1 + +# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware +io.disable_io_emu=false + +# Security black plug mcode id string (e.g. GQC02JAA). +sec.black_plug_mcode=GKJDZCAA diff --git a/doc/architecture.md b/doc/architecture.md index 9857965..40708a8 100644 --- a/doc/architecture.md +++ b/doc/architecture.md @@ -127,6 +127,15 @@ TODO go into some more detail about some differences in the hook modules, e.g. 1 * Font patching for Japanese chars * Filesystem patches to detour E and F backup drives for settings +#### iidxhook4-cn (18 CN) +* Ezusb IO2 I/O emulation + * Setupapi emulation + * Full security emulation with SRAM and round plugs + * Full game essential I/O emulation +* d3d9 patching and extended features +* Font patching for Japanese chars +* Filesystem patches to detour E and F backup drives for settings + #### iidxhook5 (19) * Ezusb IO2 I/O emulation * Setupapi emulation @@ -136,6 +145,15 @@ TODO go into some more detail about some differences in the hook modules, e.g. 1 * Font patching for Japanese chars * Filesystem patches to detour E and F backup drives for settings +#### iidxhook5-cn (20 CN) +* Ezusb IO2 I/O emulation + * Setupapi emulation + * Full security emulation with SRAM and round plugs + * Full game essential I/O emulation +* d3d9 patching and extended features +* Font patching for Japanese chars +* Filesystem patches to detour E and F backup drives for settings + #### iidxhook6 (20) * Ezusb IO2 I/O emulation * Setupapi emulation diff --git a/doc/iidxhook/README.md b/doc/iidxhook/README.md index 784dbfb..aeee6c2 100644 --- a/doc/iidxhook/README.md +++ b/doc/iidxhook/README.md @@ -17,6 +17,7 @@ games: * [iidxhook2](iidxhook2.md): DistorteD * [iidxhook3](iidxhook3.md): GOLD, DJ TROOPERS, EMPRESS, SIRIUS * [iidxhook4](iidxhook4.md): Resort Anthem +* [iidxhook4-cn](iidxhook4-cn.md): Resort Anthem CN (狂热节拍 IIDX) * [iidxhook5](iidxhook5.md): Lincle * [iidxhook5-cn](iidxhook5-cn.md): tricoro CN (狂热节拍 IIDX 2) * [iidxhook6](iidxhook6.md): Tricoro diff --git a/doc/iidxhook/iidxhook4-cn.md b/doc/iidxhook/iidxhook4-cn.md new file mode 100644 index 0000000..8205184 --- /dev/null +++ b/doc/iidxhook/iidxhook4-cn.md @@ -0,0 +1,13 @@ +# Game list + +The following games are compatible with this version of iidxhook: +* Resort Anthem CN (狂热节拍 IIDX) + +The games must be bootstrapped using [inject.exe](../inject.md). + +# Remarks + +Resort Anthem CN (狂热节拍 IIDX): + +* Does not have NETWORK function +* Game doesn't used card readers diff --git a/src/imports/import_32_1101_avs.def b/src/imports/import_32_1101_avs.def index 1b63626..cfc6f9b 100644 --- a/src/imports/import_32_1101_avs.def +++ b/src/imports/import_32_1101_avs.def @@ -18,6 +18,7 @@ EXPORTS property_destroy @247 NONAME property_insert_read @255 NONAME property_node_create @266 NONAME + property_node_datasize @267 NONAME property_node_refer @278 NONAME property_node_remove @279 NONAME property_psmap_import @288 NONAME diff --git a/src/main/iidxhook4-cn/Module.mk b/src/main/iidxhook4-cn/Module.mk new file mode 100644 index 0000000..b02bb82 --- /dev/null +++ b/src/main/iidxhook4-cn/Module.mk @@ -0,0 +1,26 @@ +avsdlls += iidxhook4-cn + +ldflags_iidxhook4-cn := \ + -liphlpapi \ + +deplibs_iidxhook4-cn := \ + avs \ + +libs_iidxhook4-cn := \ + iidxhook-util \ + ezusb-emu \ + ezusb2-emu \ + ezusb2-iidx-emu \ + ezusb-iidx-emu \ + security \ + hook \ + hooklib \ + iidxio \ + cconfig \ + util \ + ezusb \ + +src_iidxhook4-cn := \ + avs-boot.c \ + path.c \ + dllmain.c \ diff --git a/src/main/iidxhook4-cn/avs-boot.c b/src/main/iidxhook4-cn/avs-boot.c new file mode 100644 index 0000000..378d80c --- /dev/null +++ b/src/main/iidxhook4-cn/avs-boot.c @@ -0,0 +1,103 @@ +#define LOG_MODULE "avs-boot" + +#include +#include + +#include "hook/table.h" + +#include "imports/avs.h" + +#include "iidxhook4-cn/avs-boot.h" + +#include "util/log.h" + +static void (*real_avs_boot)( + struct property_node *config, + void *std_heap, + size_t sz_std_heap, + void *avs_heap, + size_t sz_avs_heap, + avs_log_writer_t log_writer, + void *log_context); + +static void my_avs_boot( + struct property_node *config, + void *std_heap, + size_t sz_std_heap, + void *avs_heap, + size_t sz_avs_heap, + avs_log_writer_t log_writer, + void *log_context); + +static const struct hook_symbol iidxhook4_cn_log_hook_syms[] = { + {.name = "avs_boot", + .patch = my_avs_boot, + .link = (void **) &real_avs_boot}, +}; + +static void avs_boot_replace_property_uint32( + struct property_node *node, const char *name, uint32_t val) +{ + struct property_node *tmp; + + tmp = property_search(NULL, node, name); + + if (tmp) { + property_node_remove(tmp); + } + + property_node_create(NULL, node, PSMAP_TYPE_U32, name, val); +} + +static void avs_boot_replace_property_str( + struct property_node *node, const char *name, const char *val) +{ + struct property_node *tmp; + + tmp = property_search(NULL, node, name); + + if (tmp) { + property_node_remove(tmp); + } + + tmp = property_node_create(NULL, node, PROPERTY_TYPE_STR, name, val); + + if (tmp) { + property_node_datasize(tmp); + } +} + +static void my_avs_boot( + struct property_node *config, + void *std_heap, + size_t sz_std_heap, + void *avs_heap, + size_t sz_avs_heap, + avs_log_writer_t log_writer, + void *log_context) +{ + log_info("Called my_avs_boot"); + + avs_boot_replace_property_uint32(config, "log/level", 4); + avs_boot_replace_property_str(config, "fs/root/device", "."); + + real_avs_boot( + config, + std_heap, + sz_std_heap, + avs_heap, + sz_avs_heap, + log_writer_debug, + NULL); +} + +void iidxhook4_cn_avs_boot_init() +{ + hook_table_apply( + NULL, + "libavs-win32.dll", + iidxhook4_cn_log_hook_syms, + lengthof(iidxhook4_cn_log_hook_syms)); + + log_info("Inserted avs log hooks"); +} diff --git a/src/main/iidxhook4-cn/avs-boot.h b/src/main/iidxhook4-cn/avs-boot.h new file mode 100644 index 0000000..f2d652e --- /dev/null +++ b/src/main/iidxhook4-cn/avs-boot.h @@ -0,0 +1,10 @@ +#ifndef IIDXHOOK4_CN_AVS_BOOT_H +#define IIDXHOOK4_CN_AVS_BOOT_H + +/** + * Initialize hooking of avs_boot. This re-enables avs logging + * and injects a few important settings. + */ +void iidxhook4_cn_avs_boot_init(); + +#endif diff --git a/src/main/iidxhook4-cn/dllmain.c b/src/main/iidxhook4-cn/dllmain.c new file mode 100644 index 0000000..40ae23b --- /dev/null +++ b/src/main/iidxhook4-cn/dllmain.c @@ -0,0 +1,223 @@ +#include + +#include +#include +#include +#include + +#include "bemanitools/iidxio.h" + +#include "cconfig/cconfig-hook.h" + +#include "ezusb-iidx-emu/node-security-plug.h" + +#include "ezusb2-emu/desc.h" +#include "ezusb2-emu/device.h" + +#include "ezusb2-iidx-emu/msg.h" + +#include "hook/table.h" + +#include "hooklib/acp.h" +#include "hooklib/setupapi.h" + +#include "iidxhook4-cn/avs-boot.h" +#include "iidxhook4-cn/path.h" + +#include "iidxhook-util/chart-patch.h" +#include "iidxhook-util/config-eamuse.h" +#include "iidxhook-util/config-gfx.h" +#include "iidxhook-util/config-io.h" +#include "iidxhook-util/config-sec.h" +#include "iidxhook-util/d3d9.h" +#include "iidxhook-util/settings.h" + +#include "security/rp-sign-key.h" + +#include "imports/avs.h" + +#include "util/log.h" + +#define IIDXHOOK4_CN_INFO_HEADER \ + "iidxhook for Resort Anthem CN" \ + ", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV) +#define IIDXHOOK4_CN_CMD_USAGE \ + "Usage: inject.exe iidxhook4-cn.dll [options...]" + +static HANDLE STDCALL my_OpenProcess(DWORD, BOOL, DWORD); +static HANDLE(STDCALL *real_OpenProcess)(DWORD, BOOL, DWORD); +static bool iidxhook_init_check; + +static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = { + iidxhook_util_d3d9_irp_handler, +}; + +static const struct hook_symbol init_hook_syms[] = { + {.name = "OpenProcess", + .patch = my_OpenProcess, + .link = (void **) &real_OpenProcess}, +}; + +static struct iidxhook_config_io config_io; + +static void +iidxhook4_cn_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx) +{ + struct iidxhook_util_d3d9_config d3d9_config; + + iidxhook_util_d3d9_init_config(&d3d9_config); + + d3d9_config.windowed = config_gfx->windowed; + d3d9_config.framed = config_gfx->framed; + d3d9_config.override_window_width = config_gfx->window_width; + d3d9_config.override_window_height = config_gfx->window_height; + d3d9_config.framerate_limit = config_gfx->frame_rate_limit; + d3d9_config.pci_vid = config_gfx->pci_id_vid; + d3d9_config.pci_pid = config_gfx->pci_id_pid; + d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width; + d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height; + d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter; + d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate; + d3d9_config.device_adapter = config_gfx->device_adapter; + /* Required for GOLD (and newer?) to not crash with NVIDIA cards */ + d3d9_config.iidx14_to_19_nvidia_fix = true; + + if (config_gfx->monitor_check == 0) { + log_info("Auto monitor check enabled"); + + d3d9_config.iidx09_to_19_monitor_check_cb = + iidxhook_util_chart_patch_set_refresh_rate; + iidxhook_util_chart_patch_init( + IIDXHOOK_UTIL_CHART_PATCH_TIMEBASE_14_TO_18_VGA); + } else if (config_gfx->monitor_check > 0) { + log_info( + "Manual monitor check, resulting refresh rate: %f", + config_gfx->monitor_check); + + iidxhook_util_chart_patch_init( + IIDXHOOK_UTIL_CHART_PATCH_TIMEBASE_14_TO_18_VGA); + iidxhook_util_chart_patch_set_refresh_rate(config_gfx->monitor_check); + } + + iidxhook_util_d3d9_configure(&d3d9_config); + + hook_d3d9_init(iidxhook_d3d9_handlers, lengthof(iidxhook_d3d9_handlers)); +} + +/** + * This seems to be a good entry point to intercept + * before the game calls anything important + */ +static HANDLE STDCALL +my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId) +{ + struct cconfig *config; + + struct iidxhook_util_config_eamuse config_eamuse; + struct iidxhook_config_gfx config_gfx; + struct iidxhook_config_sec config_sec; + + if (iidxhook_init_check) { + return real_OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); + } + + iidxhook_init_check = true; + + log_info("-------------------------------------------------------------"); + log_info("--------------- Begin iidxhook my_OpenProcess ---------------"); + log_info("-------------------------------------------------------------"); + + config = cconfig_init(); + + iidxhook_util_config_eamuse_init(config); + iidxhook_config_gfx_init(config); + iidxhook_config_io_init(config); + iidxhook_config_sec_init(config); + + if (!cconfig_hook_config_init( + config, + IIDXHOOK4_CN_INFO_HEADER "\n" IIDXHOOK4_CN_CMD_USAGE, + CCONFIG_CMD_USAGE_OUT_DBG)) { + cconfig_finit(config); + exit(EXIT_FAILURE); + } + + iidxhook_util_config_eamuse_get(&config_eamuse, config); + iidxhook_config_gfx_get(&config_gfx, config); + iidxhook_config_io_get(&config_io, config); + iidxhook_config_sec_get(&config_sec, config); + + cconfig_finit(config); + + log_info(IIDXHOOK4_CN_INFO_HEADER); + log_info("Initializing iidxhook..."); + + /** + * This game is using a black round plug for game license management instead of a black usb dongle. + * No white dongle hooks applies since the game does not have network functionality. + * Also, card readers are not used/checked; no card reader hooks required. + */ + ezusb_iidx_emu_node_security_plug_set_boot_version( + &config_sec.boot_version); + ezusb_iidx_emu_node_security_plug_set_boot_seeds(config_sec.boot_seeds); + ezusb_iidx_emu_node_security_plug_set_plug_black_sign_key( + &security_rp_sign_key_black_iidx); + ezusb_iidx_emu_node_security_plug_set_plug_black_mcode( + &config_sec.black_plug_mcode); + ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid); + + iidxhook4_cn_setup_d3d9_hooks(&config_gfx); + + if (!config_io.disable_io_emu) { + log_info("Starting IIDX IO backend"); + + iidx_io_set_loggers( + log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal); + + if (!iidx_io_init( + avs_thread_create, avs_thread_join, avs_thread_destroy)) { + log_fatal("Initializing IIDX IO backend failed"); + } + } else { + log_info("IIDX IO emulation backend disabled"); + } + + /* Set up IO emulation hooks _after_ IO API setup to allow + API implementations with real IO devices */ + iohook_push_handler(ezusb2_emu_device_dispatch_irp); + iohook_push_handler(iidxhook_util_chart_patch_dispatch_irp); + iohook_push_handler(settings_hook_dispatch_irp); + + if (!config_io.disable_io_emu) { + hook_setupapi_init(&ezusb2_emu_desc_device.setupapi); + ezusb2_emu_device_hook_init(ezusb2_iidx_emu_msg_init()); + } + + log_info("-------------------------------------------------------------"); + log_info("---------------- End iidxhook my_OpenProcess ----------------"); + log_info("-------------------------------------------------------------"); + + return real_OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); +} + +/** + * Hook library for Resort Anthem CN + */ +BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx) +{ + if (reason != DLL_PROCESS_ATTACH) { + return TRUE; + } + + log_to_writer(log_writer_debug, NULL); + + hook_table_apply( + NULL, "kernel32.dll", init_hook_syms, lengthof(init_hook_syms)); + + iidxhook4_cn_path_init(); + iidxhook4_cn_avs_boot_init(); + acp_hook_init(); + settings_hook_init(); + + return TRUE; +} diff --git a/src/main/iidxhook4-cn/iidxhook4-cn.def b/src/main/iidxhook4-cn/iidxhook4-cn.def new file mode 100644 index 0000000..55cc115 --- /dev/null +++ b/src/main/iidxhook4-cn/iidxhook4-cn.def @@ -0,0 +1,4 @@ +LIBRARY iidxhook4-cn + +EXPORTS + DllMain@12 @1 NONAME diff --git a/src/main/iidxhook4-cn/path.c b/src/main/iidxhook4-cn/path.c new file mode 100644 index 0000000..bf96a4c --- /dev/null +++ b/src/main/iidxhook4-cn/path.c @@ -0,0 +1,156 @@ +#define LOG_MODULE "path" + +#include +#include +#include + +#include "hook/table.h" + +#include "iidxhook4-cn/path.h" + +#include "util/log.h" +#include "util/str.h" + +#define PATH_A "D:/JDZ-001/contents/" +#define PATH_W L"D:/JDZ-001/contents/" + +static HANDLE WINAPI my_CreateFileA( + LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); +static HANDLE(WINAPI *real_CreateFileA)( + LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); + +static HANDLE WINAPI my_CreateFileW( + LPCWSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); +static HANDLE(WINAPI *real_CreateFileW)( + LPCWSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); + +static HANDLE WINAPI my_FindFirstFileA( + LPCSTR lpFileName, + LPWIN32_FIND_DATAA lpFindFileData); +static HANDLE(WINAPI *real_FindFirstFileA)( + LPCSTR lpFileName, + LPWIN32_FIND_DATAA lpFindFileData); + +static const struct hook_symbol iidxhook4_cn_path_hook_syms[] = { + {.name = "CreateFileA", + .patch = my_CreateFileA, + .link = (void **) &real_CreateFileA}, + {.name = "CreateFileW", + .patch = my_CreateFileW, + .link = (void **) &real_CreateFileW}, + {.name = "FindFirstFileA", + .patch = my_FindFirstFileA, + .link = (void **) &real_FindFirstFileA}, +}; + +static HANDLE WINAPI my_CreateFileA( + LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + if (lpFileName != NULL && strstr(lpFileName, PATH_A) == lpFileName) { + char relative_path[MAX_PATH] = "."; + str_cat(relative_path, MAX_PATH, lpFileName + strlen(PATH_A) - 1); + return real_CreateFileA( + relative_path, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + } + + return real_CreateFileA( + lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); +} + +static HANDLE WINAPI my_CreateFileW( + LPCWSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + if (lpFileName != NULL && wcsstr(lpFileName, PATH_W) == lpFileName) { + wchar_t relative_path[MAX_PATH] = L"."; + wstr_cat(relative_path, MAX_PATH, lpFileName + wcslen(PATH_W) - 1); + return real_CreateFileW( + relative_path, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + } + + return real_CreateFileW( + lpFileName, + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); +} + +static HANDLE WINAPI my_FindFirstFileA( + LPCSTR lpFileName, + LPWIN32_FIND_DATAA lpFindFileData) +{ + if (lpFileName != NULL && strstr(lpFileName, PATH_A) == lpFileName) { + char relative_path[MAX_PATH] = "."; + str_cat(relative_path, MAX_PATH, lpFileName + strlen(PATH_A) - 1); + return real_FindFirstFileA(relative_path, lpFindFileData); + } + + return real_FindFirstFileA(lpFileName, lpFindFileData); +} + +void iidxhook4_cn_path_init() +{ + hook_table_apply( + NULL, + "kernel32.dll", + iidxhook4_cn_path_hook_syms, + lengthof(iidxhook4_cn_path_hook_syms)); + + log_info("Inserted path hooks"); +} diff --git a/src/main/iidxhook4-cn/path.h b/src/main/iidxhook4-cn/path.h new file mode 100644 index 0000000..0105d65 --- /dev/null +++ b/src/main/iidxhook4-cn/path.h @@ -0,0 +1,6 @@ +#ifndef IIDXHOOK4_CN_PATH_H +#define IIDXHOOK4_CN_PATH_H + +void iidxhook4_cn_path_init(); + +#endif