-
Notifications
You must be signed in to change notification settings - Fork 2
/
spoof_call.h
125 lines (109 loc) · 2.83 KB
/
spoof_call.h
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
121
122
123
124
125
#pragma once
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <windows.h>
#include "sdkdefines.h"
uintptr_t get_base_address(const wchar_t* mod_name);
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
{
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>>
{
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(Ret(*fn)(Args...), Args... args) -> Ret
{
static const void* jmprbx = nullptr;
if (!jmprbx) {
const auto ntdll = reinterpret_cast<const unsigned char*>(ue::cached::Base);
const auto dos = reinterpret_cast<const IMAGE_DOS_HEADER*>(ntdll);
const auto nt = reinterpret_cast<const IMAGE_NT_HEADERS*>(ntdll + dos->e_lfanew);
const auto sections = IMAGE_FIRST_SECTION(nt);
const auto num_sections = nt->FileHeader.NumberOfSections;
constexpr char section_name[5]{ '.', 't', 'e', 'x', 't' };
const auto section = std::find_if(sections, sections + num_sections, [&](const auto& s) {
return std::equal(s.Name, s.Name + 5, section_name);
});
constexpr unsigned char instr_bytes[2]{ 0xFF, 0x26 };
const auto va = ntdll + section->VirtualAddress;
jmprbx = std::search(va, va + section->Misc.VirtualSize, instr_bytes, instr_bytes + 2);
}
struct shell_params
{
const void* trampoline;
void* function;
void* rdx;
};
shell_params p
{
jmprbx,
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...);
}