-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShadowRebirth.cpp
283 lines (246 loc) · 8.79 KB
/
ShadowRebirth.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
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
// ShadowRebirth.cpp
#include "ShadowRebirth.h"
#include <tlhelp32.h>
#include <psapi.h>
#include <iostream>
#include <sstream>
// Typedef for NtUnmapViewOfSection
typedef LONG(NTAPI* pNtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);
// Global variable for saving the child process ID
DWORD child_pid = 0;
void SetColor(WORD color) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole != INVALID_HANDLE_VALUE) {
SetConsoleTextAttribute(hConsole, color);
}
}
void ResetColor() {
SetColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
DWORD GetParentProcessID(DWORD pid) {
DWORD ppid = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe)) {
do {
if (pe.th32ProcessID == pid) {
ppid = pe.th32ParentProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
}
return ppid;
}
std::vector<HMODULE> GetProcessModules(DWORD processID) {
std::vector<HMODULE> modules;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
if (hProcess) {
HMODULE hMods[1024];
DWORD cbNeeded;
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
modules.push_back(hMods[i]);
}
}
CloseHandle(hProcess);
}
return modules;
}
// Function for determining the module name based on the handle
std::wstring GetModuleName(HMODULE hModule, DWORD processID) {
wchar_t szModName[MAX_PATH];
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
if (hProcess) {
if (GetModuleFileNameExW(hProcess, hModule, szModName, sizeof(szModName) / sizeof(wchar_t))) {
std::wstring fullPath(szModName);
size_t pos = fullPath.find_last_of(L"\\/");
CloseHandle(hProcess);
return (pos != std::wstring::npos) ? fullPath.substr(pos + 1) : fullPath;
}
CloseHandle(hProcess);
}
return L"";
}
// Function for checking whether a specific DLL is loaded
bool IsDLLLoaded(const std::vector<HMODULE>& modules, const std::wstring& dllName, DWORD processID) {
for (const auto& mod : modules) {
std::wstring modName = GetModuleName(mod, processID);
if (_wcsicmp(modName.c_str(), dllName.c_str()) == 0) {
return true;
}
}
return false;
}
// Function for unloading the DLL using NtUnmapViewOfSection
bool UnmapDLLFunc(DWORD processID, const std::wstring& dllName) {
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if (!hProcess) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Error opening the process. Error code: " << GetLastError() << L"\n";
ResetColor();
return false;
}
std::vector<HMODULE> modules = GetProcessModules(processID);
HMODULE hTargetDLL = nullptr;
for (const auto& mod : modules) {
if (_wcsicmp(GetModuleName(mod, processID).c_str(), dllName.c_str()) == 0) {
hTargetDLL = mod;
break;
}
}
if (!hTargetDLL) {
SetColor(FOREGROUND_GREEN);
std::wcerr << L"[+] DLL " << dllName << L" was not found.\n";
ResetColor();
CloseHandle(hProcess);
return false;
}
HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
if (!hNtdll) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] ntdll.dll is not loaded.\n";
ResetColor();
CloseHandle(hProcess);
return false;
}
auto NtUnmapViewOfSection = (pNtUnmapViewOfSection)GetProcAddress(hNtdll, "NtUnmapViewOfSection");
if (!NtUnmapViewOfSection) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] NtUnmapViewOfSection was not found.\n";
ResetColor();
CloseHandle(hProcess);
return false;
}
LONG status = NtUnmapViewOfSection(hProcess, (PVOID)hTargetDLL);
if (status != 0) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Error when unmapping the DLL: " << status << L"\n";
ResetColor();
CloseHandle(hProcess);
return false;
}
SetColor(FOREGROUND_GREEN);
std::wcout << L"[+] DLL " << dllName << L" successfully unmapped.\n";
ResetColor();
CloseHandle(hProcess);
return true;
}
// Function for determining the path of the current executable program
std::wstring GetExecutablePath() {
wchar_t path[MAX_PATH];
if (GetModuleFileNameW(NULL, path, MAX_PATH) == 0) {
return L"";
}
return std::wstring(path);
}
// Function for starting a new instance of the process in the suspended state
bool StartSelfSuspended(DWORD currentPID, PROCESS_INFORMATION& pi) {
std::wstring exePath = GetExecutablePath();
if (exePath.empty()) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Could not determine the path of the executable program.\n";
ResetColor();
return false;
}
// Create the command line for the new process without special arguments
std::wstringstream cmd;
cmd << L"\"" << exePath << L"\"";
std::wstring commandLine = cmd.str();
// STARTUPINFOW initializing
STARTUPINFOW si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Create the new process in suspended state
BOOL success = CreateProcessW(
NULL,
const_cast<LPWSTR>(commandLine.c_str()),
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP | CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi
);
if (!success) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Error when starting the new process in suspended state. Error code: " << GetLastError() << L"\n";
ResetColor();
return false;
}
SetColor(FOREGROUND_GREEN);
std::wcout << L"[+] New process successfully started in suspended state. PID: " << pi.dwProcessId << L"\n";
ResetColor();
child_pid = pi.dwProcessId; // Save the child process ID
std::wcout << L"[+] Child PID is " << child_pid << L"\n";
return true;
}
// Function to resume the new process
bool ResumeProcess(PROCESS_INFORMATION& pi) {
if (ResumeThread(pi.hThread) == (DWORD)-1) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Error when resuming the new process. Error code: " << GetLastError() << L"\n";
ResetColor();
return false;
}
SetColor(FOREGROUND_GREEN);
std::wcout << L"[+] New process successfully resumed.\n";
ResetColor();
// Closing Handles
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
// Function for initialising the anti-debugging measures
bool InitializeAntiDebugging(DWORD currentPID, DWORD parentPID, const std::wstring& targetDLL) {
// List the modules in the parent process
std::vector<HMODULE> parentModules = GetProcessModules(parentPID);
bool dllLoaded = IsDLLLoaded(parentModules, targetDLL, parentPID);
if (dllLoaded) {
SetColor(FOREGROUND_RED);
std::wcout << L"[+] DLL " << targetDLL << L" is loaded in the parent process. Initiate the anti-debugging measures.\n";
ResetColor();
PROCESS_INFORMATION pi;
if (!StartSelfSuspended(currentPID, pi)) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Could not start the new process.\n";
ResetColor();
return false;
}
// Unloading the DLL from the parent process
if (!UnmapDLLFunc(parentPID, targetDLL)) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Error when unmapping the DLL from the parent process.\n";
ResetColor();
// Terminate the new process if unmapping has failed
TerminateProcess(pi.hProcess, 1);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return false;
}
// Resume process
if (!ResumeProcess(pi)) {
SetColor(FOREGROUND_RED);
std::wcerr << L"[-] Error when resuming the new process.\n";
ResetColor();
return false;
}
// End the current process
SetColor(FOREGROUND_GREEN);
std::wcout << L"[+] Current process is terminated.\n";
ResetColor();
ExitProcess(0);
}
else {
SetColor(FOREGROUND_GREEN);
std::wcout << L"[+] DLL " << targetDLL << L" is not loaded in the parent process. No action required.\n";
ResetColor();
}
return true;
}