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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
/*
* Shameless copy pasta from: https://github.com/sidyhe/dxx
*/
#include <cstdio>
#include <cstdlib>
#include <ntddk.h>
#define KCRT_POOL_DEFAULT_TAG 0xDEADBEEF
typedef struct _MALLOC_HEADER
{
ULONG32 Tags;
ULONG32 _Resv0;
ULONG_PTR Size;
} MALLOC_HEADER, *PMALLOC_HEADER;
C_ASSERT(sizeof(MALLOC_HEADER) % sizeof(void *) == 0);
// dynamic memory mgmt
PMALLOC_HEADER GET_MALLOC_HEADER(PVOID ptr)
{
return (MALLOC_HEADER *)((PUCHAR)ptr - sizeof(MALLOC_HEADER));
}
PVOID GET_MALLOC_ADDRESS(PMALLOC_HEADER header)
{
return (PVOID)((PUCHAR)header + sizeof(MALLOC_HEADER));
}
ULONG_PTR GET_MALLOC_SIZE(PVOID ptr)
{
PMALLOC_HEADER header = GET_MALLOC_HEADER(ptr);
if (header->Tags != KCRT_POOL_DEFAULT_TAG)
KeBugCheckEx(BAD_POOL_HEADER, 0, 0, 0, 0);
return header->Size;
}
// c runtime
void __cdecl free(void * ptr)
{
if (ptr)
{
MALLOC_HEADER * mhdr = GET_MALLOC_HEADER(ptr);
if (mhdr->Tags != KCRT_POOL_DEFAULT_TAG)
KeBugCheckEx(BAD_POOL_HEADER, 0, 0, 0, 0);
ExFreePool(mhdr);
}
}
void * __cdecl malloc(size_t size)
{
PMALLOC_HEADER mhdr = NULL;
const size_t new_size = size + sizeof(MALLOC_HEADER);
mhdr = (PMALLOC_HEADER)ExAllocatePoolWithTag(NonPagedPool, new_size, KCRT_POOL_DEFAULT_TAG);
if (mhdr)
{
RtlZeroMemory(mhdr, new_size);
mhdr->Tags = KCRT_POOL_DEFAULT_TAG;
mhdr->Size = size;
return GET_MALLOC_ADDRESS(mhdr);
}
return NULL;
}
void * __cdecl realloc(void * ptr, size_t new_size)
{
if (!ptr)
{
return malloc(new_size);
}
else if (new_size == 0)
{
free(ptr);
return NULL;
}
else
{
size_t old_size = GET_MALLOC_SIZE(ptr);
if (new_size <= old_size)
{
return ptr;
}
else
{
void * new_ptr = malloc(new_size);
if (new_ptr)
{
memcpy(new_ptr, ptr, old_size);
free(ptr);
return new_ptr;
}
}
}
return NULL;
}
// new & delete
void * __cdecl operator new(std::size_t size)
{
return malloc(size);
}
void * __cdecl operator new[](size_t size)
{
return malloc(size);
}
void __cdecl operator delete(void * ptr)
{
free(ptr);
}
void __cdecl operator delete(void * ptr, size_t)
{
free(ptr);
}
void __cdecl operator delete[](void * ptr, long long unsigned int)
{
free(ptr);
}
void __cdecl operator delete[](void * ptr)
{
free(ptr);
}
// EASTL
void * operator new[](size_t size, const char *, int, unsigned, const char *, int)
{
return malloc(size);
}
void * operator new[](size_t size, size_t, size_t, const char *, int, unsigned, const char *, int)
{
return malloc(size);
}
extern "C" void __cxa_pure_virtual(void)
{
// definitly not perfect, but we get at least a notification
while (1)
{
DbgPrint("Pure virtual function call..\n");
LARGE_INTEGER li = { .QuadPart = -10000000 };
KeDelayExecutionThread(KernelMode, TRUE, &li);
}
}
// stolen from musl: https://elixir.bootlin.com/musl/v1.1.9/source/src/math/ceilf.c
#define FORCE_EVAL(x) \
do \
{ \
if (sizeof(x) == sizeof(float)) \
{ \
volatile float __x __attribute__((unused)); \
__x = (x); \
} \
else if (sizeof(x) == sizeof(double)) \
{ \
volatile double __x __attribute__((unused)); \
__x = (x); \
} \
else \
{ \
volatile long double __x __attribute__((unused)); \
__x = (x); \
} \
} while (0)
extern "C" float ceilf(float x)
{
union {
float f;
UINT32 i;
} u = {x};
int e = (int)(u.i >> 23 & 0xff) - 0x7f;
UINT32 m;
if (e >= 23)
return x;
if (e >= 0)
{
m = 0x007fffff >> e;
if ((u.i & m) == 0)
return x;
FORCE_EVAL(x + 0x1p120f);
if (u.i >> 31 == 0)
u.i += m;
u.i &= ~m;
}
else
{
FORCE_EVAL(x + 0x1p120f);
if (u.i >> 31)
u.f = -0.0;
else if (u.i << 1)
u.f = 1.0;
}
return u.f;
}
|