-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcpp.cpp
190 lines (158 loc) · 4.81 KB
/
cpp.cpp
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
extern "C" {
#pragma section(".CRT$XIA", long, read)
#pragma section(".CRT$XIZ", long, read)
#pragma section(".CRT$XCA", long, read)
#pragma section(".CRT$XCZ", long, read)
#pragma section(".CRT$XPA", long, read)
#pragma section(".CRT$XPZ", long, read)
#pragma section(".CRT$XTA", long, read)
#pragma section(".CRT$XTZ", long, read)
#pragma comment(linker, "/merge:.CRT=.rdata")
using _PVFV = void(_cdecl *)(void);
using _PIFV = int(_cdecl *)(void);
// C initializers
__declspec(allocate(".CRT$XIA")) _PIFV __xi_a[] = {0};
__declspec(allocate(".CRT$XIZ")) _PIFV __xi_z[] = {0};
// C++ initializers
__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[] = {0};
__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[] = {0};
// C pre-terminators
__declspec(allocate(".CRT$XPA")) _PVFV __xp_a[] = {0};
__declspec(allocate(".CRT$XPZ")) _PVFV __xp_z[] = {0};
// C terminators
__declspec(allocate(".CRT$XTA")) _PVFV __xt_a[] = {0};
__declspec(allocate(".CRT$XTZ")) _PVFV __xt_z[] = {0};
}
#include <fltKernel.h>
#include "cpp.hpp"
#include <exception>
#include <typeinfo>
void *__cdecl operator new(size_t count)
{
void *result = ExAllocatePoolWithTag(NonPagedPoolNx, count, 'WDMX');
if (!result) {
ExRaiseStatus(STATUS_FATAL_MEMORY_EXHAUSTION);
}
return result;
}
void *__cdecl operator new(size_t, void *address)
{
return address;
}
void __cdecl operator delete(void *address)
{
ExFreePoolWithTag(address, 'WDMX');
}
void __cdecl operator delete[](void *address)
{
ExFreePoolWithTag(address, 'WDMX');
}
void __cdecl operator delete(void *, void *) {}
void __cdecl operator delete(void *address, size_t)
{
::operator delete(address);
}
type_info::~type_info() noexcept {}
namespace std {
_Prhand _Raise_handler;
[[noreturn]] void __cdecl _Xbad_alloc()
{
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
[[noreturn]] void __cdecl _Xinvalid_argument(_In_z_ const char *)
{
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
[[noreturn]] void __cdecl _Xlength_error(_In_z_ const char *)
{
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
[[noreturn]] void __cdecl _Xout_of_range(_In_z_ const char *)
{
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
[[noreturn]] void __cdecl _Xoverflow_error(_In_z_ const char *)
{
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
[[noreturn]] void __cdecl _Xruntime_error(_In_z_ const char *)
{
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
[[noreturn]] void __cdecl _Xbad_function_call()
{
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
const char *__cdecl _Syserror_map(int) { return "unknown error"; }
int __cdecl _Winerror_map(int) { return 0; }
unsigned int __cdecl _Random_device()
{
ULONG value = 0;
return RtlRandomEx(&value);
}
} // namespace std
extern "C" [[nodiscard]] size_t __stdcall __std_system_error_allocate_message(
unsigned long _Message_id, char **_Ptr_str) noexcept
{
return 0;
}
extern "C" void __stdcall __std_system_error_deallocate_message(
char *_Str) noexcept
{
}
[[noreturn]] void __cdecl _invalid_parameter_noinfo_noreturn()
{
ExRaiseStatus(STATUS_INVALID_PARAMETER);
}
[[noreturn]] void __cdecl _invoke_watson(_In_opt_z_ wchar_t const *Expression,
_In_opt_z_ wchar_t const *FunctionName,
_In_opt_z_ wchar_t const *FileName,
_In_ unsigned int LineNo,
_In_ uintptr_t Reserved)
{
ExRaiseStatus(STATUS_INVALID_PARAMETER);
}
using AtExitCallback = void(__cdecl *)();
static AtExitCallback AtExitCallbacks[32];
static AtExitCallback *LastAtExitCallback = AtExitCallbacks - 1;
template<typename F>
static void InvokeFunctions(F *begin, F *end)
{
for (auto pf = begin; pf < end; pf++) {
if (*pf == nullptr) {
continue;
}
using return_type = std::invoke_result_t<F>;
static_assert(std::is_same_v<void, return_type> ||
std::is_same_v<int, return_type>);
if constexpr (std::is_same_v<void, return_type>) {
(**pf)();
}
else if constexpr (std::is_same_v<int, return_type>) {
if ((**pf)()) {
ExRaiseStatus(STATUS_INTERNAL_ERROR);
}
}
}
}
void InvokeCtors()
{
InvokeFunctions(__xi_a, __xi_z);
InvokeFunctions(__xc_a, __xc_z);
}
void InvokeDtors()
{
InvokeFunctions(AtExitCallbacks, LastAtExitCallback + 1);
InvokeFunctions(__xp_a, __xp_z);
InvokeFunctions(__xt_a, __xt_z);
}
extern "C" int __cdecl atexit(AtExitCallback callback)
{
if (!callback) {
return 0;
}
*reinterpret_cast<AtExitCallback *>(InterlockedAdd64(
reinterpret_cast<LONG64 *>(&LastAtExitCallback), sizeof(void *))) =
callback;
return 1;
}