Skip to content

Commit

Permalink
Revert "FunctionHook: Update with proper RAII"
Browse files Browse the repository at this point in the history
This reverts commit fb42769.
This was causing race conditions.
  • Loading branch information
praydog committed Mar 31, 2024
1 parent 30f586f commit 033041b
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 21 deletions.
42 changes: 38 additions & 4 deletions shared/utility/FunctionHook.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <spdlog/spdlog.h>
#include <MinHook.h>

#include <safetyhook/inline_hook.hpp>

#include "FunctionHook.hpp"
Expand All @@ -12,6 +14,36 @@ FunctionHook::FunctionHook(Address target, Address destination)
{
spdlog::info("Attempting to hook {:p}->{:p}", target.ptr(), destination.ptr());

// Create the hook. Call create afterwards to prevent race conditions accessing FunctionHook before it leaves its constructor.
/*if (auto status = MH_CreateHook(target.as<LPVOID>(), destination.as<LPVOID>(), (LPVOID*)&m_original); status == MH_OK) {
m_target = target;
m_destination = destination;
spdlog::info("Hook init successful {:p}->{:p}", target.ptr(), destination.ptr());
}
else {
spdlog::error("Failed to hook {:p}: {}", target.ptr(), MH_StatusToString(status));
}*/
}

FunctionHook::~FunctionHook() {
}

bool FunctionHook::create() {
if (m_target == 0 || m_destination == 0 ) {
spdlog::error("FunctionHook not initialized");
return false;
}

/*if (auto status = MH_EnableHook((LPVOID)m_target); status != MH_OK) {
m_original = 0;
m_destination = 0;
m_target = 0;
spdlog::error("Failed to hook {:x}: {}", m_target, MH_StatusToString(status));
return false;
}*/

try {
auto expect = safetyhook::InlineHook::create(safetyhook::Allocator::global(), m_target, m_destination);

Expand Down Expand Up @@ -45,22 +77,24 @@ FunctionHook::FunctionHook(Address target, Address destination)
};

spdlog::error("Failed to hook {:x}: {}", m_target, error);
return;
return false;
}

m_inline_hook = std::move(*expect);
} catch (const std::exception& e) {
spdlog::error("Failed to hook {:x}: {}", m_target, e.what());
return false;
} catch (...) {
spdlog::error("Failed to hook {:x}: unknown exception", m_target);
return false;
}

if (m_inline_hook) {
spdlog::info("Hooked {:x}->{:x}", m_target, m_destination);
} else {
spdlog::error("Failed to hook {:x}", m_target);
return false;
}
}

FunctionHook::~FunctionHook() {
}
return true;
}
2 changes: 2 additions & 0 deletions shared/utility/FunctionHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class FunctionHook {
FunctionHook(Address target, Address destination);
virtual ~FunctionHook();

bool create();

auto get_original() const {
return m_inline_hook.trampoline().address();
}
Expand Down
2 changes: 1 addition & 1 deletion src/DInputHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ bool DInputHook::hook() {
// Hook them.
m_get_device_state_hook = make_unique<FunctionHook>(get_device_state, (uintptr_t)&DInputHook::get_device_state);

return m_get_device_state_hook->is_valid();
return m_get_device_state_hook->create();
}

HRESULT DInputHook::get_device_state_internal(IDirectInputDevice* device, DWORD size, LPVOID data) {
Expand Down
1 change: 1 addition & 0 deletions src/HookManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ HookManager::HookId HookManager::add(sdk::REMethodDefinition* fn, HookManager::P
create_jitted_facilitator(hook, fn,
[&](){
fn_hook = std::make_unique<FunctionHook>(hook->target_fn, (void*)hook->facilitator_fn);
fn_hook->create();
return fn_hook->get_original();
},
[&]() {
Expand Down
22 changes: 11 additions & 11 deletions src/mods/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ std::optional<std::string> Hooks::hook_update_transform() {
// Can be found by breakpointing RETransform's worldTransform
m_update_transform_hook = std::make_unique<FunctionHook>(update_transform, &update_transform_hook);

if (!m_update_transform_hook->is_valid()) {
if (!m_update_transform_hook->create()) {
//return "Failed to hook UpdateTransform";
spdlog::error("Failed to hook UpdateTransform");
return std::nullopt; // who cares
Expand Down Expand Up @@ -231,7 +231,7 @@ std::optional<std::string> Hooks::hook_update_camera_controller() {
// Can be found by breakpointing camera controller's worldPosition
m_update_camera_controller_hook = std::make_unique<FunctionHook>(update_camera_controller, &update_camera_controller_hook);

if (!m_update_camera_controller_hook->is_valid()) {
if (!m_update_camera_controller_hook->create()) {
return "Failed to hook UpdateCameraController";
}
#endif
Expand All @@ -258,7 +258,7 @@ std::optional<std::string> Hooks::hook_update_camera_controller2() {
// Can be found by breakpointing camera controller's worldRotation
m_update_camera_controller2_hook = std::make_unique<FunctionHook>(update_camera_controller2, &update_camera_controller2_hook);

if (!m_update_camera_controller2_hook->is_valid()) {
if (!m_update_camera_controller2_hook->create()) {
return "Failed to hook Updatecamera_controller2";
}
#endif
Expand Down Expand Up @@ -306,7 +306,7 @@ std::optional<std::string> Hooks::hook_gui_draw() {

m_gui_draw_hook = std::make_unique<FunctionHook>(gui_draw, &gui_draw_hook);

if (!m_gui_draw_hook->is_valid()) {
if (!m_gui_draw_hook->create()) {
return "Failed to hook GUI::draw";
}

Expand Down Expand Up @@ -337,7 +337,7 @@ std::optional<std::string> Hooks::hook_application_entry(std::string name, std::

hook = std::make_unique<FunctionHook>(func, hook_fn);

if (!hook->is_valid()) {
if (!hook->create()) {
return "Failed to hook via::Application::" + name;
}

Expand Down Expand Up @@ -469,7 +469,7 @@ std::optional<std::string> Hooks::hook_all_application_entries() {
}

/*for (auto& entry : m_application_entry_hooks) {
if (!entry.second->is_valid()) {
if (!entry.second->create()) {
return "Failed to hook via::Application::" + std::string{entry.first};
}
}*/
Expand All @@ -489,7 +489,7 @@ std::optional<std::string> Hooks::hook_update_before_lock_scene() {

m_update_before_lock_scene_hook = std::make_unique<FunctionHook>(update_before_lock_scene, &update_before_lock_scene_hook);

if (!m_update_before_lock_scene_hook->is_valid()) {
if (!m_update_before_lock_scene_hook->create()) {
return "Failed to hook via::render::EntityRenderer::updateBeforeLockScene";
}

Expand Down Expand Up @@ -532,7 +532,7 @@ std::optional<std::string> Hooks::hook_lightshaft_draw() {

m_lightshaft_draw_hook = std::make_unique<FunctionHook>((uintptr_t)draw, (uintptr_t)&lightshaft_draw_hook);

if (!m_lightshaft_draw_hook->is_valid()) {
if (!m_lightshaft_draw_hook->create()) {
return "Failed to hook via::render::LightShaft::draw";
}
#endif
Expand Down Expand Up @@ -563,7 +563,7 @@ std::optional<std::string> Hooks::hook_view_get_size() {
// Hook the native function
m_view_get_size_hook = std::make_unique<FunctionHook>(native_func, view_get_size_hook);

if (!m_view_get_size_hook->is_valid()) {
if (!m_view_get_size_hook->create()) {
return "Hook init failed: via.SceneView.get_Size native function hook failed.";
}

Expand Down Expand Up @@ -593,7 +593,7 @@ std::optional<std::string> Hooks::hook_camera_get_projection_matrix() {
// Hook the native function
m_camera_get_projection_matrix_hook = std::make_unique<FunctionHook>(native_func, camera_get_projection_matrix_hook);

if (!m_camera_get_projection_matrix_hook->is_valid()) {
if (!m_camera_get_projection_matrix_hook->create()) {
return "Hook init failed: via.Camera.get_ProjectionMatrix native function hook failed.";
}

Expand Down Expand Up @@ -623,7 +623,7 @@ std::optional<std::string> Hooks::hook_camera_get_view_matrix() {
// Hook the native function
m_camera_get_view_matrix_hook = std::make_unique<FunctionHook>(native_func, camera_get_view_matrix_hook);

if (!m_camera_get_view_matrix_hook->is_valid()) {
if (!m_camera_get_view_matrix_hook->create()) {
return "Hook init failed: via.Camera.get_ViewMatrix native function hook failed.";
}

Expand Down
4 changes: 2 additions & 2 deletions src/mods/Hooks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ class Hooks : public Mod {

virtual bool hook_draw(Address target) {
draw_hook = std::make_unique<FunctionHook>(target, &RenderLayerHook<T>::draw);
return draw_hook->is_valid();
return draw_hook->create();
}

virtual bool hook_update(Address target) {
update_hook = std::make_unique<FunctionHook>(target, &RenderLayerHook<T>::update);
return update_hook->is_valid();
return update_hook->create();
}

operator RenderLayerHook<sdk::renderer::RenderLayer>&() {
Expand Down
6 changes: 3 additions & 3 deletions src/mods/VR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ std::optional<std::string> VR::hijack_input() {
// Hook the native function
g_input_hook = std::make_unique<FunctionHook>(func, inputsystem_update_hook);

if (!g_input_hook->is_valid()) {
if (!g_input_hook->create()) {
return "VR init failed: InputSystem.update native function hook failed.";
}
#endif
Expand Down Expand Up @@ -1157,7 +1157,7 @@ std::optional<std::string> VR::hijack_camera() {
// Hook the native function
g_projection_matrix_hook2 = std::make_unique<FunctionHook>(native_func, gui_camera_get_projection_matrix_hook);

if (g_projection_matrix_hook2->is_valid()) {
if (g_projection_matrix_hook2->create()) {
spdlog::info("Hooked via.gui.GUICamera.get_ProjectionMatrix");
}
} else {
Expand Down Expand Up @@ -1232,7 +1232,7 @@ std::optional<std::string> VR::hijack_wwise_listeners() {

g_wwise_listener_update_hook = std::make_unique<FunctionHook>(update_native, wwise_listener_update_hook);

if (!g_wwise_listener_update_hook->is_valid()) {
if (!g_wwise_listener_update_hook->create()) {
return "VR init failed: via.wwise.WwiseListener update native function hook failed.";
}
#endif
Expand Down

0 comments on commit 033041b

Please sign in to comment.