#include namespace detail { extern "C" void* _spoofer_stub(); template static inline auto shellcode_stub_helper( const void* shell, Args... args ) -> Ret { auto fn = (Ret(*)(Args...))(shell); return fn(args...); } template 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 struct argument_remapper> { // 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 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(fn) }; using mapper = detail::argument_remapper; return mapper::template do_call((const void*)&detail::_spoofer_stub, &p, args...); }