Skip to content

Commit

Permalink
Merge pull request #151 from shad0wshayd3-TES5/dev-replace-func
Browse files Browse the repository at this point in the history
refactor: Relocation::replace_func
  • Loading branch information
powerof3 authored Nov 17, 2024
2 parents 105df57 + 74e5bce commit cc3edf1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 40 deletions.
41 changes: 31 additions & 10 deletions include/REL/Relocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,37 @@ namespace REL
return stl::unrestricted_cast<value_type>(_impl);
}

template <std::ptrdiff_t O = 0>
void replace_func(const std::size_t a_count, const std::uintptr_t a_dst) requires(std::same_as<value_type, std::uintptr_t>)
{
#pragma pack(push, 1)
struct Assembly
{
std::uint8_t jmp;
std::uint8_t modrm;
std::int32_t disp;
std::uint64_t addr;
};
static_assert(sizeof(Assembly) == 0xE);
#pragma pack(pop)

Assembly assembly{
.jmp = static_cast<std::uint8_t>(0xFF),
.modrm = static_cast<std::uint8_t>(0x25),
.disp = static_cast<std::int32_t>(0),
.addr = static_cast<std::uint64_t>(a_dst),
};

safe_fill(address() + O, INT3, a_count);
safe_write(address() + O, &assembly, sizeof(assembly));
}

template <std::ptrdiff_t O = 0, class F>
void replace_func(const std::size_t a_count, const F a_dst) requires(std::same_as<value_type, std::uintptr_t>)
{
replace_func<O>(a_count, stl::unrestricted_cast<std::uintptr_t>(a_dst));
}

template <std::integral U>
void write(const U& a_data) requires(std::same_as<value_type, std::uintptr_t>)
{
Expand Down Expand Up @@ -323,16 +354,6 @@ namespace REL
safe_fill(address(), a_value, a_count);
}

#ifdef SKSE_SUPPORT_XBYAK
void write_func(const std::size_t a_count, const std::uintptr_t a_dst) requires(std::same_as<value_type, std::uintptr_t>);

template <class F>
void write_func(const std::size_t a_count, const F a_dst) requires(std::same_as<value_type, std::uintptr_t>)
{
write_func(a_count, stl::unrestricted_cast<std::uintptr_t>(a_dst));
}
#endif

template <class U = value_type>
std::uintptr_t write_vfunc(const std::size_t a_idx, const std::uintptr_t a_newFunc) requires(std::same_as<U, std::uintptr_t>)
{
Expand Down
30 changes: 0 additions & 30 deletions src/REL/Relocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,3 @@ namespace REL
assert(success);
}
}

#ifdef SKSE_SUPPORT_XBYAK
# include <xbyak/xbyak.h>

namespace REL
{
struct write_func_impl : Xbyak::CodeGenerator
{
write_func_impl(std::uintptr_t a_dst)
{
Xbyak::Label dst;
jmp(ptr[rip + dst]);
L(dst);
dq(a_dst);
}
};

template <class T>
void Relocation<T>::write_func(const std::size_t a_count, const std::uintptr_t a_dst) requires(std::same_as<value_type, std::uintptr_t>)
{
safe_fill(address(), INT3, a_count);
auto patch = write_func_impl{ a_dst };
patch.ready();
assert(patch.getSize() <= a_count);
safe_write(address(), std::span{ patch.getCode<const std::byte*>(), patch.getSize() });
}

template void Relocation<std::uintptr_t>::write_func(const std::size_t, const std::uintptr_t);
}
#endif

0 comments on commit cc3edf1

Please sign in to comment.