forked from NtRaiseHardError/Heavens-Gate-2.0
-
Notifications
You must be signed in to change notification settings - Fork 0
/
HeavensGate.h
341 lines (279 loc) · 9.18 KB
/
HeavensGate.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
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/*
Made by David Cernak - Dadas1337
Donate some Bitcoin : 1LaLSsqSU1woJ72k9FByNjUF7dLzS6u443
*/
#define uint64_t unsigned long long int
#define uint32_t unsigned
#define uint16_t unsigned short
#define uint8_t unsigned char
void memcpy64(uint64_t dst, uint64_t src, uint64_t sz) {
char inst[] = {
/*32bit:
push 0x33
push _next_64bit_block
retf*/
0x6A, 0x33, 0x68, 0x44, 0x33, 0x22, 0x11, 0xCB,
/*64bit:
push rsi
push rdi
mov rsi,src
mov rdi,dst
mov rcx,sz
rep movsb
pop rdi
pop rsi
push 0x23
push _next_32bit_block
retfq*/
0x56, 0x57, 0x48, 0xBE, 0x88, 0x77, 0x66, 0x55,
0x44, 0x33, 0x22, 0x11, 0x48, 0xBF, 0x88, 0x77,
0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x48, 0xB9,
0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
0xF3, 0xA4, 0x5F, 0x5E, 0x6A, 0x23, 0x68, 0x44,
0x33, 0x22, 0x11, 0x48, 0xCB,
/*32bit:
ret*/
0xC3
};
static char *r = NULL;
if (!r) {
r = (char*)VirtualAlloc(0, sizeof(inst), 0x3000, 0x40);
for (int i = 0; i < sizeof(inst); i++)r[i] = inst[i];
}
*(uint32_t*)(r + 3) = (uint32_t)(r + 8);
*(uint64_t*)(r + 12) = (uint64_t)(src);
*(uint64_t*)(r + 22) = (uint64_t)(dst);
*(uint64_t*)(r + 32) = (uint64_t)(sz);
*(uint32_t*)(r + 47) = (uint32_t)(r + 53);
((void(*)(void))(r))();
}
void GetPEB64(void *peb) {
char inst[] = {
/*32bit:
mov esi,peb
push 0x33
push _next_64bit_block
retf*/
0xBE, 0x44, 0x33, 0x22, 0x11, 0x6A, 0x33, 0x68,
0x44, 0x33, 0x22, 0x11, 0xCB,
/*64bit:
mov rax,GS:[0x60]
mov [esi],rax
push 0x23
push _next_32bit_block
retfq*/
0x65, 0x48, 0x8B, 0x04, 0x25, 0x60, 0x00, 0x00,
0x00, 0x67, 0x48, 0x89, 0x06, 0x6A, 0x23, 0x68,
0x44, 0x33, 0x22, 0x11, 0x48, 0xCB,
/*32bit:
ret*/
0xC3
};
static char *r = NULL;
if (!r) {
r = (char*)VirtualAlloc(0, sizeof(inst), 0x3000, 0x40);
memcpy64((uint64_t)(unsigned)r, (uint64_t)(unsigned)inst, sizeof(inst));
}
*(uint32_t*)(r + 1) = (uint32_t)(peb);
*(uint32_t*)(r + 8) = (uint32_t)(r + 13);
*(uint32_t*)(r + 29) = (uint32_t)(r + 35);
((void(*)(void))(r))();
}
uint64_t GetModuleLDREntry(wchar_t *name) {
uint64_t ptr;
GetPEB64(&ptr);
memcpy64((uint64_t)(unsigned)(&ptr), ptr + 24, 8);//PTR -> PPEB_LDR_DATA LoaderData;
uint64_t start = ptr + 16;
memcpy64((uint64_t)(unsigned)(&ptr), ptr + 16, 8);//PTR -> LIST_ENTRY64 InLoadOrderModuleList.FirstBlink
while (start != ptr) {
uint64_t tmp;
memcpy64((uint64_t)(unsigned)(&tmp), ptr + 96, 8); //TMP -> UNICODE_STRING Basename -> Buffer
if (tmp) {
wchar_t kek[32];
memcpy64((uint64_t)(unsigned)kek, tmp, 60); //KEK = Basename
if (!lstrcmpiW(name, kek))return ptr;
}
memcpy64((uint64_t)(unsigned)(&ptr), ptr, 8); //PTR -> Flink
}
return 0;
}
uint64_t GetModuleHandle64(wchar_t *name) {
uint64_t ldr = GetModuleLDREntry(name);
if (!ldr)return 0;
uint64_t base;
memcpy64((uint64_t)(unsigned)(&base), ldr + 48, 8);
return base;
}
uint64_t X64Call(uint64_t proc, unsigned n, ...) {
uint64_t *args = (&n) + 1;
if (n<4)n = 4;
uint8_t stackfix = (n % 2) ? 8 : 0;
static char inst[] = {
/*32bit:
push 0x33
push _next_64bit_block
retf*/
0x6A, 0x33, 0x68, 0x44, 0x33, 0x22, 0x11, 0xCB,
/*64bit:
push rsi
push rbx
mov rbx,rsp
and rbx,0xf
add rbx,stackfix
sub rsp,rbx
mov rcx,number of stack args
mov rsi,last (most right) arg ptr
cmp rcx,0
jz skip
nextarg:
push qword[rsi]
sub rsi,8
loop nextarg
skip:
mov r9,[rsi]
sub rsi,8
mov r8,[rsi]
sub rsi,8
mov rdx,[rsi]
sub rsi,8
mov rcx,[rsi]
sub rsp,32
mov rax,proc
call rax
add rsp,32+(8*stackargs)
add rsp,rbx
pop rbx
mov rsi,&ret
mov [rsi],rax
pop rsi
push 0x23
push _next_32bit_block
retfq*/
0x56, 0x53, 0x48, 0x89, 0xE3, 0x48, 0x83, 0xE3,
0x0F, 0x48, 0x83, 0xC3, 0x38, 0x48, 0x29, 0xDC,
0x48, 0xC7, 0xC1, 0x39, 0x00, 0x00, 0x00, 0x48,
0xC7, 0xC6, 0x44, 0x33, 0x22, 0x11, 0x48, 0x83,
0xF9, 0x00, 0x74, 0x09, 0xFF, 0x76, 0x00, 0x48,
0x83, 0xEE, 0x08, 0xE2, 0xF7, 0x4C, 0x8B, 0x0E,
0x48, 0x83, 0xEE, 0x08, 0x4C, 0x8B, 0x06, 0x48,
0x83, 0xEE, 0x08, 0x48, 0x8B, 0x16, 0x48, 0x83,
0xEE, 0x08, 0x48, 0x8B, 0x0E, 0x48, 0x83, 0xEC,
0x20, 0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44,
0x33, 0x22, 0x11, 0xFF, 0xD0, 0x48, 0x83, 0xC4,
0x69, 0x48, 0x01, 0xDC, 0x5B, 0x48, 0xC7, 0xC6,
0x44, 0x33, 0x22, 0x11, 0x48, 0x89, 0x06, 0x5E,
0x6A, 0x23, 0x68, 0x44, 0x33, 0x22, 0x11, 0x48,
0xCB,
/*32bit:
ret*/
0xC3
};
static char *r = NULL;
if (!r) {
r = (char*)VirtualAlloc(0, sizeof(inst), 0x3000, 0x40);
memcpy64((uint64_t)(unsigned)r, (uint64_t)(unsigned)inst, sizeof(inst));
}
uint64_t ret;
*(uint32_t*)(r + 3) = (uint32_t)(r + 8);
*(uint8_t*)(r + 20) = stackfix;
*(uint8_t*)(r + 27) = (uint8_t)(((n>4) ? (n - 4) : 0));
*(uint32_t*)(r + 34) = (uint32_t)(&args[n - 1]);
*(uint64_t*)(r + 83) = proc;
*(uint8_t*)(r + 96) = (uint8_t)(32 + ((n > 4) ? ((n - 4) * 8) : 0));
*(uint32_t*)(r + 104) = (uint32_t)(&ret);
*(uint32_t*)(r + 115) = (uint32_t)(r + 121);
((void(*)(void))(r))();
return ret;
}
uint64_t MyGetProcAddress(uint64_t module, char *func) {
IMAGE_DOS_HEADER dos;
memcpy64((uint64_t)(unsigned)(&dos), module, sizeof(dos));
IMAGE_NT_HEADERS64 nt;
memcpy64((uint64_t)(unsigned)(&nt), module + dos.e_lfanew, sizeof(nt));
IMAGE_EXPORT_DIRECTORY exp;
memcpy64((uint64_t)(unsigned)(&exp), module + nt.OptionalHeader.DataDirectory[0].VirtualAddress, sizeof(exp));
for (DWORD i = 0; i < exp.NumberOfNames; i++){
DWORD nameptr;
memcpy64((uint64_t)(unsigned)(&nameptr), module + exp.AddressOfNames + (4 * i), 4);
char name[64];
memcpy64((uint64_t)(unsigned)name, module + nameptr, 64);
if (!lstrcmpA(name, func)) {
WORD ord;
memcpy64((uint64_t)(unsigned)(&ord), module + exp.AddressOfNameOrdinals + (2 * i), 2);
uint32_t adr;
memcpy64((uint64_t)(unsigned)(&adr), module + exp.AddressOfFunctions + (4 * ord), 4);
return module + adr;
}
}
return 0;
}
void MakeUTFStr(char *str, char *out) {
uint32_t len = lstrlenA(str);
*(uint16_t*)(out) = (uint16_t)(len * 2); //Length
*(uint16_t*)(out + 2) = (uint16_t)((len + 1) * 2); //Max Length
WORD *outstr = (WORD*)(out + 16);
for (uint32_t i = 0; i <= len; i++)outstr[i] = str[i];
*(uint64_t*)(out + 8) = (uint64_t)(unsigned)(out + 16);
}
uint64_t GetKernel32() {
static uint64_t kernel32 = 0;
if (kernel32)return kernel32;
uint64_t ntdll = GetModuleHandle64(L"ntdll.dll");
uint64_t LdrLoadDll = MyGetProcAddress(ntdll, "LdrLoadDll");
char str[64];
MakeUTFStr("kernel32.dll",str);
X64Call(LdrLoadDll, 4, (uint64_t)0, (uint64_t)0, (uint64_t)(unsigned)str, (uint64_t)(unsigned)(&kernel32));
if (!kernel32) {
//Windows 7 stuff - based on http://rce.co/knockin-on-heavens-gate-dynamic-processor-mode-switching/
uint64_t LdrGetKnownDllSectionHandle = MyGetProcAddress(ntdll, "LdrGetKnownDllSectionHandle");
uint64_t NtMapViewOfSection = MyGetProcAddress(ntdll, "NtMapViewOfSection");
uint64_t NtUnmapViewOfSection = MyGetProcAddress(ntdll, "NtUnmapViewOfSection");
uint64_t NtFreeVirtualMemory = MyGetProcAddress(ntdll, "NtFreeVirtualMemory");
wchar_t *dlls[] = { L"kernelbase.dll", L"kernel32.dll", L"user32.dll" };
for (int i = 1; i < 3; i++) {
uint64_t section = 0;
uint64_t base = 0;
uint64_t size = 0;
X64Call(LdrGetKnownDllSectionHandle, 3, (uint64_t)(unsigned)(dlls[i]), (uint64_t)0, (uint64_t)(unsigned)(§ion));
X64Call(NtMapViewOfSection, 10, section,
(uint64_t)-1, (uint64_t)(unsigned)(&base), (uint64_t)0, (uint64_t)0, (uint64_t)0,
(uint64_t)(unsigned)(&size), (uint64_t)2, (uint64_t)0, (uint64_t)PAGE_READONLY);
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER*)base;
IMAGE_NT_HEADERS64 *nt = (IMAGE_NT_HEADERS64*)(base + dos->e_lfanew);
uint64_t imagebase = nt->OptionalHeader.ImageBase;
uint64_t zero = 0;
X64Call(NtFreeVirtualMemory, 4, (uint64_t)-1, (uint64_t)(unsigned)(&imagebase), (uint64_t)(unsigned)(&zero), (uint64_t)MEM_RELEASE);
X64Call(NtUnmapViewOfSection, 2, (uint64_t)-1, (uint64_t)(unsigned)(&base));
}
X64Call(LdrLoadDll, 4, (uint64_t)0, (uint64_t)0, str, (uint64_t)(unsigned)(&kernel32));
for (int i = 0; i < 2; i++) {
uint64_t base=GetModuleHandle64(dlls[i]);
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER*)base;
IMAGE_NT_HEADERS64 *nt = (IMAGE_NT_HEADERS64*)(base+dos->e_lfanew);
uint64_t r=X64Call(base + nt->OptionalHeader.AddressOfEntryPoint, 3, base, (uint64_t)DLL_PROCESS_ATTACH, (uint64_t)0);
uint64_t ldr = GetModuleLDREntry(dlls[i]);
uint64_t flags;
memcpy64((uint64_t)(unsigned)(&flags), ldr + 104, 8);
flags |= 0x000080000; //LDRP_PROCESS_ATTACH_CALLED
flags |= 0x000004000; //LDRP_ENTRY_PROCESSED
memcpy64(ldr + 104, (uint64_t)(unsigned)(&flags), 8);
WORD loadcount = -1;
memcpy64(ldr + 112, (uint64_t)(unsigned)(&loadcount), 2);
}
}
return kernel32;
}
uint64_t GetProcAddress64(uint64_t module, uint64_t func) {
static uint64_t K32GetProcAddress = 0;
if (!K32GetProcAddress)K32GetProcAddress = MyGetProcAddress(GetKernel32(), "GetProcAddress");
return X64Call(K32GetProcAddress, 2, module, func);
}
uint64_t LoadLibrary64(char *name) {
static uint64_t LoadLibraryA = 0;
if (!LoadLibraryA)LoadLibraryA = GetProcAddress64(GetKernel32(), (uint64_t)(unsigned)"LoadLibraryA");
return X64Call(LoadLibraryA, 1, (uint64_t)(unsigned)name);
}
#undef uint64_t
#undef uint32_t
#undef uint16_t
#undef uint8_t