diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp new file mode 100644 index 00000000..6f696071 --- /dev/null +++ b/src/client/component/game_module.cpp @@ -0,0 +1,125 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "game_module.hpp" + +#include + +namespace game_module +{ + namespace + { + utils::hook::detour handle_a_hook; + utils::hook::detour handle_w_hook; + utils::hook::detour handle_ex_a_hook; + utils::hook::detour handle_ex_w_hook; + utils::hook::detour file_name_a_hook; + utils::hook::detour file_name_w_hook; + + HMODULE __stdcall get_module_handle_a(const LPCSTR module_name) + { + if (!module_name) + { + return get_game_module(); + } + + return handle_a_hook.invoke(module_name); + } + + HMODULE __stdcall get_module_handle_w(const LPWSTR module_name) + { + if (!module_name) + { + return get_game_module(); + } + + return handle_w_hook.invoke(module_name); + } + + BOOL __stdcall get_module_handle_ex_a(const DWORD flags, const LPCSTR module_name, HMODULE* hmodule) + { + if (!module_name) + { + *hmodule = get_game_module(); + return TRUE; + } + + return handle_ex_a_hook.invoke(flags, module_name, hmodule); + } + + BOOL __stdcall get_module_handle_ex_w(const DWORD flags, const LPCWSTR module_name, HMODULE* hmodule) + { + if (!module_name) + { + *hmodule = get_game_module(); + return TRUE; + } + + return handle_ex_w_hook.invoke(flags, module_name, hmodule); + } + + DWORD __stdcall get_module_file_name_a(HMODULE hmodule, const LPSTR filename, const DWORD size) + { + if (!hmodule || utils::nt::library(hmodule) == get_game_module()) + { + hmodule = get_host_module(); + } + + return file_name_a_hook.invoke(hmodule, filename, size); + } + + DWORD __stdcall get_module_file_name_w(HMODULE hmodule, const LPWSTR filename, const DWORD size) + { + if (!hmodule || utils::nt::library(hmodule) == get_game_module()) + { + hmodule = get_host_module(); + } + + return file_name_w_hook.invoke(hmodule, filename, size); + } + + void hook_module_resolving() + { + handle_a_hook.create(&GetModuleHandleA, &get_module_handle_a); + handle_w_hook.create(&GetModuleHandleW, &get_module_handle_w); + handle_ex_w_hook.create(&GetModuleHandleExA, &get_module_handle_ex_a); + handle_ex_w_hook.create(&GetModuleHandleExW, &get_module_handle_ex_w); + file_name_a_hook.create(&GetModuleFileNameA, &get_module_file_name_a); + file_name_w_hook.create(&GetModuleFileNameW, &get_module_file_name_w); + } + } + + utils::nt::library get_game_module() + { + static utils::nt::library game{HMODULE(BASE_ADDRESS)}; + return game; + } + + utils::nt::library get_host_module() + { + static utils::nt::library host{}; + return host; + } + + class component final : public component_interface + { + public: + void post_start() override + { + get_host_module(); + } + + void post_load() override + { +#ifdef INJECT_HOST_AS_LIB + hook_module_resolving(); +#else + assert(get_host_module() == get_game_module()); +#endif + } + }; +} + +REGISTER_COMPONENT(game_module::component) diff --git a/src/client/component/game_module.hpp b/src/client/component/game_module.hpp new file mode 100644 index 00000000..35a39f74 --- /dev/null +++ b/src/client/component/game_module.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace game_module +{ + utils::nt::library get_game_module(); + utils::nt::library get_host_module(); +} diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 85ebd257..195c66f5 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -23,8 +23,7 @@ namespace patches DECLSPEC_NORETURN void quit_stub() { - component_loader::pre_destroy(); - exit(0); + utils::hook::invoke(0x1408B1BA0); } void gscr_set_save_dvar_stub() @@ -80,12 +79,14 @@ namespace patches public: void post_unpack() override { - // Fix startup crashes - utils::hook::set(0x140633080, 0xC301B0); + // Fix startup crash (bnet) utils::hook::set(0x140272F70, 0xC301B0); - utils::hook::jump(0x140046148, sub_46148); - utils::hook::jump(0x1408B1CD0, quit_stub); + // Fix shutdown crash + utils::hook::jump(0x1408B1CD0, 0x1408B1BA0); + + // Disable splash screen + utils::hook::nop(0x14064F546, 5); // Unlock fps in main menu utils::hook::set(0x1403D8E1B, 0xEB);