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 d91b705f1..4e4ac6e15 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 e823ce51a..82f951756 100644 --- a/UE4SS/src/CrashDumper.cpp +++ b/UE4SS/src/CrashDumper.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -77,7 +76,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)); } @@ -85,13 +84,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 785b8eb97..fb29f377a 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; } @@ -232,35 +230,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 6a0e84160..0edf2f5d0 100644 --- a/UE4SS/xmake.lua +++ b/UE4SS/xmake.lua @@ -7,6 +7,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) @@ -77,7 +78,7 @@ target(projectName) add_packages("imgui", "ImGuiTextEdit", "IconFontCppHeaders", "glfw", "opengl", { public = true }) - add_packages("glaze", "polyhook_2", { public = true }) + add_packages("glaze", "safetyhook", { 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..127dbb936 --- /dev/null +++ b/deps/first/Helpers/include/Helpers/Hook.hpp @@ -0,0 +1,21 @@ +#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)...); + } + }; +} // namespace RC::Helper::Hook diff --git a/deps/first/Helpers/xmake.lua b/deps/first/Helpers/xmake.lua index 4117e478f..903b948e5 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 add764e26..e7d714b88 160000 --- a/deps/first/Unreal +++ b/deps/first/Unreal @@ -1 +1 @@ -Subproject commit add764e263046da5edb1fc9f49e1bb55ccf66fd6 +Subproject commit e7d714b88d71ea2f7a445fce561f6d6598dba3b0 diff --git a/deps/third-repo/packages/p/polyhook_2/CMakeLists.txt b/deps/third-repo/packages/p/polyhook_2/CMakeLists.txt deleted file mode 100644 index 196334bc4..000000000 --- a/deps/third-repo/packages/p/polyhook_2/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 3.27) - -include(FetchContent) - -set(FETCHCONTENT_QUIET OFF) - -# Add the preprocessor definition to fix mutex -add_definitions(-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) - -FetchContent_Declare(PolyHook2 - GIT_REPOSITORY https://github.com/stevemk14ebr/PolyHook_2_0.git - GIT_TAG fd2a88f09c8ae89440858fc52573656141013c7f - GIT_PROGRESS ON) - -if (${UE4SS_PolyHook_BUILD_SHARED}) - set(MAKE_POLYHOOK_DEPENDENCIES_SHARED ON) - set(MAKE_POLYHOOK_DEPENDENCIES_STATIC OFF) -else () - set(MAKE_POLYHOOK_DEPENDENCIES_SHARED OFF) - set(MAKE_POLYHOOK_DEPENDENCIES_STATIC ON) -endif () - -set(POLYHOOK_BUILD_DLL ON CACHE BOOL "Build dll & lib instead of tests" FORCE) -set(POLYHOOK_BUILD_SHARED_LIB ${MAKE_POLYHOOK_DEPENDENCIES_SHARED} CACHE BOOL "Build polyhook2 as shared libary" FORCE) -set(POLYHOOK_USE_EXTERNAL_ZYDIS ON CACHE BOOL "Use external zydis libary" FORCE) -set(ASMJIT_STATIC ${MAKE_POLYHOOK_DEPENDENCIES_STATIC} CACHE BOOL "Build 'asmjit' library as static" FORCE) -set(POLYHOOK_BUILD_STATIC_RUNTIME OFF CACHE BOOL "Use static runtime" FORCE) - -# prevent PolyHook from setting MSVC_RUNTIME_LIBRARY to "MultiThreaded$<$:Debug>DLL" by unsetting 'MSVC' var -set(TMP_MSVC ${MSVC}) -unset(MSVC) - -FetchContent_MakeAvailable(PolyHook2) - -# re-enable 'install' and reset 'MSVC' since we're done adding PolyHook -set(MSVC ${TMP_MSVC}) diff --git a/deps/third-repo/packages/p/polyhook_2/xmake.lua b/deps/third-repo/packages/p/polyhook_2/xmake.lua deleted file mode 100644 index 7cccc343c..000000000 --- a/deps/third-repo/packages/p/polyhook_2/xmake.lua +++ /dev/null @@ -1,15 +0,0 @@ -package("polyhook_2") - set_sourcedir(os.scriptdir()) - - add_deps("cmake", "zydis", "zycore") - - 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 = { "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..415c0be2f --- /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) + + 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..53cf0b414 100644 --- a/deps/xmake.lua +++ b/deps/xmake.lua @@ -8,4 +8,4 @@ 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("safetyhook", { debug = is_mode_debug(), configs = {runtimes = get_mode_runtimes()} }) \ No newline at end of file