-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathReturnSpoof.hpp
120 lines (113 loc) · 2 KB
/
ReturnSpoof.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#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...);
}