Skip to content

Commit

Permalink
Polyhook -> safetyhook
Browse files Browse the repository at this point in the history
fix: safetyhook compilation (localcc)

Add call_hook and call_hook_unsafe helper wrappers for Safetyhook

Add deprecation warning to polyhook_2 xmake file.
  • Loading branch information
narknon committed Oct 8, 2024
1 parent 58a902c commit b6d995c
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 70 deletions.
8 changes: 2 additions & 6 deletions UE4SS/include/CrashDumper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

#include <memory>

namespace PLH
{
class IatHook;
}
#include <safetyhook.hpp>

namespace RC
{
Expand All @@ -14,8 +11,7 @@ namespace RC
private:
bool enabled = false;
void* m_previous_exception_filter = nullptr;
std::unique_ptr<PLH::IatHook> 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();
Expand Down
16 changes: 5 additions & 11 deletions UE4SS/include/UE4SSProgram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <Unreal/Core/Containers/Array.hpp>
#include <Unreal/UnrealVersion.hpp>

#include <safetyhook.hpp>
#include <String/StringType.hpp>

// Used to set up ImGui context and allocator in DLL mods
Expand Down Expand Up @@ -133,17 +134,10 @@ namespace RC
std::mutex m_event_queue_mutex{};

private:
std::unique_ptr<PLH::IatHook> m_load_library_a_hook;
uint64_t m_hook_trampoline_load_library_a;

std::unique_ptr<PLH::IatHook> m_load_library_ex_a_hook;
uint64_t m_hook_trampoline_load_library_ex_a;

std::unique_ptr<PLH::IatHook> m_load_library_w_hook;
uint64_t m_hook_trampoline_load_library_w;

std::unique_ptr<PLH::IatHook> 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<std::unique_ptr<Mod>> m_mods;
Expand Down
11 changes: 2 additions & 9 deletions UE4SS/src/CrashDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <UE4SSProgram.hpp>
#include <Unreal/Core/Windows/WindowsHWrapper.hpp>

#include <polyhook2/PE/IatHook.hpp>
#include <dbghelp.h>

#include <String/StringType.hpp>
Expand Down Expand Up @@ -77,21 +76,15 @@ namespace RC

CrashDumper::~CrashDumper()
{
m_set_unhandled_exception_filter_hook->unHook();
m_set_unhandled_exception_filter_hook = {};
SetUnhandledExceptionFilter(reinterpret_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(m_previous_exception_filter));
}

void CrashDumper::enable()
{
SetErrorMode(SEM_FAILCRITICALERRORS);
m_previous_exception_filter = SetUnhandledExceptionFilter(ExceptionHandler);

m_set_unhandled_exception_filter_hook = std::make_unique<PLH::IatHook>("kernel32.dll",
"SetUnhandledExceptionFilter",
std::bit_cast<uint64_t>(&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;
}

Expand Down
43 changes: 8 additions & 35 deletions UE4SS/src/UE4SSProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@
#include <Unreal/World.hpp>
#include <UnrealDef.hpp>

#include <polyhook2/PE/IatHook.hpp>

namespace RC
{
// Commented out because this system (turn off hotkeys when in-game console is open) it doesn't work properly.
Expand Down Expand Up @@ -132,31 +130,31 @@ 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<HMODULE>(dll_name);
program.fire_dll_load_for_cpp_mods(ensure_str(dll_name));
return lib;
}

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<HMODULE>(dll_name, file, flags);
program.fire_dll_load_for_cpp_mods(ensure_str(dll_name));
return lib;
}

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<HMODULE>(dll_name);
program.fire_dll_load_for_cpp_mods(ToCharTypePtr(dll_name));
return lib;
}

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<HMODULE>(dll_name, file, flags);
program.fire_dll_load_for_cpp_mods(ToCharTypePtr(dll_name));
return lib;
}
Expand Down Expand Up @@ -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<PLH::IatHook>("kernel32.dll",
"LoadLibraryA",
std::bit_cast<uint64_t>(&HookedLoadLibraryA),
&m_hook_trampoline_load_library_a,
L"");
m_load_library_a_hook->hook();

m_load_library_ex_a_hook = std::make_unique<PLH::IatHook>("kernel32.dll",
"LoadLibraryExA",
std::bit_cast<uint64_t>(&HookedLoadLibraryExA),
&m_hook_trampoline_load_library_ex_a,
L"");
m_load_library_ex_a_hook->hook();

m_load_library_w_hook = std::make_unique<PLH::IatHook>("kernel32.dll",
"LoadLibraryW",
std::bit_cast<uint64_t>(&HookedLoadLibraryW),
&m_hook_trampoline_load_library_w,
L"");
m_load_library_w_hook->hook();

m_load_library_ex_w_hook = std::make_unique<PLH::IatHook>("kernel32.dll",
"LoadLibraryExW",
std::bit_cast<uint64_t>(&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();

Expand Down
3 changes: 2 additions & 1 deletion UE4SS/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 })

Expand Down
2 changes: 1 addition & 1 deletion deps/first/ASMHelper/include/ASMHelper/ASMHelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*;
Expand Down
8 changes: 4 additions & 4 deletions deps/first/ASMHelper/src/ASMHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*
Expand Down
34 changes: 34 additions & 0 deletions deps/first/Helpers/include/Helpers/Hook.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <Function/Function.hpp>

#include <safetyhook.hpp>

namespace RC::Helper::Hook
{
template <typename>
class call_hook;

template <typename ReturnType, typename... Params>
class call_hook<Function<ReturnType(Params...)>>
{
public:
ReturnType operator()(SafetyHookInline& hook, Params... args)
{
return hook.call<ReturnType, Params...>(std::forward<Params>(args)...);
}
};

template <typename>
class call_hook_unsafe;

template <typename ReturnType, typename... Params>
class call_hook_unsafe<Function<ReturnType(Params...)>>
{
public:
ReturnType operator()(SafetyHookInline& hook, Params... args)
{
return hook.unsafe_call<ReturnType, Params...>(std::forward<Params>(args)...);
}
};
} // namespace RC::Helper::Hook
1 change: 1 addition & 0 deletions deps/first/Helpers/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion deps/first/Unreal
4 changes: 3 additions & 1 deletion deps/third-repo/packages/p/polyhook_2/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}

Expand All @@ -11,5 +12,6 @@ package("polyhook_2")

import("package.tools.cmake").install(package, configs, { packagedeps = { "zycore", "zydis" } })


end)
package_end()
18 changes: 18 additions & 0 deletions deps/third-repo/packages/s/safetyhook/xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package("safetyhook")
add_urls("[email protected]: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()
3 changes: 2 additions & 1 deletion deps/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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()} })
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()} })

0 comments on commit b6d995c

Please sign in to comment.