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..1289b4323 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", "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 add764e26..a85db69c5 160000 --- a/deps/first/Unreal +++ b/deps/first/Unreal @@ -1 +1 @@ -Subproject commit add764e263046da5edb1fc9f49e1bb55ccf66fd6 +Subproject commit a85db69c5b535d37b603f31a7ba42b4bcc112204 diff --git a/deps/third-repo/packages/p/polyhook_2/xmake.lua b/deps/third-repo/packages/p/polyhook_2/xmake.lua index 7cccc343c..9f5df98fb 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 = {} @@ -11,5 +12,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