diff --git a/UE4SS/include/CrashDumper.hpp b/UE4SS/include/CrashDumper.hpp index 297e5a1b7..6aedfa925 100644 --- a/UE4SS/include/CrashDumper.hpp +++ b/UE4SS/include/CrashDumper.hpp @@ -2,10 +2,7 @@ #include -namespace PLH -{ - class IatHook; -} +#include namespace RC { @@ -14,8 +11,7 @@ namespace RC private: bool enabled = false; void* m_previous_exception_filter = nullptr; - std::unique_ptr m_set_unhandled_exception_filter_hook; - uint64_t m_hook_trampoline_set_unhandled_exception_filter_hook; + SafetyHookInline m_set_unhandled_exception_filter_hook; public: CrashDumper(); diff --git a/UE4SS/include/UE4SSProgram.hpp b/UE4SS/include/UE4SSProgram.hpp index cbe56052a..62b3dbfb7 100644 --- a/UE4SS/include/UE4SSProgram.hpp +++ b/UE4SS/include/UE4SSProgram.hpp @@ -21,6 +21,7 @@ #include #include +#include #include // Used to set up ImGui context and allocator in DLL mods @@ -133,17 +134,10 @@ namespace RC std::mutex m_event_queue_mutex{}; private: - std::unique_ptr m_load_library_a_hook; - uint64_t m_hook_trampoline_load_library_a; - - std::unique_ptr m_load_library_ex_a_hook; - uint64_t m_hook_trampoline_load_library_ex_a; - - std::unique_ptr m_load_library_w_hook; - uint64_t m_hook_trampoline_load_library_w; - - std::unique_ptr m_load_library_ex_w_hook; - uint64_t m_hook_trampoline_load_library_ex_w; + SafetyHookInline m_load_library_a_hook; + SafetyHookInline m_load_library_ex_a_hook; + SafetyHookInline m_load_library_w_hook; + SafetyHookInline m_load_library_ex_w_hook; public: std::vector> m_mods; diff --git a/UE4SS/src/CrashDumper.cpp b/UE4SS/src/CrashDumper.cpp index 98c7315a4..27c888278 100644 --- a/UE4SS/src/CrashDumper.cpp +++ b/UE4SS/src/CrashDumper.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -78,7 +77,7 @@ namespace RC CrashDumper::~CrashDumper() { - m_set_unhandled_exception_filter_hook->unHook(); + m_set_unhandled_exception_filter_hook = {}; SetUnhandledExceptionFilter(reinterpret_cast(m_previous_exception_filter)); } @@ -86,13 +85,7 @@ namespace RC { SetErrorMode(SEM_FAILCRITICALERRORS); m_previous_exception_filter = SetUnhandledExceptionFilter(ExceptionHandler); - - m_set_unhandled_exception_filter_hook = std::make_unique("kernel32.dll", - "SetUnhandledExceptionFilter", - std::bit_cast(&HookedSetUnhandledExceptionFilter), - &m_hook_trampoline_set_unhandled_exception_filter_hook, - L""); - m_set_unhandled_exception_filter_hook->hook(); + m_set_unhandled_exception_filter_hook = safetyhook::create_inline(SetUnhandledExceptionFilter, HookedSetUnhandledExceptionFilter); this->enabled = true; } diff --git a/UE4SS/src/UE4SSProgram.cpp b/UE4SS/src/UE4SSProgram.cpp index 0d44516df..31ffd1f55 100644 --- a/UE4SS/src/UE4SSProgram.cpp +++ b/UE4SS/src/UE4SSProgram.cpp @@ -55,8 +55,6 @@ #include #include -#include - namespace RC { // Commented out because this system (turn off hotkeys when in-game console is open) it doesn't work properly. @@ -132,7 +130,7 @@ namespace RC void* HookedLoadLibraryA(const char* dll_name) { UE4SSProgram& program = UE4SSProgram::get_program(); - HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_a, &LoadLibraryA)(dll_name); + HMODULE lib = program.m_load_library_a_hook.call(dll_name); program.fire_dll_load_for_cpp_mods(ensure_str(dll_name)); return lib; } @@ -140,7 +138,7 @@ namespace RC void* HookedLoadLibraryExA(const char* dll_name, void* file, int32_t flags) { UE4SSProgram& program = UE4SSProgram::get_program(); - HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_ex_a, &LoadLibraryExA)(dll_name, file, flags); + HMODULE lib = program.m_load_library_ex_a_hook.call(dll_name, file, flags); program.fire_dll_load_for_cpp_mods(ensure_str(dll_name)); return lib; } @@ -148,7 +146,7 @@ namespace RC void* HookedLoadLibraryW(const wchar_t* dll_name) { UE4SSProgram& program = UE4SSProgram::get_program(); - HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_w, &LoadLibraryW)(dll_name); + HMODULE lib = program.m_load_library_w_hook.call(dll_name); program.fire_dll_load_for_cpp_mods(ToCharTypePtr(dll_name)); return lib; } @@ -156,7 +154,7 @@ namespace RC void* HookedLoadLibraryExW(const wchar_t* dll_name, void* file, int32_t flags) { UE4SSProgram& program = UE4SSProgram::get_program(); - HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_ex_w, &LoadLibraryExW)(dll_name, file, flags); + HMODULE lib = program.m_load_library_ex_w_hook.call(dll_name, file, flags); program.fire_dll_load_for_cpp_mods(ToCharTypePtr(dll_name)); return lib; } @@ -234,35 +232,10 @@ namespace RC #define UE4SS_COMPILER STR("MSVC") #endif - Output::send(STR("UE4SS Build Configuration: {} ({})\n"), ensure_str(UE4SS_CONFIGURATION), UE4SS_COMPILER); - - m_load_library_a_hook = std::make_unique("kernel32.dll", - "LoadLibraryA", - std::bit_cast(&HookedLoadLibraryA), - &m_hook_trampoline_load_library_a, - L""); - m_load_library_a_hook->hook(); - - m_load_library_ex_a_hook = std::make_unique("kernel32.dll", - "LoadLibraryExA", - std::bit_cast(&HookedLoadLibraryExA), - &m_hook_trampoline_load_library_ex_a, - L""); - m_load_library_ex_a_hook->hook(); - - m_load_library_w_hook = std::make_unique("kernel32.dll", - "LoadLibraryW", - std::bit_cast(&HookedLoadLibraryW), - &m_hook_trampoline_load_library_w, - L""); - m_load_library_w_hook->hook(); - - m_load_library_ex_w_hook = std::make_unique("kernel32.dll", - "LoadLibraryExW", - std::bit_cast(&HookedLoadLibraryExW), - &m_hook_trampoline_load_library_ex_w, - L""); - m_load_library_ex_w_hook->hook(); + m_load_library_a_hook = safetyhook::create_inline(LoadLibraryA, HookedLoadLibraryA); + m_load_library_ex_a_hook = safetyhook::create_inline(LoadLibraryExA, HookedLoadLibraryExA); + m_load_library_w_hook = safetyhook::create_inline(LoadLibraryW, HookedLoadLibraryW); + m_load_library_ex_w_hook = safetyhook::create_inline(LoadLibraryExW, HookedLoadLibraryExW); Unreal::UnrealInitializer::SetupUnrealModules(); diff --git a/UE4SS/xmake.lua b/UE4SS/xmake.lua index bcc66eb23..7c30cd69a 100644 --- a/UE4SS/xmake.lua +++ b/UE4SS/xmake.lua @@ -9,6 +9,7 @@ add_requires("glfw 3.3.9", { debug = is_mode_debug() , configs = {runtimes = get add_requires("opengl", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) add_requires("glaze v2.9.5", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) add_requires("fmt 10.2.1", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) +add_requires("safetyhook v0.4.1", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) option("ue4ssBetaIsStarted") set_default(true) @@ -79,7 +80,7 @@ target(projectName) add_packages("imgui", "ImGuiTextEdit", "IconFontCppHeaders", "glfw", "opengl", { public = true }) - add_packages("glaze", "polyhook_2", { public = true }) + add_packages("glaze", "safetyhook", "polyhook_2", { public = true }) add_links("dbghelp", "psapi", "d3d11", { public = true }) diff --git a/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp b/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp index 55a92112c..8acea5784 100644 --- a/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp +++ b/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp @@ -9,7 +9,7 @@ namespace RC::ASM { void* address{}; ZydisDecodedInstruction raw{}; - ZydisDecodedOperand* operands{}; + ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]{}; }; RC_ASM_API auto resolve_jmp(void* instruction_ptr) -> void*; diff --git a/deps/first/ASMHelper/src/ASMHelper.cpp b/deps/first/ASMHelper/src/ASMHelper.cpp index bf59ba5cd..dbceb1cca 100644 --- a/deps/first/ASMHelper/src/ASMHelper.cpp +++ b/deps/first/ASMHelper/src/ASMHelper.cpp @@ -12,13 +12,13 @@ namespace RC::ASM ZydisDecoder decoder{}; ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); ZyanUSize offset = 0; - ZydisDecodedInstruction instruction{}; - ZydisDecodedOperand operands[10]{}; - while (ZYAN_SUCCESS(ZydisDecoderDecodeFull(&decoder, instruction_ptr + offset, 16 - offset, &instruction, operands))) + + Instruction instruction{in_instruction_ptr, {}, {}}; + while (ZYAN_SUCCESS(ZydisDecoderDecodeFull(&decoder, instruction_ptr + offset, 16 - offset, &instruction.raw, instruction.operands))) { break; } - return {in_instruction_ptr, instruction, operands}; + return instruction; } auto resolve_absolute_address(void* in_instruction_ptr) -> void* diff --git a/deps/first/Helpers/include/Helpers/Hook.hpp b/deps/first/Helpers/include/Helpers/Hook.hpp new file mode 100644 index 000000000..8ea2d1ad1 --- /dev/null +++ b/deps/first/Helpers/include/Helpers/Hook.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include + +#include + +namespace RC::Helper::Hook +{ + template + class call_hook; + + template + class call_hook> + { + public: + ReturnType operator()(SafetyHookInline& hook, Params... args) + { + return hook.call(std::forward(args)...); + } + }; + + template + class call_hook_unsafe; + + template + class call_hook_unsafe> + { + public: + ReturnType operator()(SafetyHookInline& hook, Params... args) + { + return hook.unsafe_call(std::forward(args)...); + } + }; +} // namespace RC::Helper::Hook diff --git a/deps/first/Helpers/xmake.lua b/deps/first/Helpers/xmake.lua index 05a36e7ce..5d7e4c9bd 100644 --- a/deps/first/Helpers/xmake.lua +++ b/deps/first/Helpers/xmake.lua @@ -7,6 +7,7 @@ target(projectName) add_rules("ue4ss.dependency") add_deps("String") + add_packages("safetyhook") add_includedirs("include", { public = true }) add_headerfiles("include/**.hpp") diff --git a/deps/first/Unreal b/deps/first/Unreal index 69a66d2ee..aedd3a4ea 160000 --- a/deps/first/Unreal +++ b/deps/first/Unreal @@ -1 +1 @@ -Subproject commit 69a66d2eea439dfe4e493f73105597284afcd93f +Subproject commit aedd3a4eae486c12a3828025dc0575386230a8f0 diff --git a/deps/third-repo/packages/p/polyhook_2/xmake.lua b/deps/third-repo/packages/p/polyhook_2/xmake.lua index bbed757f5..9675e0b09 100644 --- a/deps/third-repo/packages/p/polyhook_2/xmake.lua +++ b/deps/third-repo/packages/p/polyhook_2/xmake.lua @@ -2,7 +2,8 @@ package("polyhook_2") set_sourcedir(os.scriptdir()) add_deps("cmake", "zydis", "zycore") - + -- Print a deprecation warning + print("Warning: The package 'polyhook_2' is deprecated and will be removed in a future release. If you are using this package please update your code to use 'safetyhook'.") on_install(function (package) local configs = {} @@ -16,5 +17,6 @@ package("polyhook_2") import("package.tools.cmake").install(package, configs, { packagedeps = { "zycore", "zydis" } }) + end) package_end() \ No newline at end of file diff --git a/deps/third-repo/packages/s/safetyhook/xmake.lua b/deps/third-repo/packages/s/safetyhook/xmake.lua new file mode 100644 index 000000000..524d44e16 --- /dev/null +++ b/deps/third-repo/packages/s/safetyhook/xmake.lua @@ -0,0 +1,18 @@ +package("safetyhook") + add_urls("git@github.com:cursey/safetyhook.git") + add_urls("https://github.com/cursey/safetyhook.git") + + add_versions("v0.4.1", "629558c64009a7291ba6ed5cfb49187086a27a47") + + add_deps("cmake", "zydis") + + on_install(function (package) + local configs = {} + table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release")) + table.insert(configs, "-DBUILD_SHARED_LIBS=OFF") + import("package.tools.cmake").install(package, configs, { packagedeps = {"zydis", "zycore"} }) + + os.cp("include/*.hpp", package:installdir("include")) + os.cp("include/safetyhook/*.hpp", package:installdir("include/safetyhook")) + end) +package_end() \ No newline at end of file diff --git a/deps/xmake.lua b/deps/xmake.lua index 45680fba6..064a38958 100644 --- a/deps/xmake.lua +++ b/deps/xmake.lua @@ -8,4 +8,5 @@ add_repositories("third-party deps/third-repo", { rootdir = get_config("ue4ssRoo add_requires("zycore v1.5.0", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) add_requires("zydis v4.1.0", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) -add_requires("polyhook_2", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) \ No newline at end of file +add_requires("polyhook_2", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) +add_requires("safetyhook", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) \ No newline at end of file