diff --git a/UE4SS/CMakeLists.txt b/UE4SS/CMakeLists.txt index 04015f4ab..3ae218d5a 100644 --- a/UE4SS/CMakeLists.txt +++ b/UE4SS/CMakeLists.txt @@ -161,7 +161,7 @@ target_link_libraries(${TARGET} PUBLIC MProgram ScopedTimer) target_link_libraries(${TARGET} PUBLIC - ImGui PolyHook_2 d3d11 GLFW opengl32 dbghelp) + ImGui safetyhook d3d11 GLFW opengl32 dbghelp) set_property(TARGET ${TARGET} PROPERTY INTERPROCEDURAL_OPTIMIZATION ON) diff --git a/UE4SS/include/CrashDumper.hpp b/UE4SS/include/CrashDumper.hpp index b2ab6f7c7..6aedfa925 100644 --- a/UE4SS/include/CrashDumper.hpp +++ b/UE4SS/include/CrashDumper.hpp @@ -2,7 +2,7 @@ #include -#include +#include namespace RC { @@ -11,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 5052b91cd..cc700c7aa 100644 --- a/UE4SS/include/UE4SSProgram.hpp +++ b/UE4SS/include/UE4SSProgram.hpp @@ -21,6 +21,8 @@ #include #include +#include + // Used to set up ImGui context and allocator in DLL mods #define UE4SS_ENABLE_IMGUI() \ { \ @@ -109,17 +111,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: static inline std::vector> m_mods; diff --git a/UE4SS/src/CrashDumper.cpp b/UE4SS/src/CrashDumper.cpp index 3a81f4240..2bc60ed6b 100644 --- a/UE4SS/src/CrashDumper.cpp +++ b/UE4SS/src/CrashDumper.cpp @@ -75,7 +75,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)); } @@ -83,13 +83,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 614754371..3477332b8 100644 --- a/UE4SS/src/UE4SSProgram.cpp +++ b/UE4SS/src/UE4SSProgram.cpp @@ -128,7 +128,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(to_wstring(dll_name)); return lib; } @@ -136,7 +136,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(to_wstring(dll_name)); return lib; } @@ -144,7 +144,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(dll_name); return lib; } @@ -152,7 +152,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(dll_name); return lib; } @@ -227,36 +227,11 @@ namespace RC #else #define UE4SS_COMPILER L"MSVC" #endif - - Output::send(STR("UE4SS Build Configuration: {} ({})\n"), to_wstring(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/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp b/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp index 83961b8b9..8aa86ab84 100644 --- a/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp +++ b/deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp @@ -9,6 +9,7 @@ namespace RC::ASM { void* address{}; ZydisDecodedInstruction raw{}; + ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]{}; }; RC_ASM_API auto is_jmp_instruction(void* instruction_ptr) -> bool; diff --git a/deps/first/ASMHelper/src/ASMHelper.cpp b/deps/first/ASMHelper/src/ASMHelper.cpp index 574f04526..660dbc6bc 100644 --- a/deps/first/ASMHelper/src/ASMHelper.cpp +++ b/deps/first/ASMHelper/src/ASMHelper.cpp @@ -10,14 +10,15 @@ namespace RC::ASM { auto instruction_ptr = static_cast(in_instruction_ptr); ZydisDecoder decoder{}; - ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); + ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); ZyanUSize offset = 0; - ZydisDecodedInstruction instruction{}; - while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, instruction_ptr + offset, 16 - offset, &instruction))) + + 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}; + return instruction; } auto is_jmp_instruction(void* in_instruction_ptr) -> bool @@ -36,7 +37,7 @@ namespace RC::ASM { auto instruction = get_first_instruction_at_address(in_instruction_ptr); ZyanU64 resolved_address{}; - if (ZYAN_SUCCESS(ZydisCalcAbsoluteAddress(&instruction.raw, &instruction.raw.operands[0], std::bit_cast(in_instruction_ptr), &resolved_address))) + if (ZYAN_SUCCESS(ZydisCalcAbsoluteAddress(&instruction.raw, &instruction.operands[0], std::bit_cast(in_instruction_ptr), &resolved_address))) { return std::bit_cast(resolved_address); } diff --git a/deps/first/Helpers/CMakeLists.txt b/deps/first/Helpers/CMakeLists.txt index 1b73f2faa..ece88b35c 100644 --- a/deps/first/Helpers/CMakeLists.txt +++ b/deps/first/Helpers/CMakeLists.txt @@ -10,3 +10,5 @@ add_library(${TARGET} INTERFACE) target_compile_features(${TARGET} INTERFACE cxx_std_20) target_include_directories(${TARGET} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) + +target_link_libraries(${TARGET} INTERFACE File Function safetyhook) 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/third/CMakeLists.txt b/deps/third/CMakeLists.txt index 5d91aa6ee..e838ff9ca 100644 --- a/deps/third/CMakeLists.txt +++ b/deps/third/CMakeLists.txt @@ -23,42 +23,44 @@ FetchContent_Declare(ImGui GIT_SHALLOW TRUE GIT_PROGRESS ON CONFIGURE_COMMAND "") - + FetchContent_Declare(ImGuiTextEdit GIT_REPOSITORY git@github.com:UE4SS-RE/ImGuiColorTextEdit.git GIT_TAG master GIT_SHALLOW TRUE GIT_PROGRESS ON CONFIGURE_COMMAND "") - + add_subdirectory("imgui") # ImGui end # Zydis start FetchContent_Declare(zydis GIT_REPOSITORY git@github.com:zyantific/zydis.git - GIT_TAG v3.1.0 + GIT_TAG v4.0.0 GIT_SHALLOW TRUE GIT_PROGRESS ON) - + add_subdirectory("zydis") # Zydis end -# PolyHook start -FetchContent_Declare(PolyHook2 - GIT_REPOSITORY git@github.com:stevemk14ebr/PolyHook_2_0.git - GIT_TAG 16bc0faf77a15b91b72763353901cfe34daf3174 +# safetyhook start +FetchContent_Declare( + safetyhook + GIT_REPOSITORY "https://github.com/UE4SS-RE/safetyhook.git" + GIT_TAG "4def59079b95e08dc086cecf5515abde377059e5" GIT_PROGRESS ON) +FetchContent_MakeAvailable(safetyhook) -add_subdirectory("PolyHook_2_0") -# PolyHook end +add_subdirectory("safetyhook") +# safetyhook end # raw_pdb start FetchContent_Declare(raw_pdb GIT_REPOSITORY git@github.com:MolecularMatters/raw_pdb.git GIT_TAG 8c6a7146393c83d27fa101e8bc8017f2a7f151df GIT_PROGRESS ON) - + add_subdirectory("raw_pdb") # raw_pdb end # Third Party Depenedencies \ No newline at end of file diff --git a/deps/third/PolyHook_2_0/CMakeLists.txt b/deps/third/PolyHook_2_0/CMakeLists.txt index 7e89d3df1..e69de29bb 100644 --- a/deps/third/PolyHook_2_0/CMakeLists.txt +++ b/deps/third/PolyHook_2_0/CMakeLists.txt @@ -1,53 +0,0 @@ -include(FetchContent) - -set(FETCHCONTENT_QUIET OFF) - -set(ZYDIS_LIBRARY Zydis) -set(ZYCORE_LIBRARY Zycore) - -get_target_property(ZYDIS_INCLUDE_DIR ${ZYDIS_LIBRARY} INCLUDE_DIRECTORIES) -get_target_property(ZYCORE_INCLUDE_DIR ${ZYCORE_LIBRARY} INCLUDE_DIRECTORIES) -message(${ZYDIS_INCLUDE_DIR}) - -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) - -# add a conditional for disabling 'set_target_properties' on demand to prevent PolyHook from setting MSVC_RUNTIME_LIBRARY to "MultiThreaded$<$:Debug>DLL" -if(NOT DEFINED _DISABLE_SET_PROPERTIES) - set(_DISABLE_SET_PROPERTIES TRUE) - - macro(set_target_properties) - if (NOT _DISABLE_SET_PROPERTIES) - _set_target_properties(${ARGV}) - endif() - endmacro() -endif() - -# add a conditional for disabling 'install' on demand -if(NOT DEFINED _DISABLE_INSTALL) - set(_DISABLE_INSTALL TRUE) - - macro(install) - if (NOT _DISABLE_INSTALL) - _install(${ARGV}) - endif() - endmacro() -endif() - -FetchContent_MakeAvailable(PolyHook2) - -# re-enable 'set_target_properties' and 'install' since we're done adding PolyHook -set(_DISABLE_SET_PROPERTIES FALSE) -set(_DISABLE_INSTALL FALSE) diff --git a/deps/third/safetyhook/CMakeLists.txt b/deps/third/safetyhook/CMakeLists.txt new file mode 100644 index 000000000..6b612c9af --- /dev/null +++ b/deps/third/safetyhook/CMakeLists.txt @@ -0,0 +1,10 @@ +include(FetchContent) + +set(FETCHCONTENT_QUIET OFF) + +FetchContent_Declare( + safetyhook + GIT_REPOSITORY "https://github.com/UE4SS-RE/safetyhook.git" + GIT_TAG "4def59079b95e08dc086cecf5515abde377059e5" +) +FetchContent_MakeAvailable(safetyhook) \ No newline at end of file