Defcon/hook_lib/spoof_call.h

121 lines
2.0 KiB
C
Raw Permalink Normal View History

2023-11-26 08:54:06 -05:00
#pragma once
#include <type_traits>
namespace detail
{
extern "C" void* _spoofer_stub();
template <typename Ret, typename... Args>
static inline auto shellcode_stub_helper(
const void* shell,
Args... args
) -> Ret
{
auto fn = (Ret(*)(Args...))(shell);
return fn(args...);
}
template <std::size_t Argc, typename>
struct argument_remapper
{
// At least 5 params
template<
typename Ret,
typename First,
typename Second,
typename Third,
typename Fourth,
typename... Pack
>
static auto do_call(
const void* shell,
void* shell_param,
First first,
Second second,
Third third,
Fourth fourth,
Pack... pack
) -> Ret
{
return shellcode_stub_helper<
Ret,
First,
Second,
Third,
Fourth,
void*,
void*,
Pack...
>(
shell,
first,
second,
third,
fourth,
shell_param,
nullptr,
pack...
);
}
};
template <std::size_t Argc>
struct argument_remapper<Argc, std::enable_if_t<Argc <= 4>>
{
// 4 or less params
template<
typename Ret,
typename First = void*,
typename Second = void*,
typename Third = void*,
typename Fourth = void*
>
static auto do_call(
const void* shell,
void* shell_param,
First first = First{},
Second second = Second{},
Third third = Third{},
Fourth fourth = Fourth{}
) -> Ret
{
return shellcode_stub_helper<
Ret,
First,
Second,
Third,
Fourth,
void*,
void*
>(
shell,
first,
second,
third,
fourth,
shell_param,
nullptr
);
}
};
}
template <typename Ret, typename... Args>
static inline auto spoof_call(
const void* trampoline,
Ret(*fn)(Args...),
Args... args
) -> Ret
{
struct shell_params
{
const void* trampoline;
void* function;
void* rbx;
};
shell_params p{ trampoline, reinterpret_cast<void*>(fn) };
using mapper = detail::argument_remapper<sizeof...(Args), void>;
return mapper::template do_call<Ret, Args...>((const void*)&detail::_spoofer_stub, &p, args...);
}