From 417c17a3f1e6cbd885dd28dc6f4757ac8c6bf50e Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Tue, 19 Nov 2024 23:36:59 -0700 Subject: [PATCH] feat: improve `Relocation` & `Utilities` (#302) changes: * add second template arg to applicable `Relocation::write_` funcs for address offset * remove `AllocTrampoline` from `stl::write_*` funcs, this is bad practice * normalize `stl::write_*` support for structs with `std::uintptr_t`, `REL::ID`, `REL::Offset`, `REL::Relocation` static `address` members --- include/REL/Relocation.h | 16 ++++----- include/SFSE/Utilities.h | 77 +++++++++++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 24 deletions(-) diff --git a/include/REL/Relocation.h b/include/REL/Relocation.h index af3642dc..3c829e7a 100644 --- a/include/REL/Relocation.h +++ b/include/REL/Relocation.h @@ -337,32 +337,32 @@ namespace REL safe_write(address(), a_data.data(), a_data.size_bytes()); } - template + template std::uintptr_t write_branch(const std::uintptr_t a_dst) requires(std::same_as) { - return SFSE::GetTrampoline().write_branch(address(), a_dst); + return SFSE::GetTrampoline().write_branch(address() + O, a_dst); } - template + template std::uintptr_t write_branch(const F a_dst) requires(std::same_as) { - return SFSE::GetTrampoline().write_branch(address(), stl::unrestricted_cast(a_dst)); + return SFSE::GetTrampoline().write_branch(address() + O, stl::unrestricted_cast(a_dst)); } - template + template std::uintptr_t write_call(const std::uintptr_t a_dst) requires(std::same_as) { - return SFSE::GetTrampoline().write_call(address(), a_dst); + return SFSE::GetTrampoline().write_call(address() + O, a_dst); } - template + template std::uintptr_t write_call(const F a_dst) requires(std::same_as) { - return SFSE::GetTrampoline().write_call(address(), stl::unrestricted_cast(a_dst)); + return SFSE::GetTrampoline().write_call(address() + O, stl::unrestricted_cast(a_dst)); } void write_fill(const std::uint8_t a_value, const std::size_t a_count) diff --git a/include/SFSE/Utilities.h b/include/SFSE/Utilities.h index 2ff6cdd3..33d8dcaa 100644 --- a/include/SFSE/Utilities.h +++ b/include/SFSE/Utilities.h @@ -5,39 +5,84 @@ namespace SFSE::stl { - template + template constexpr void write_thunk_call(const std::uintptr_t a_address) noexcept { - AllocTrampoline(14); - auto& trampoline = GetTrampoline(); - T::func = trampoline.write_call(a_address, T::thunk); + T::func = GetTrampoline().write_call(a_address, T::thunk); } - template + template + constexpr void write_thunk_call(const U a_id) noexcept + requires(std::is_same_v || std::is_same_v) + { + T::func = GetTrampoline().write_call(a_id.address(), T::thunk); + } + + template + constexpr void write_thunk_call(const REL::Relocation a_id) noexcept + requires(std::is_same_v::value_type, std::uintptr_t>) + { + T::func = GetTrampoline().write_call(a_id.address(), T::thunk); + } + + template constexpr void write_thunk_call() noexcept { - write_thunk_call(T::address); + write_thunk_call(T::address); + } + + template + constexpr void write_thunk_jump(const std::uintptr_t a_address) noexcept + { + T::func = GetTrampoline().write_branch(a_address, T::thunk); + } + + template + constexpr void write_thunk_jump(const U a_id) noexcept + requires(std::is_same_v || std::is_same_v) + { + T::func = GetTrampoline().write_branch(a_id.address(), T::thunk); + } + + template + constexpr void write_thunk_jump(const REL::Relocation a_id) noexcept + requires(std::is_same_v::value_type, std::uintptr_t>) + { + T::func = GetTrampoline().write_branch(a_id.address(), T::thunk); + } + + template + constexpr void write_thunk_jump() noexcept + { + write_thunk_jump(T::address); } template - constexpr void write_vfunc(const REL::ID a_id) noexcept + constexpr void write_vfunc(const std::uintptr_t a_address) noexcept { - static REL::Relocation vtbl{ a_id }; + static REL::Relocation vtbl{ REL::Offset(a_address) }; T::func = vtbl.write_vfunc(T::idx, T::thunk); } - template - constexpr void write_vfunc(const std::size_t a_vtableIdx = 0) noexcept + template + constexpr void write_vfunc(const U a_id) noexcept + requires(std::is_same_v || std::is_same_v) { - write_vfunc(To::VTABLE[a_vtableIdx]); + static REL::Relocation vtbl{ a_id }; + T::func = vtbl.write_vfunc(T::idx, T::thunk); } - template - constexpr void write_thunk_jump(const std::uintptr_t a_src) noexcept + template + constexpr void write_vfunc(const REL::Relocation a_id) noexcept + requires(std::is_same_v::value_type, std::uintptr_t>) { - AllocTrampoline(14); - auto& trampoline = GetTrampoline(); - T::func = trampoline.write_branch(a_src, T::thunk); + T::func = a_id.write_vfunc(T::idx, T::thunk); + } + + template + constexpr void write_vfunc(const std::size_t a_vtableIdx = 0) noexcept + { + write_vfunc(To::VTABLE[a_vtableIdx]); } namespace detail