/
main.cpp
244 lines (212 loc) · 8.49 KB
/
main.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
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
#include <Windows.h>
#include <iostream>
#include <unordered_map>
#include <Winternl.h>
#include <tuple>
#include <d3d11.h>
#include "utils.h"
typedef HRESULT(__stdcall* D3D11PresentHook) (IDXGISwapChain* This, UINT SyncInterval, UINT Flags);
volatile static D3D11PresentHook oPresent = NULL;
uintptr_t** present_pointer;
IDXGISwapChain* globalchain;
extern "C" HRESULT __stdcall hookD3D11Present(IDXGISwapChain * This, UINT SyncInterval, UINT Flags)
{
printf("[>] Handler called! Saving swapchain\n");
globalchain = This;
*present_pointer = (uintptr_t*)oPresent;
return oPresent(This, SyncInterval, Flags);
}
std::unordered_map<std::string, std::tuple<std::string,int>>modules{
{ "gameoverlayrenderer64.dll", std::tuple<std::string,int>("33 F6 83 E5 F7 44 8B C5 8B D6 49 8B CE FF 15", 15) },
{ "DiscordHook64.dll", std::tuple<std::string,int>("48 89 D9 89 FA 41 89 F0 FF 15", 10) },
{ "overlay64.dll", std::tuple<std::string,int>("48 8B 5C 24 40 44 8B 44 24 30 8B 54 24 38 48 8B CB FF 15", 19) },
{ "DiscordHook64.dll", std::tuple<std::string,int>("44 8B C7 8B D6 48 8B CB FF 15", 10) }
};
bool func_anomaly(uintptr_t& present) {
bool found_anomaly = false;
while (true) {
while (true) {
while (*(BYTE*)present == 0xE9) {
if (*(DWORD*)(present + 5) == 0xCCCCCCCC)
found_anomaly = true;
present += *(signed int*)(present + 1) + 5;
}
if (*(WORD*)present != 0x25FF)
break;
present = *(uintptr_t*)(present + 6);
}
if (*(WORD*)present != 0xB848 || *((WORD*)present + 5) != 0xE0FF)
break;
present = *(uintptr_t*)(present + 2);
found_anomaly = true;
}
return found_anomaly;
}
bool find_memory_anomaly(uintptr_t present) {
bool found_anomaly = false;
MEMORY_BASIC_INFORMATION mbi = { 0 };
MEMORY_BASIC_INFORMATION mbi2 = { 0 };
NTSTATUS v27 = NtQueryVirtualMemory((HANDLE) - 1, (LPVOID)present, MemoryBasicInformation, &mbi, 48i64, 0) < 0;
NTSTATUS v7 = v27;
NTSTATUS v28;
bool v31 = v27
|| mbi.State != MEM_COMMIT
|| mbi.Type != MEM_IMAGE
&& (mbi.Type != MEM_PRIVATE
|| mbi.State != MEM_FREE
|| *((uintptr_t*)present + 20) != 0xEBFFFFFF41058D48ui64
|| (present = *((uintptr_t*)present - 3),
v28 = NtQueryVirtualMemory((HANDLE) - 1i64, (LPVOID)present, MemoryBasicInformation, &mbi2, 48i64, 0) < 0,
v7 = v28)
|| mbi2.State != MEM_COMMIT
|| mbi2.Type != MEM_IMAGE)
|| mbi.Protect != 16 && mbi.Protect != 32 && mbi.Protect != 64 && mbi.Protect != 128
|| *(uintptr_t*)present == 0x74894808245C8948i64
&& (*((uintptr_t*)present + 1) == 0x4140EC8348571024i64
|| *((uintptr_t*)present + 1) == 0x5518247C89481024i64)
|| *(uintptr_t*)present == 0x57565520245C8948i64
|| *(uintptr_t*)present == 0x4157551824748948i64
|| *(uintptr_t*)present == 0x8D48564157565540ui64
|| *(DWORD*)present == 1220840264 && *((WORD*)present + 2) == 22665
|| *(uintptr_t*)present == 0x5741564157565340i64
|| *(uintptr_t*)present == 0x5741564155C48B48i64
|| *(uintptr_t*)present == 0x4156415441575540i64;
found_anomaly = v31;
return found_anomaly;
}
int main() {
bool reported = false;
//General report
{
uintptr_t base = (uintptr_t)GetModuleHandleA("dxgi.dll");
if (base) {
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)(base + dos->e_lfanew);
DWORD code_base = nt->OptionalHeader.BaseOfCode;
DWORD code_size = nt->OptionalHeader.SizeOfCode;
uintptr_t code_start = code_base + base;
uintptr_t sig_base = utils::scanpattern(code_start, code_size, "48 C7 40 B8 FE FF FF FF 48 89 58 18");
if (sig_base) {
uintptr_t swap_chain = sig_base + *(signed int*)(sig_base + 0x25) + 0x29;
uintptr_t present = *(uintptr_t*)(swap_chain + 0x40);
MEMORY_BASIC_INFORMATION mbi_globalchain = { 0 };
NTSTATUS globalchainstatus = NtQueryVirtualMemory((HANDLE)-1, (PVOID)swap_chain, MemoryBasicInformation, (PVOID)&mbi_globalchain, sizeof(mbi_globalchain), 0);
if (globalchainstatus || func_anomaly(present)) {
reported = true;
printf("[!!!] Anomaly at: %p\n", present);
}
else
{
printf("[>] No anomalys found jump chain ends at %p\n", present);
printf("[>] Verifying memory!\n");
if (find_memory_anomaly(present)) {
printf("[!!!] Memory anomaly at destination!\n");
reported = true;
}
}
printf("==GENERAL REPORT==\n");
printf("Report: %x %x\n", 0x47, 0x1);
printf("Present: %p\n", present);
printf("First 32 bytes...\n");
printf("Allocation base: %p\n", mbi_globalchain.AllocationBase);
printf("Base address: %p\n", mbi_globalchain.BaseAddress);
}
}
}
//Module specific detections
int idx = 0;
for (auto pair : modules) {
if (uintptr_t base = (uintptr_t)GetModuleHandleA(pair.first.c_str())) {
present_pointer = 0;
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)(base + dos->e_lfanew);
DWORD code_base = nt->OptionalHeader.BaseOfCode;
DWORD code_size = nt->OptionalHeader.SizeOfCode;
uintptr_t code_start = code_base + base;
uintptr_t sig_base = utils::scanpattern(code_start, code_size, std::get<0>(pair.second).c_str());
if (!sig_base)
continue;
printf("[>] Sig at %p\n", sig_base);
if (idx == 0) { //gameoverlayrenderer64.dll
uintptr_t jmp_dst = sig_base - 0x45;
if (*(BYTE*)jmp_dst == 0xE8 &&
(jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(DWORD*)jmp_dst != 0x83485340)) {
present_pointer = (uintptr_t**)&jmp_dst;
}
}
else if (idx == 1) { //DiscordHook64.dll
uintptr_t jmp_dst = sig_base - 0x13;
if (*(BYTE*)jmp_dst == 0xE8 &&
(jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(BYTE*)jmp_dst == 0xE9) &&
(jmp_dst += *(signed int*)(jmp_dst + 1) + 15, *(BYTE*)jmp_dst == 0xE9) &&
(jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(BYTE*)jmp_dst != 0x56535540)
) {
present_pointer = (uintptr_t**)&jmp_dst;
}
else {
jmp_dst = sig_base - 0xA6;
if (*(BYTE*)jmp_dst == 0xE9 &&
(jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(BYTE*)jmp_dst == 0xE9) &&
(jmp_dst += *(signed int*)(jmp_dst + 1) + 6, **(uintptr_t**)jmp_dst == 0x2454891824448944)
) {
present_pointer = (uintptr_t**)jmp_dst;
}
}
}
if(!present_pointer) { //overlay64.dll or DiscordHook64.dll
present_pointer = (uintptr_t**)(sig_base + std::get<1>(pair.second)+ *(DWORD*)(sig_base + std::get<1>(pair.second)) + 4);
}
if (present_pointer && *present_pointer) {
MEMORY_BASIC_INFORMATION mbi = { 0 };
NTSTATUS status = NtQueryVirtualMemory((HANDLE) - 1, *present_pointer, MemoryBasicInformation, (PVOID) & mbi, sizeof(mbi), 0);
if (status || mbi.State != MEM_COMMIT || mbi.Type != MEM_PRIVATE || mbi.Protect != PAGE_EXECUTE_READWRITE || *(DWORD*)(*present_pointer) == 0x50C03148) { //xor rax, rax push rax
printf("[!!!] Present is invalid memory! %p %p\n", status, &mbi);
reported = true;
}
printf("[>] Present pointer in %s at %p\n", pair.first.c_str(), present_pointer);
oPresent = (D3D11PresentHook)*present_pointer;
*present_pointer = (uintptr_t*)hookD3D11Present;
Sleep(1000); //Sleep and hope that present got called once
printf("[>] Found SwapChain at %p\n", globalchain);
MEMORY_BASIC_INFORMATION mbi_globalchain = { 0 };
NTSTATUS globalchainstatus = NtQueryVirtualMemory((HANDLE)-1, globalchain, MemoryBasicInformation, (PVOID)&mbi_globalchain, sizeof(mbi_globalchain), 0);
uintptr_t present_from_vtable = *(uintptr_t*)(*(uintptr_t*)(globalchain)+0x40);
if (globalchainstatus || func_anomaly(present_from_vtable)) {
reported = true;
printf("[!!!] Anomaly at: %p\n", present_from_vtable);
}
else
{
printf("[>] No anomalys found jump chain ends at %p\n", present_from_vtable);
printf("[>] Verifying memory!\n");
if (find_memory_anomaly(present_from_vtable)) {
printf("[!!!] Memory anomaly at destination!\n");
reported = true;
}
}
}
}
idx++;
}
if (reported) {
printf("[!!!] You received reports!\n");
}
else {
printf("[>] No reports! You're good to go\n");
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH: {
AllocConsole();
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout);
main();
break;
}
}
return TRUE;
}