121 lines
2.0 KiB
C
121 lines
2.0 KiB
C
|
#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...);
|
||
|
}
|