#include "ddrhook1/master.h" #include "ddrhook-util/dinput.h" #include "ddrhook-util/gfx.h" #include "ddrhook-util/monitor.h" #include "hook/table.h" #include "p3ioemu/devmgr.h" #include "util/defs.h" #include "util/log.h" static HMODULE(STDCALL *real_LoadLibraryA)(const char *name); static BOOL(STDCALL *real_IsDebuggerPresent)(); static HMODULE STDCALL my_LoadLibraryA(const char *name); static BOOL STDCALL my_IsDebuggerPresent(); static const struct hook_symbol master_kernel32_syms[] = { { .name = "LoadLibraryA", .patch = my_LoadLibraryA, .link = (void **) &real_LoadLibraryA, }, { .name = "IsDebuggerPresent", .patch = my_IsDebuggerPresent, .link = (void **) &real_IsDebuggerPresent, }, }; static BOOL STDCALL my_IsDebuggerPresent() { // DDR X has different code paths for when a debugger is attached, // but we want the normal path and not the debugger path. // The biggest noticeable difference is that when a debugger is attached // it will show fway.mpg (a car driving) instead of the sky background // on the menus. return FALSE; } static HMODULE STDCALL my_LoadLibraryA(const char *name) { HMODULE result; result = GetModuleHandleA(name); if (result != NULL) { log_misc("LoadLibraryA(%s) -> %p [already loaded]", name, result); return result; } result = real_LoadLibraryA(name); log_misc("LoadLibraryA(%s) -> %p [newly loaded]", name, result); if (result == NULL) { return result; } ddrhook1_master_insert_hooks(result); return result; } void ddrhook1_master_insert_hooks(HMODULE target) { /* Insert all other hooks here */ p3io_setupapi_insert_hooks(target); monitor_setupapi_insert_hooks(target); gfx_insert_hooks(target); dinput_init(target); /* Insert dynamic loader hooks so that we can hook late-loaded modules */ hook_table_apply( target, "kernel32.dll", master_kernel32_syms, lengthof(master_kernel32_syms)); log_info("Inserted dynamic loader hooks into %p", target); }