t8-mod/source/proxy-dll/spoofer/spoofcall.cpp
2023-11-10 13:52:20 -08:00

92 lines
1.7 KiB
C++

#include <std_include.hpp>
#include <utilities/hook.hpp>
#include <stack>
namespace spoofcall
{
void* callstack_proxy_addr{ nullptr };
static thread_local const void* address_to_call{};
namespace
{
thread_local std::stack<uint64_t> address_stack{};
const void* get_address_to_call()
{
return address_to_call;
}
void store_address(const uint64_t address)
{
address_stack.push(address);
}
uint64_t get_stored_address()
{
const auto res = address_stack.top();
address_stack.pop();
return res;
}
void callstack_return_stub(utilities::hook::assembler& a)
{
a.push(rax);
a.pushad64();
a.call_aligned(get_stored_address);
a.mov(qword_ptr(rsp, 0x80), rax);
a.popad64();
a.add(rsp, 8);
a.jmp(qword_ptr(rsp, -8));
}
uint64_t get_callstack_return_stub()
{
const auto placeholder = 0x1403CF1C6_g;
utilities::hook::set<uint8_t>(placeholder - 2, 0xFF); // fakes a call
utilities::hook::nop(placeholder, 1);
utilities::hook::jump(placeholder + 1, utilities::hook::assemble(callstack_return_stub));
return placeholder;
}
void callstack_stub(utilities::hook::assembler& a)
{
a.push(rax);
a.pushad64();
a.call_aligned(get_address_to_call);
a.mov(qword_ptr(rsp, 0x80), rax);
a.mov(rcx, qword_ptr(rsp, 0x88));
a.call_aligned(store_address);
a.mov(rax, get_callstack_return_stub());
a.mov(qword_ptr(rsp, 0x88), rax);
a.popad64();
a.add(rsp, 8);
a.jmp(qword_ptr(rsp, -8));
}
}
void* get_spoofcall_proxy(const void* funcAddr)
{
static bool spoofer_initialized = false;
if (!spoofer_initialized)
{
callstack_proxy_addr = utilities::hook::assemble(callstack_stub);
}
address_to_call = funcAddr;
return callstack_proxy_addr;
}
}