Aktualizacja: 2025-10-18 15:32:14
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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";
|
||||
|
||||
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;
|
||||
}
|
||||
// HVCI bypass is handled in Controller::DisableDSE() before calling this function
|
||||
// This function only handles standard DSE patching
|
||||
|
||||
// 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)",
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
22
kvc/Kvc.cpp
22
kvc/Kvc.cpp
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user