@@ -278,6 +278,37 @@ namespace REL
278278 return stl::unrestricted_cast<value_type>(_impl);
279279 }
280280
281+ template <std::ptrdiff_t O = 0 >
282+ void replace_func (const std::size_t a_count, const std::uintptr_t a_dst) requires(std::same_as<value_type, std::uintptr_t >)
283+ {
284+ #pragma pack(push, 1)
285+ struct Assembly
286+ {
287+ std::uint8_t jmp;
288+ std::uint8_t modrm;
289+ std::int32_t disp;
290+ std::uint64_t addr;
291+ };
292+ static_assert (sizeof (Assembly) == 0xE );
293+ #pragma pack(pop)
294+
295+ Assembly assembly{
296+ .jmp = static_cast <std::uint8_t >(0xFF ),
297+ .modrm = static_cast <std::uint8_t >(0x25 ),
298+ .disp = static_cast <std::int32_t >(0 ),
299+ .addr = static_cast <std::uint64_t >(a_dst),
300+ };
301+
302+ safe_fill (address () + O, INT3, a_count);
303+ safe_write (address () + O, &assembly, sizeof (assembly));
304+ }
305+
306+ template <std::ptrdiff_t O = 0 , class F >
307+ void replace_func (const std::size_t a_count, const F a_dst) requires(std::same_as<value_type, std::uintptr_t >)
308+ {
309+ replace_func<O>(a_count, stl::unrestricted_cast<std::uintptr_t >(a_dst));
310+ }
311+
281312 void write (const void * a_src, std::size_t a_count) requires(std::same_as<value_type, std::uintptr_t >)
282313 {
283314 safe_write (address (), a_src, a_count);
@@ -329,16 +360,6 @@ namespace REL
329360 safe_fill (address (), a_value, a_count);
330361 }
331362
332- #ifdef F4SE_SUPPORT_XBYAK
333- void write_func (const std::size_t a_count, const std::uintptr_t a_dst) requires(std::same_as<value_type, std::uintptr_t >);
334-
335- template <class F >
336- void write_func (const std::size_t a_count, const F a_dst) requires(std::same_as<value_type, std::uintptr_t >)
337- {
338- write_func (a_count, stl::unrestricted_cast<std::uintptr_t >(a_dst));
339- }
340- #endif
341-
342363 template <class U = value_type>
343364 std::uintptr_t write_vfunc (std::size_t a_idx, std::uintptr_t a_newFunc) requires(std::same_as<U, std::uintptr_t >)
344365 {
0 commit comments