Gorstaks Antivirus

 avatar
unknown
powershell
3 months ago
346 kB
5
No Index
# Antivirus.ps1 - Single-file EDR (generated from current Bin logic)
# Author: Gorstak | Usage: .\Antivirus.ps1 | .\Antivirus.ps1 -RemoveRules
#Requires -RunAsAdministrator
param(
    [Parameter(Mandatory=$false)][switch]$RemoveRules = $false,
    [Parameter(Mandatory=$false)][string]$Module = $null
)
$script:ScriptRoot = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path }

# --- OptimizedConfig ---
# Optimized configuration for EDR modules
# Provides tick intervals, scan limits, batch settings, CPU throttling
#Requires -Version 5.1

$script:ModuleTickIntervals = @{
    "HashDetection" = 90
    "ResponseEngine" = 180
    "MemoryScanning" = 90
    "BeaconDetection" = 60
    "NetworkTrafficMonitoring" = 45
    "AMSIBypassDetection" = 90
    "ProcessAnomalyDetection" = 90
    "EventLogMonitoring" = 90
    "FileEntropyDetection" = 120
    "Initializer" = 300
    "PrivacyForgeSpoofing" = 60
}

$script:ScanLimits = @{
    "MaxFiles" = 500
    "MaxProcesses" = 500
    "MaxConnections" = 1000
    "MaxEvents" = 500
    "SampleSizeBytes" = 4096
}

function Get-TickInterval {
    param([string]$ModuleName)
    if ($script:ModuleTickIntervals.ContainsKey($ModuleName)) {
        return $script:ModuleTickIntervals[$ModuleName]
    }
    return 90
}

function Get-ScanLimit {
    param([string]$LimitName)
    if ($script:ScanLimits.ContainsKey($LimitName)) {
        return $script:ScanLimits[$LimitName]
    }
    return 500
}

function Get-BatchSettings {
    return @{
        BatchSize = 50
        BatchDelayMs = 10
    }
}

function Get-LoopSleep {
    return 5
}

function Test-CPULoadThreshold {
    try {
        $cpu = Get-Counter '\Processor(_Total)\% Processor Time' -ErrorAction SilentlyContinue
        if ($cpu -and $cpu.CounterSamples[0].CookedValue -gt 90) { return $true }
    } catch { }
    return $false
}

function Get-CPULoad {
    try {
        $cpu = Get-Counter '\Processor(_Total)\% Processor Time' -ErrorAction SilentlyContinue
        if ($cpu) { return [int]$cpu.CounterSamples[0].CookedValue }
    } catch { }
    return 0
}

function Write-Log {
    param(
        [string]$Level,
        [string]$Message,
        [string]$Category = ""
    )
    
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $output = "[$timestamp] [$Level] $Message"
    
    if ($Category) {
        $output = "[$timestamp] [$Level] [$Category] $Message"
    }
    
    Write-Output $output
}

# --- CacheManager ---
# Cache Manager Module
# Provides caching to reduce repeated expensive operations
#Requires -Version 5.1

$script:SignatureCache = @{}
$script:HashCache = @{}
$script:ProcessCache = @{}
$script:LastCacheClean = Get-Date

function Get-CachedSignature {
    param([string]$FilePath)
    
    $now = Get-Date
    $ttl = 60 # minutes
    
    if ($script:SignatureCache.ContainsKey($FilePath)) {
        $cached = $script:SignatureCache[$FilePath]
        if (($now - $cached.Timestamp).TotalMinutes -lt $ttl) {
            return $cached.Value
        }
    }
    
    try {
        $sig = Get-AuthenticodeSignature -FilePath $FilePath -ErrorAction SilentlyContinue
        $script:SignatureCache[$FilePath] = @{
            Value = $sig
            Timestamp = $now
        }
        return $sig
    } catch {
        return $null
    }
}

function Get-CachedFileHash {
    param(
        [string]$FilePath,
        [string]$Algorithm = "MD5"
    )
    
    $now = Get-Date
    $ttl = 120 # minutes
    $key = "$FilePath|$Algorithm"
    
    if ($script:HashCache.ContainsKey($key)) {
        $cached = $script:HashCache[$key]
        $fileInfo = Get-Item $FilePath -ErrorAction SilentlyContinue
        if ($fileInfo -and $cached.LastWrite -eq $fileInfo.LastWriteTime -and ($now - $cached.Timestamp).TotalMinutes -lt $ttl) {
            return $cached.Value
        }
    }
    
    try {
        $fileInfo = Get-Item $FilePath -ErrorAction SilentlyContinue
        if (-not $fileInfo) { return $null }
        
        $hash = (Get-FileHash -Path $FilePath -Algorithm $Algorithm -ErrorAction SilentlyContinue).Hash
        $script:HashCache[$key] = @{
            Value = $hash
            Timestamp = $now
            LastWrite = $fileInfo.LastWriteTime
        }
        return $hash
    } catch {
        return $null
    }
}

function Clear-ExpiredCache {
    $now = Get-Date
    
    if (($now - $script:LastCacheClean).TotalMinutes -lt 30) {
        return
    }
    
    $script:LastCacheClean = $now
    
    # Clean signature cache
    $expiredSigs = $script:SignatureCache.Keys | Where-Object {
        ($now - $script:SignatureCache[$_].Timestamp).TotalMinutes -gt 60
    }
    foreach ($key in $expiredSigs) {
        $script:SignatureCache.Remove($key)
    }
    
    # Clean hash cache
    $expiredHashes = $script:HashCache.Keys | Where-Object {
        ($now - $script:HashCache[$_].Timestamp).TotalMinutes -gt 120
    }
    foreach ($key in $expiredHashes) {
        $script:HashCache.Remove($key)
    }
}

# --- Initializer ---
# Initializer Module
# Sets up the Antivirus EDR environment - runs once at startup - Optimized for low resource usage

$ModuleName = "Initializer"
$script:LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$Initialized = $false

function Invoke-Initialization {
    try {
        Write-Output "STATS:$ModuleName`:Starting environment initialization"
        
        # Create required directories
        $directories = @(
            "$env:ProgramData\Antivirus",
            "$env:ProgramData\Antivirus\Logs",
            "$env:ProgramData\Antivirus\Data",
            "$env:ProgramData\Antivirus\Modules", 
            "$env:ProgramData\Antivirus\Quarantine",
            "$env:ProgramData\Antivirus\Reports"
        )
        
        foreach ($dir in $directories) {
            if (-not (Test-Path $dir)) {
                New-Item -Path $dir -ItemType Directory -Force | Out-Null
                Write-Output "STATS:$ModuleName`:Created directory: $dir"
            }
        }
        
        # Initialize log files with headers
        $logFiles = @(
            "$env:ProgramData\Antivirus\Logs\System_$(Get-Date -Format 'yyyy-MM-dd').log",
            "$env:ProgramData\Antivirus\Logs\Threats_$(Get-Date -Format 'yyyy-MM-dd').log",
            "$env:ProgramData\Antivirus\Logs\Responses_$(Get-Date -Format 'yyyy-MM-dd').log"
        )
        
        foreach ($logFile in $logFiles) {
            if (-not (Test-Path $logFile)) {
                $header = "# Antivirus EDR Log - Created $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`n# Format: Timestamp|Module|Action|Details`n"
                Set-Content -Path $logFile -Value $header
                Write-Output "STATS:$ModuleName`:Initialized log: $logFile"
            }
        }
        
        # Create Event Log source if it doesn't exist
        try {
            if (-not [System.Diagnostics.EventLog]::SourceExists("AntivirusEDR")) {
                [System.Diagnostics.EventLog]::CreateEventSource("AntivirusEDR", "Application")
                Write-Output "STATS:$ModuleName`:Created Event Log source: AntivirusEDR"
            }
        } catch {
            Write-Output "ERROR:$ModuleName`:Failed to create Event Log source: $_"
        }
        
        # Initialize configuration file
        $configFile = "$env:ProgramData\Antivirus\Data\config.json"
        if (-not (Test-Path $configFile)) {
            $defaultConfig = @{
                Version = "1.0"
                Initialized = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
                LastUpdate = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
                Settings = @{
                    MaxLogSizeMB = 100
                    QuarantineRetentionDays = 30
                    EnableRealTimeResponse = $true
                    ResponseSeverity = "Medium"
                }
            }
            $defaultConfig | ConvertTo-Json -Depth 3 | Set-Content -Path $configFile
            Write-Output "STATS:$ModuleName`:Created configuration file"
        }
        
        # Create status tracking file
        $statusFile = "$env:ProgramData\Antivirus\Data\agent_status.json"
        if (-not (Test-Path $statusFile)) {
            $statusTemplate = @{
                LastCheck = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
                ActiveAgents = @()
                SystemHealth = "Healthy"
                TotalDetections = 0
                TotalResponses = 0
            }
            $statusTemplate | ConvertTo-Json -Depth 3 | Set-Content -Path $statusFile
            Write-Output "STATS:$ModuleName`:Created status tracking file"
        }
        
        # Log initialization completion
        $initLog = "$env:ProgramData\Antivirus\Logs\System_$(Get-Date -Format 'yyyy-MM-dd').log"
        "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|Initializer|Environment|Antivirus EDR environment initialized successfully" | Add-Content -Path $initLog
        
        Write-Output "DETECTION:$ModuleName`:Environment initialization completed"
        return 1
        
    } catch {
        Write-Output "ERROR:$ModuleName`:Initialization failed: $_"
        return 0
    }
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    while ($true) {
        try {
            # CPU throttling - skip scan if CPU load is too high (only for maintenance, not init)
            if ($Initialized -and (Test-CPULoadThreshold)) {
                $cpuLoad = Get-CPULoad
                Write-Output "STATS:$ModuleName`:CPU load too high ($cpuLoad%), skipping check"
                Start-Sleep -Seconds ($loopSleep * 2)  # Sleep longer when CPU is high
                continue
            }
            
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $TickInterval) {
                if (-not $Initialized) {
                    $count = Invoke-Initialization
                    if ($count -gt 0) {
                        $Initialized = $true
                        $TickInterval = Get-TickInterval -ModuleName $ModuleName  # Use optimized interval
                        Write-Output "STATS:$ModuleName`:Initialization complete - switching to maintenance mode"
                    }
                } else {
                    # Maintenance mode - just check system health
                    $statusFile = "$env:ProgramData\Antivirus\Data\agent_status.json"
                    if (Test-Path $statusFile) {
                        $status = Get-Content $statusFile | ConvertFrom-Json
                        $status.LastCheck = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
                        $status | ConvertTo-Json -Depth 3 | Set-Content -Path $statusFile
                        Write-Output "STATS:$ModuleName`:System health check completed"
                    } else {
                        Write-Output "STATS:$ModuleName`:Status file not found, system may need re-initialization"
                    }
                }
                $script:LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 120  # Longer sleep on error
        }
    }
}

# --- HashDetection ---
# Optimized Hash-based Malware Detection Module
# Significantly reduced file I/O and CPU usage


$ModuleName = "HashDetection"
$LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$script:ThreatHashes = @{}
$script:ScannedFiles = @{}
$script:Initialized = $false

function Initialize-HashDatabaseOptimized {
    if ($script:Initialized) {
        return
    }
    
    $threatPath = "$env:ProgramData\Antivirus\HashDatabase\threats.txt"
    if (Test-Path $threatPath) {
        Get-Content $threatPath -ErrorAction SilentlyContinue | ForEach-Object {
            if ($_ -match '^([A-F0-9]{32,64})$') {
                $script:ThreatHashes[$matches[1].ToUpper()] = $true
            }
        }
    }
    
    $script:Initialized = $true
}

function Invoke-HashScanOptimized {
    $threatsFound = @()
    $batchSettings = Get-BatchSettings
    $maxFiles = Get-ScanLimit -LimitName "MaxFiles"
    
    Initialize-HashDatabaseOptimized
    
    $scanPaths = @("$env:APPDATA", "$env:LOCALAPPDATA\Temp", "$env:USERPROFILE\Downloads")
    $scannedCount = 0
    
    foreach ($scanPath in $scanPaths) {
        if (-not (Test-Path $scanPath)) { continue }
        if ($scannedCount -ge $maxFiles) { break }
        
        try {
            $cutoff = (Get-Date).AddHours(-1)
            $files = Get-ChildItem -Path $scanPath -Include *.exe,*.dll -Recurse -File -ErrorAction SilentlyContinue |
                Where-Object { $_.LastWriteTime -gt $cutoff } |
                Select-Object -First ($maxFiles - $scannedCount)
            
            $batchCount = 0
            foreach ($file in $files) {
                $scannedCount++
                
                if ($script:ScannedFiles.ContainsKey($file.FullName)) {
                    $cached = $script:ScannedFiles[$file.FullName]
                    if ($cached.LastWrite -eq $file.LastWriteTime) {
                        continue
                    }
                }
                
                $batchCount++
                if ($batchCount % $batchSettings.BatchSize -eq 0 -and $batchSettings.BatchDelayMs -gt 0) {
                    Start-Sleep -Milliseconds $batchSettings.BatchDelayMs
                }
                
                $hash = Get-CachedFileHash -FilePath $file.FullName -Algorithm "SHA256"
                if (-not $hash) { continue }
                
                # Mark as scanned
                $script:ScannedFiles[$file.FullName] = @{
                    LastWrite = $file.LastWriteTime
                    Hash = $hash
                }
                
                # Check against threat database
                if ($script:ThreatHashes.ContainsKey($hash.ToUpper())) {
                    $threatsFound += @{
                        File = $file.FullName
                        Hash = $hash
                        Threat = "Known Malware Hash"
                    }
                }
            }
        } catch {
            continue
        }
    }
    
    if ($threatsFound.Count -gt 0) {
        $logPath = "$env:ProgramData\Antivirus\Logs\HashDetection_$(Get-Date -Format 'yyyy-MM-dd').log"
        $threatsFound | ForEach-Object {
            "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|THREAT|$($_.File)|$($_.Hash)" | Add-Content -Path $logPath
        }
        Write-Output "DETECTION:$ModuleName`:Found $($threatsFound.Count) hash-based threats"
    }
    
    Write-Output "STATS:$ModuleName`:Scanned=$scannedCount,Threats=$($threatsFound.Count)"
    
    $now = Get-Date
    $oldKeys = $script:ScannedFiles.Keys | Where-Object {
        -not (Test-Path $_)
    }
    foreach ($key in $oldKeys) {
        $script:ScannedFiles.Remove($key)
    }
    
    Clear-ExpiredCache
    return $threatsFound.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    Start-Sleep -Seconds (Get-Random -Minimum 10 -Maximum 60)
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-HashScanOptimized
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 60
        }
    }
}

# --- AMSIBypassDetection ---
# Detects AMSI bypass techniques (amsi.dll patching, etc.)
# Converted from GEDR C# job: JobAMSIBypassDetection
# Enhanced with full implementation from C# version
#Requires -Version 5.1


$ModuleName = "AMSIBypassDetection"
$script:Initialized = $false

# AMSI bypass patterns
$script:BypassPatterns = @(
    "AmsiUtils",
    "AmsiScanBuffer", 
    "amsiInitFailed",
    "Bypass",
    "amsi.dll",
    "amsiutils",
    "PatchAmsi",
    "DisableAmsi",
    "Remove-Amsi",
    "Invoke-AmsiBypass",
    "AMSI.*bypass",
    "bypass.*AMSI",
    "-nop.*-w.*hidden.*-enc",
    "amsi.*off",
    "amsi.*disable",
    "Set-Amsi",
    "Override.*AMSI",
    "System.Management.Automation.AmsiUtils",
    "AmsiContext",
    "AMSI_RESULT_CLEAN",
    "ForceAmsi",
    "Hacking",
    "Context"
)

function Initialize-AMSIBypassDetection {
    if ($script:Initialized) {
        return
    }
    
    Write-Log "INFO" "Initializing AMSI Bypass Detection module"
    $script:Initialized = $true
}

function Get-ProcessList {
    # Get process list similar to GEDR's EdrProcess.GetProcesses
    try {
        $processes = Get-CimInstance -ClassName Win32_Process -ErrorAction SilentlyContinue |
            Select-Object ProcessId, Name, CommandLine, ExecutablePath, ParentProcessId |
            Where-Object { $_.ProcessId -ne $PID }
        
        return $processes
    }
    catch {
        Write-Log "ERROR" "Failed to get process list: $($_.Exception.Message)"
        return @()
    }
}

function Test-ScriptHostProcess {
    param([string]$ProcessName)
    
    if ([string]::IsNullOrEmpty($ProcessName)) {
        return $false
    }
    
    $nameLower = $ProcessName.ToLowerInvariant()
    return ($nameLower.Contains("powershell") -or 
            $nameLower.Contains("pwsh") -or 
            $nameLower.Contains("wscript") -or 
            $nameLower.Contains("cscript"))
}

function Test-AMSIBypassPattern {
    param([string]$CommandLine)
    
    if ([string]::IsNullOrEmpty($CommandLine)) {
        return $false
    }
    
    $cmdLower = $CommandLine.ToLowerInvariant()
    foreach ($pattern in $script:BypassPatterns) {
        if ($cmdLower -match $pattern) {
            return $true
        }
    }
    return $false
}

function Test-ObfuscatedCommand {
    param([string]$CommandLine)
    
    if ([string]::IsNullOrEmpty($CommandLine)) {
        return $false
    }
    
    $cmdLower = $CommandLine.ToLowerInvariant()
    return ($cmdLower.Contains("-enc") -and 
            $cmdLower.Contains("-encodedcommand") -and 
            $CommandLine.Length -gt 500)
}

function Test-AMSIDisabledRegistry {
    # Check if AMSI is disabled via registry
    try {
        # Check common AMSI bypass registry locations
        $amsiPaths = @(
            "HKLM:\SOFTWARE\Microsoft\AMSI",
            "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings",
            "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
        )
        
        foreach ($path in $amsiPaths) {
            if (Test-Path $path) {
                $properties = Get-ItemProperty -Path $path -ErrorAction SilentlyContinue
                if ($properties) {
                    # Check for common AMSI disable values
                    foreach ($prop in $properties.PSObject.Properties) {
                        if ($prop.Name -like "*amsi*" -or $prop.Name -like "*AMSI*") {
                            if ($prop.Value -eq 0 -or $prop.Value -eq "Disabled" -or $prop.Value -eq $false) {
                                return $true
                            }
                        }
                    }
                }
            }
        }
        
        return $false
    }
    catch {
        Write-Log "ERROR" "Error checking AMSI registry: $($_.Exception.Message)"
        return $false
    }
}

function Invoke-ThreatResponse {
    param(
        [int]$ProcessId,
        [string]$ProcessName,
        [string]$ExecutablePath, 
        [string]$ThreatLevel
    )
    
    try {
        # Log threat response
        Write-Log "ACTION" "THREAT RESPONSE: Triggering response for $ProcessName (PID: $ProcessId) - Level: $ThreatLevel" -Category "threat_responses"
        
        # Implement response actions based on threat level
        switch ($ThreatLevel) {
            "High" {
                # For high threats, consider terminating process
                if ($ProcessId -gt 0) {
                    try {
                        Stop-Process -Id $ProcessId -Force -ErrorAction SilentlyContinue
                        Write-Log "ACTION" "THREAT RESPONSE: Terminated high-risk process $ProcessName (PID: $ProcessId)" -Category "threat_responses"
                    }
                    catch {
                        Write-Log "WARNING" "Failed to terminate process $ProcessName (PID: $ProcessId): $($_.Exception.Message)"
                    }
                }
                
                # Quarantine file if it exists
                if ($ExecutablePath -and (Test-Path $ExecutablePath)) {
                    Invoke-QuarantineFile -FilePath $ExecutablePath -Reason "AMSI bypass detection"
                }
            }
            "Critical" {
                # For critical threats, always terminate and quarantine
                if ($ProcessId -gt 0) {
                    try {
                        Stop-Process -Id $ProcessId -Force -ErrorAction SilentlyContinue
                        Write-Log "ACTION" "THREAT RESPONSE: Terminated critical process $ProcessName (PID: $ProcessId)" -Category "threat_responses"
                    }
                    catch {
                        Write-Log "WARNING" "Failed to terminate process $ProcessName (PID: $ProcessId): $($_.Exception.Message)"
                    }
                }
                
                if ($ExecutablePath -and (Test-Path $ExecutablePath)) {
                    Invoke-QuarantineFile -FilePath $ExecutablePath -Reason "Critical AMSI bypass detection"
                }
            }
        }
    }
    catch {
        Write-Log "ERROR" "Error in threat response: $($_.Exception.Message)"
    }
}

function Invoke-QuarantineFile {
    param([string]$FilePath, [string]$Reason)
    
    try {
        $quarantinePath = "$env:ProgramData\Antivirus\Quarantine"
        if (-not (Test-Path $quarantinePath)) {
            New-Item -Path $quarantinePath -ItemType Directory -Force | Out-Null
        }
        
        $fileName = Split-Path $FilePath -Leaf
        $quarantineFile = Join-Path $quarantinePath "$fileName-$([Guid]::NewGuid()).quar"
        
        Move-Item -Path $FilePath -Destination $quarantineFile -Force
        Write-Log "ACTION" "QUARANTINE: $FilePath moved to $quarantineFile (Reason: $Reason)" -Category "quarantine"
    }
    catch {
        Write-Log "ERROR" "Failed to quarantine file $FilePath`: $($_.Exception.Message)"
    }
}

function Invoke-AMSIBypassDetection {
    try {
        Initialize-AMSIBypassDetection
        
        $script:ThreatCount = 0
        $processes = Get-ProcessList
        
        Write-Log "INFO" "Scanning $($processes.Count) processes for AMSI bypass patterns"
        
        foreach ($process in $processes) {
            $processName = if ($process.Name) { $process.Name } else { "" }
            $cmdLine = if ($process.CommandLine) { $process.CommandLine } else { "" }
            
            # Only check script host processes
            if (-not (Test-ScriptHostProcess -ProcessName $processName)) {
                continue
            }
            
            if ([string]::IsNullOrEmpty($cmdLine)) {
                continue
            }
            
            # Check for AMSI bypass patterns
            if (Test-AMSIBypassPattern -CommandLine $cmdLine) {
                $cmdLower = $cmdLine.ToLowerInvariant()
                $pattern = $script:BypassPatterns | Where-Object { $cmdLower -match $_ } | Select-Object -First 1
                
                $dedupeKey = "AMSIBypass_$($process.ProcessId)_$($pattern)"
                if (Test-Deduplication -Key $dedupeKey -Category "amsi_bypass") {
                    Write-Log "THREAT" "AMSI BYPASS: $($process.Name) (PID: $($process.ProcessId)) - Pattern: $pattern" -Category "amsi_bypass_detections"
                    $script:ThreatCount++
                }
                
                # Trigger threat response
                Invoke-ThreatResponse -ProcessId $process.ProcessId -ProcessName $process.Name -ExecutablePath $process.ExecutablePath -ThreatLevel "High"
            }
            
            # Check for obfuscated commands
            if (Test-ObfuscatedCommand -CommandLine $cmdLine) {
                $dedupeKey = "AMSIBypass_$($process.ProcessId)_obfuscated"
                if (Test-Deduplication -Key $dedupeKey -Category "amsi_bypass") {
                    Write-Log "THREAT" "AMSI BYPASS (obfuscated): $($process.Name) (PID: $($process.ProcessId)) - Long encoded command" -Category "amsi_bypass_detections"
                    $script:ThreatCount++
                }
                
                # Trigger critical threat response for obfuscated commands
                Invoke-ThreatResponse -ProcessId $process.ProcessId -ProcessName $process.Name -ExecutablePath $process.ExecutablePath -ThreatLevel "Critical"
            }
        }
        
        # Check registry for AMSI disable
        if (Test-AMSIDisabledRegistry) {
            $dedupeKey = "AMSIBypass_Registry"
            if (Test-Deduplication -Key $dedupeKey -Category "amsi_bypass") {
                Write-Log "THREAT" "AMSI BYPASS: Registry tampering detected - AMSI disabled via registry" -Category "amsi_bypass_detections"
                $script:ThreatCount++
            }
        }
        
        Write-Log "INFO" "AMSI bypass detection completed. Threats found: $script:ThreatCount"
    }
    catch {
        Write-Log "ERROR" "Error in AMSIBypassDetection: $($_.Exception.Message)"
    }
}

# Module exports - scheduler will call Invoke-AMSIBypassDetection on appropriate interval

# Alias for backward compatibility
function Invoke-AMSIBypassScan {
    Invoke-AMSIBypassDetection
}

# --- GFocus ---
# GFocus.ps1 - Network traffic monitor + firewall rule cleanup
# Single script: monitor mode (default) or -RemoveRules to clear NTM_Block_* / BlockedConnection_*
# Monitors IPs; blocks or allows or removes block as the user surfs. Address bar is inferred from
# browser 80/443 connections (no extension): first 80/443 = navigation, within 30s = dependencies.
# Browsers only: games and other apps are never monitored or blocked. Block rules are
# browser-specific (program= + remoteip). DNS IPs (8.8.8.8, 1.1.1.1, etc.) are never blocked.
# Requires Administrator privileges
function Write-ColorOutput {
    param([string]$Message, [string]$Color = "White")
    Write-Host $Message -ForegroundColor $Color
}

# --- Remove-rules mode: clear NTM_Block_* and BlockedConnection_*, then exit ---
function Remove-BlockedRules {
    Write-ColorOutput "Removing all blocked connection rules..." "Yellow"
    $totalRemoved = 0

    $blockedRules = Get-NetFirewallRule -DisplayName "BlockedConnection_*" -ErrorAction SilentlyContinue
    if ($blockedRules) {
        $count = ($blockedRules | Measure-Object).Count
        Write-ColorOutput "Found $count BlockedConnection_* rule(s)." "Cyan"
        foreach ($Rule in $blockedRules) {
            Remove-NetFirewallRule -DisplayName $Rule.DisplayName -ErrorAction SilentlyContinue
            Write-ColorOutput "  Removed: $($Rule.DisplayName)" "Green"
            $totalRemoved++
        }
    } else {
        Write-ColorOutput "No BlockedConnection_* rules found." "Gray"
    }

    $out = netsh advfirewall firewall show rule name=all 2>&1 | Out-String
    $ruleMatches = [regex]::Matches($out, 'Rule Name:\s*(NTM_Block_[^\s\r\n]+)')
    $ntmList = @($ruleMatches | ForEach-Object { $_.Groups[1].Value.Trim() } | Sort-Object -Unique)
    if ($ntmList.Count -gt 0) {
        Write-ColorOutput "Found $($ntmList.Count) NTM_Block_* rule(s)." "Cyan"
        foreach ($name in $ntmList) {
            $del = netsh advfirewall firewall delete rule name="$name" 2>&1 | Out-String
            if ($del -notmatch 'No rules match') {
                Write-ColorOutput "  Removed: $name" "Green"
                $totalRemoved++
            }
        }
    } else {
        Write-ColorOutput "No NTM_Block_* rules found." "Gray"
    }

    if ($totalRemoved -gt 0) {
        Write-ColorOutput "`nDone. Removed $totalRemoved rule(s) in total." "Green"
    } else {
        Write-ColorOutput "`nNo blocked connection rules to remove." "Gray"
    }
}

# --- Monitor mode (NTM) ---
$script:AllowedDomains = @()
$script:AllowedIPs = @()
$script:BlockedConnections = @{}
$script:MonitoringActive = $true
$script:CurrentBrowserConnections = @{}

# Browsers only: monitoring and blocking apply solely to these processes.
$BrowserProcesses = @(
    'chrome', 'firefox', 'msedge', 'iexplore', 'opera', 'brave', 'vivaldi', 'waterfox', 'palemoon',
    'seamonkey', 'librewolf', 'tor', 'dragon', 'iridium', 'chromium', 'maxthon', 'slimjet', 'citrio',
    'blisk', 'sidekick', 'epic', 'ghostery', 'falkon', 'kinza', 'orbitum', 'coowon', 'coc_coc_browser',
    'browser', 'qqbrowser', 'ucbrowser', '360chrome', '360se', 'sleipnir', 'k-meleon', 'basilisk',
    'floorp', 'pulse', 'naver', 'whale', 'coccoc', 'yandex', 'avastbrowser', 'asb', 'avgbrowser',
    'ccleanerbrowser', 'dcbrowser', 'edge', 'edgedev', 'edgebeta', 'edgecanary', 'operagx', 'operaneon',
    'bravesoftware', 'browsex', 'browsec', 'comet', 'elements', 'flashpeak', 'surf'
)

# Gaming (and all non-browser apps) are never monitored or blocked — explicitly unhindered.
$GamingProcesses = @(
    'steam', 'steamwebhelper', 'epicgameslauncher', 'origin', 'battle.net', 'eadesktop', 'ea app',
    'ubisoft game launcher', 'gog galaxy', 'rungame', 'gamebar', 'gameservices', 'overwolf'
)

# Never block these IPs (common DNS). Blocking them would break resolution for everyone.
$NeverBlockIPs = @('8.8.8.8', '8.8.4.4', '1.1.1.1', '1.0.0.1')

function Remove-BlockRulesForIP {
    param([string]$RemoteAddress)
    $safeName = $RemoteAddress -replace '\.', '_' -replace ':', '_'
    $prefix = "NTM_Block_${safeName}_"
    $out = netsh advfirewall firewall show rule name=all 2>&1 | Out-String
    $ruleMatches = [regex]::Matches($out, 'Rule Name:\s*(NTM_Block_[^\s\r\n]+)')
    foreach ($m in $ruleMatches) {
        $name = $m.Groups[1].Value.Trim()
        if ($name -like "${prefix}*") {
            $del = netsh advfirewall firewall delete rule name="$name" 2>&1 | Out-String
            if ($del -notmatch 'No rules match') {
                Write-ColorOutput "REMOVED BLOCK (user surfed): $RemoteAddress -> $name" "Green"
            }
        }
    }
    $toRemove = @($script:BlockedConnections.Keys | Where-Object { $_ -like "${RemoteAddress}|*" })
    foreach ($k in $toRemove) { $script:BlockedConnections.Remove($k) }
}

function Add-AllowedDomain {
    param([string]$Domain)
    $Domain = $Domain -replace '^https?://', '' -replace '/$', ''
    $Domain = ($Domain -split '/')[0]
    if ($Domain -match '^[\d\.]+$' -or $Domain -match '^[\da-f:]+$') {
        if ($script:AllowedIPs -notcontains $Domain) {
            $script:AllowedIPs += $Domain
            Write-ColorOutput "Added allowed IP: $Domain" "Green"
            Remove-BlockRulesForIP -RemoteAddress $Domain
        }
        return
    }
    if ($script:AllowedDomains -notcontains $Domain) {
        $script:AllowedDomains += $Domain
        Write-ColorOutput "Added allowed domain: $Domain" "Green"
        try {
            $IPs = [System.Net.Dns]::GetHostAddresses($Domain) | ForEach-Object { $_.IPAddressToString }
            foreach ($IP in $IPs) {
                if ($script:AllowedIPs -notcontains $IP) {
                    $script:AllowedIPs += $IP
                    Write-ColorOutput "  Resolved IP: $IP" "Gray"
                    Remove-BlockRulesForIP -RemoteAddress $IP
                }
            }
        } catch {
            Write-ColorOutput "  Warning: Could not resolve domain to IP" "Yellow"
        }
    }
}

function Test-BrowserConnection {
    param([string]$RemoteAddress)
    if ($RemoteAddress -match '^(127\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.)') { return $true }
    if ($script:AllowedIPs -contains $RemoteAddress) { return $true }
    return $false
}

function Watch-BrowserActivity {
    param([string]$RemoteAddress, [string]$ProcessName, [int]$RemotePort)
    if ($BrowserProcesses -contains $ProcessName.ToLower()) {
        $Now = Get-Date
        $RecentNavigationTime = $null
        foreach ($BrowserIP in $script:CurrentBrowserConnections.Keys) {
            $ConnectionTime = $script:CurrentBrowserConnections[$BrowserIP]
            $TimeDiff = ($Now - $ConnectionTime).TotalSeconds
            if ($TimeDiff -le 30) {
                if ($null -eq $RecentNavigationTime -or $ConnectionTime -gt $RecentNavigationTime) {
                    $RecentNavigationTime = $ConnectionTime
                }
            }
        }
        if ($null -ne $RecentNavigationTime) {
            if ($script:AllowedIPs -notcontains $RemoteAddress) {
                $script:AllowedIPs += $RemoteAddress
                Write-ColorOutput "DEPENDENCY: Allowing $RemoteAddress (linked to browser navigation)" "Gray"
                Remove-BlockRulesForIP -RemoteAddress $RemoteAddress
            }
            return $true
        }
        elseif ($RemotePort -eq 443 -or $RemotePort -eq 80) {
            if ($script:AllowedIPs -notcontains $RemoteAddress) {
                $script:AllowedIPs += $RemoteAddress
                Write-ColorOutput "BROWSER NAVIGATION: Allowing $RemoteAddress and its dependencies" "Cyan"
                Remove-BlockRulesForIP -RemoteAddress $RemoteAddress
            }
            $script:CurrentBrowserConnections[$RemoteAddress] = $Now
            return $true
        }
        else {
            if ($script:AllowedIPs -notcontains $RemoteAddress) {
                $script:AllowedIPs += $RemoteAddress
                Write-ColorOutput "BROWSER: Allowing $RemoteAddress" "DarkCyan"
                Remove-BlockRulesForIP -RemoteAddress $RemoteAddress
            }
            return $true
        }
    }
    $Now = Get-Date
    foreach ($BrowserIP in $script:CurrentBrowserConnections.Keys) {
        $ConnectionTime = $script:CurrentBrowserConnections[$BrowserIP]
        $TimeDiff = ($Now - $ConnectionTime).TotalSeconds
        if ($TimeDiff -le 30) {
            if ($script:AllowedIPs -notcontains $RemoteAddress) {
                $script:AllowedIPs += $RemoteAddress
                Write-ColorOutput "DEPENDENCY: Allowing $RemoteAddress (linked to browser navigation)" "Gray"
                Remove-BlockRulesForIP -RemoteAddress $RemoteAddress
            }
            return $true
        }
    }
    return $false
}

function New-BlockRule {
    param([string]$RemoteAddress, [int]$RemotePort, [string]$ProcessName, [string]$ProgramPath)
    if ($RemoteAddress -in $NeverBlockIPs) { return }
    $safeName = $RemoteAddress -replace '\.', '_' -replace ':', '_'
    $procSafe = ($ProcessName -replace '\.exe$','').Trim().ToLower()
    $ruleName = "NTM_Block_${safeName}_${procSafe}"
    $key = "${RemoteAddress}|${ProcessName}"
    if (-not $ProgramPath -or -not (Test-Path $ProgramPath)) {
        Write-ColorOutput "Skip block (no program path): $RemoteAddress ($ProcessName)" "Yellow"
        return
    }
    $progArg = "program=`"$ProgramPath`""
    $out = netsh advfirewall firewall add rule name="$ruleName" dir=out action=block remoteip="$RemoteAddress" $progArg 2>&1 | Out-String
    if ($out -match 'already exists') {
        $script:BlockedConnections[$key] = @{ Port = $RemotePort; Process = $ProcessName }
        return
    }
    if ($out -match 'Error|Failed|Unable') {
        Write-ColorOutput "Failed to block $RemoteAddress for $ProcessName : $($out.Trim())" "Red"
        return
    }
    $script:BlockedConnections[$key] = @{ Port = $RemotePort; Process = $ProcessName }
    Write-ColorOutput "BLOCKED (browser only): $RemoteAddress`:$RemotePort ($ProcessName)" "Red"
}

function Start-ConnectionMonitoring {
    Write-ColorOutput "" "Cyan"
    Write-ColorOutput "=== GFocus / Network Traffic Monitor ===" "Cyan"
    Write-ColorOutput "Browsers only: monitoring and blocking apply to browsers only." "Cyan"
    Write-ColorOutput "Gaming and all other apps are unhindered (never monitored or blocked)." "Green"
    Write-ColorOutput "Address bar inferred from browser 80/443 nav + 30s dependencies (no extension)." "Cyan"
    Write-ColorOutput "Block/allow/remove block as user surfs. Press Ctrl+C to stop." "Yellow"
    Write-ColorOutput "To clear block rules later: GFocus.ps1 -RemoveRules" "Gray"
    Write-ColorOutput "" "Cyan"
    $SeenConnections = @{}
    while ($script:MonitoringActive) {
        $Connections = Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue |
            Where-Object { $_.RemoteAddress -ne '0.0.0.0' -and $_.RemoteAddress -ne '::' }
        foreach ($Conn in $Connections) {
            $Key = "$($Conn.RemoteAddress):$($Conn.RemotePort):$($Conn.OwningProcess)"
            if ($SeenConnections.ContainsKey($Key)) { continue }
            $SeenConnections[$Key] = $true
            try {
                $Process = Get-Process -Id $Conn.OwningProcess -ErrorAction Stop
                $ProcessName = $Process.ProcessName
                $ProcessPath = $Process.Path
            } catch { $Process = $null; $ProcessName = "Unknown"; $ProcessPath = $null }
            $procName = ($ProcessName -replace '\.exe$','').Trim().ToLower()
            if ($procName -notin $BrowserProcesses) {
                continue
            }
            $IsBrowserOrDependency = Watch-BrowserActivity -RemoteAddress $Conn.RemoteAddress -ProcessName $ProcessName -RemotePort $Conn.RemotePort
            if ($IsBrowserOrDependency) { continue }
            if (-not (Test-BrowserConnection -RemoteAddress $Conn.RemoteAddress)) {
                $blockKey = "$($Conn.RemoteAddress)|$ProcessName"
                if (-not $script:BlockedConnections.ContainsKey($blockKey)) {
                    New-BlockRule -RemoteAddress $Conn.RemoteAddress -RemotePort $Conn.RemotePort -ProcessName $ProcessName -ProgramPath $ProcessPath
                }
            } else {
                Write-ColorOutput "ALLOWED: $($Conn.RemoteAddress):$($Conn.RemotePort) (Process: $ProcessName)" "Green"
            }
        }
        $Now = Get-Date
        $ToRemove = @()
        foreach ($IP in $script:CurrentBrowserConnections.Keys) {
            if (($Now - $script:CurrentBrowserConnections[$IP]).TotalSeconds -gt 60) { $ToRemove += $IP }
        }
        foreach ($IP in $ToRemove) { $script:CurrentBrowserConnections.Remove($IP) }
        Start-Sleep -Seconds 2
    }
}

function Stop-Monitoring {
    Write-ColorOutput "" "Cyan"
    Write-ColorOutput "=== Stopping GFocus ===" "Cyan"
    Write-ColorOutput "Blocked connections:" "Yellow"
    if ($script:BlockedConnections.Count -eq 0) {
        Write-ColorOutput "  None." "Green"
    } else {
        foreach ($k in $script:BlockedConnections.Keys) {
            $Info = $script:BlockedConnections[$k]
            $ip = ($k -split '\|', 2)[0]
            Write-ColorOutput "  - ${ip}:$($Info.Port) - $($Info.Process) (browser-only rule)" "Red"
        }
    }
    Write-ColorOutput "`nTo remove block rules: GFocus.ps1 -RemoveRules" "Gray"
}

Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action { Stop-Monitoring }

# One tick for scheduler: process new browser connections (allow/block). Uses script-level seen cache.
if (-not $script:GFocusSeenConnections) { $script:GFocusSeenConnections = @{} }
function Invoke-GFocusTick {
    $Connections = Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue |
        Where-Object { $_.RemoteAddress -ne '0.0.0.0' -and $_.RemoteAddress -ne '::' }
    foreach ($Conn in $Connections) {
        $Key = "$($Conn.RemoteAddress):$($Conn.RemotePort):$($Conn.OwningProcess)"
        if ($script:GFocusSeenConnections.ContainsKey($Key)) { continue }
        $script:GFocusSeenConnections[$Key] = $true
        try {
            $Process = Get-Process -Id $Conn.OwningProcess -ErrorAction Stop
            $ProcessName = $Process.ProcessName
            $ProcessPath = $Process.Path
        } catch { $Process = $null; $ProcessName = "Unknown"; $ProcessPath = $null }
        $procName = ($ProcessName -replace '\.exe$','').Trim().ToLower()
        if ($procName -notin $BrowserProcesses) { continue }
        $IsBrowserOrDependency = Watch-BrowserActivity -RemoteAddress $Conn.RemoteAddress -ProcessName $ProcessName -RemotePort $Conn.RemotePort
        if ($IsBrowserOrDependency) { continue }
        if (-not (Test-BrowserConnection -RemoteAddress $Conn.RemoteAddress)) {
            $blockKey = "$($Conn.RemoteAddress)|$ProcessName"
            if (-not $script:BlockedConnections.ContainsKey($blockKey)) {
                New-BlockRule -RemoteAddress $Conn.RemoteAddress -RemotePort $Conn.RemotePort -ProcessName $ProcessName -ProgramPath $ProcessPath
            }
        }
    }
    $Now = Get-Date
    $ToRemove = @($script:CurrentBrowserConnections.Keys | Where-Object { ($Now - $script:CurrentBrowserConnections[$_]).TotalSeconds -gt 60 })
    foreach ($IP in $ToRemove) { $script:CurrentBrowserConnections.Remove($IP) }
}

# --- ResponseEngine ---
# Response Engine Module
# Centralized response system for all detection modules - Optimized for low resource usage

$ModuleName = "ResponseEngine"
$script:LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$ResponseQueue = @()
$ResponseActions = @{
    "Critical" = @("Quarantine", "KillProcess", "BlockNetwork", "Log")
    "High" = @("Quarantine", "Log", "Alert")
    "Medium" = @("Log", "Alert")
    "Low" = @("Log")
}
$ProcessedThreats = @{}

function Invoke-ResponseAction {
    param(
        [hashtable]$Detection,
        [string]$Severity
    )
    
    $actions = $ResponseActions[$Severity]
    if (-not $actions) {
        $actions = @("Log")
    }
    
    $results = @()
    
    foreach ($action in $actions) {
        try {
            switch ($action) {
                "Quarantine" {
                    if ($Detection.FilePath -or $Detection.DllPath) {
                        $filePath = $Detection.FilePath -or $Detection.DllPath
                        if (Test-Path $filePath) {
                            # Import quarantine function if available
                            $quarantineModule = Get-Module -Name "QuarantineManagement" -ErrorAction SilentlyContinue
                            if (-not $quarantineModule) {
                                # Load quarantine module
                                $quarantinePath = Join-Path $PSScriptRoot "QuarantineManagement.ps1"
                                if (Test-Path $quarantinePath) {
                                    . $quarantinePath
                                }
                            }
                            
                            # Call quarantine function
                            if (Get-Command -Name "Invoke-QuarantineFile" -ErrorAction SilentlyContinue) {
                                Invoke-QuarantineFile -FilePath $filePath -Reason "Threat Detected: $($Detection.Type)" -Source $Detection.ModuleName
                                $results += "Quarantined: $filePath"
                            }
                        }
                    }
                }
                
                "KillProcess" {
                    if ($Detection.ProcessId) {
                        try {
                            $proc = Get-Process -Id $Detection.ProcessId -ErrorAction Stop
                            Stop-Process -Id $Detection.ProcessId -Force -ErrorAction Stop
                            $results += "Killed process: $($proc.ProcessName) (PID: $Detection.ProcessId)"
                        } catch {
                            $results += "Failed to kill process PID: $Detection.ProcessId"
                        }
                    }
                }
                
                "BlockNetwork" {
                    if ($Detection.RemoteAddress -or $Detection.RemotePort) {
                        try {
                            # Block network connection using firewall
                            $remoteIP = $Detection.RemoteAddress
                            $remotePort = $Detection.RemotePort
                            
                            if ($remoteIP) {
                                $ruleName = "Block_Threat_$($remoteIP.Replace('.', '_'))"
                                $existingRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
                                
                                if (-not $existingRule) {
                                    New-NetFirewallRule -DisplayName $ruleName -Direction Outbound -RemoteAddress $remoteIP -Action Block -ErrorAction SilentlyContinue | Out-Null
                                    $results += "Blocked network to: $remoteIP"
                                }
                            }
                        } catch {
                            $results += "Failed to block network: $_"
                        }
                    }
                }
                
                "Alert" {
                    # Send alert (can be extended with email, SIEM, etc.)
                    $alertMsg = "ALERT: $($Detection.Type) - $($Detection.ProcessName -or $Detection.FilePath) - Severity: $Severity"
                    Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2100 `
                        -Message $alertMsg
                    $results += "Alert sent: $alertMsg"
                }
                
                "Log" {
                    # Already logged, but add to response log
                    $logPath = "$env:ProgramData\Antivirus\Logs\ResponseEngine_$(Get-Date -Format 'yyyy-MM-dd').log"
                    $logEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$Severity|$($Detection.Type)|$($Detection.ProcessName -or $Detection.FilePath)|$($Detection.ModuleName)"
                    Add-Content -Path $logPath -Value $logEntry -ErrorAction SilentlyContinue
                    $results += "Logged"
                }
            }
        } catch {
            $results += "Error in action $action`: $_"
        }
    }
    
    return $results
}

function Invoke-ResponseEngine {
    $responses = @()
    
    try {
        # Check all module detection logs for new threats
        $logPath = "$env:ProgramData\Antivirus\Logs"
        if (Test-Path $logPath) {
            $today = Get-Date -Format 'yyyy-MM-dd'
            $logFiles = Get-ChildItem -Path $logPath -Filter "*_$today.log" -File -ErrorAction SilentlyContinue |
                Where-Object { $_.Name -ne "ResponseEngine_$today.log" -and $_.Name -ne "Antivirus_$today.log" }
            
            foreach ($logFile in $logFiles) {
                try {
                    $moduleName = $logFile.BaseName -replace "_$today", ""
                    $logEntries = Get-Content -Path $logFile.FullName -ErrorAction SilentlyContinue | Select-Object -Last 50
                    
                    foreach ($entry in $logEntries) {
                        # Parse log entry (format: timestamp|type|risk|details)
                        if ($entry -match '\|') {
                            $parts = $entry -split '\|'
                            if ($parts.Length -ge 3) {
                                $timestamp = $parts[0]
                                $detectionType = $parts[1]
                                $risk = $parts[2]
                                $details = $parts[3..($parts.Length-1)] -join '|'
                                
                                # Create detection hash
                                $detectionHash = ($moduleName + $timestamp + $detectionType + $details).GetHashCode()
                                
                                # Skip if already processed
                                if ($ProcessedThreats.ContainsKey($detectionHash)) {
                                    continue
                                }
                                
                                # Determine severity from risk level
                                $severity = switch ($risk) {
                                    "Critical" { "Critical" }
                                    "High" { "High" }
                                    "Medium" { "Medium" }
                                    default { "Low" }
                                }
                                
                                # Create detection object
                                $detection = @{
                                    ModuleName = $moduleName
                                    Timestamp = $timestamp
                                    Type = $detectionType
                                    Risk = $risk
                                    Details = $details
                                    Severity = $severity
                                }
                                
                                # Extract ProcessId, FilePath, etc. from details
                                if ($details -match 'PID:(\d+)') {
                                    $detection.ProcessId = [int]$matches[1]
                                }
                                if ($details -match '(.+\.exe|.+\.dll)') {
                                    $detection.FilePath = $matches[1]
                                }
                                if ($details -match '(\d+\.\d+\.\d+\.\d+)') {
                                    $detection.RemoteAddress = $matches[1]
                                }
                                
                                # Execute response actions
                                $actionResults = Invoke-ResponseAction -Detection $detection -Severity $severity
                                
                                # Mark as processed
                                $ProcessedThreats[$detectionHash] = Get-Date
                                
                                $responses += @{
                                    Detection = $detection
                                    Actions = $actionResults
                                    Timestamp = Get-Date
                                }
                                
                                Write-Output "DETECTION:$ModuleName`:Processed $detectionType from $moduleName - Actions: $($actionResults -join ', ')"
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        }
        
        # Cleanup old processed threats (older than 24 hours)
        $oldKeys = $ProcessedThreats.Keys | Where-Object {
            ((Get-Date) - $ProcessedThreats[$_]).TotalHours -gt 24
        }
        foreach ($key in $oldKeys) {
            $ProcessedThreats.Remove($key)
        }
        
        # Also check Event Log for detection events (2001-2100)
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='Application'; Id=2001..2099} -ErrorAction SilentlyContinue -MaxEvents 100 |
                Where-Object {
                    $_.Source -eq "AntivirusEDR" -and
                    (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromMinutes(5)
                }
            
            foreach ($event in $events) {
                $eventHash = ($event.Id.ToString() + $event.TimeCreated.ToString()).GetHashCode()
                
                if (-not $ProcessedThreats.ContainsKey($eventHash)) {
                    # Parse event message for detection info
                    $message = $event.Message
                    $severity = if ($event.EntryType -eq "Error") { "Critical" } 
                               elseif ($event.EntryType -eq "Warning") { "High" }
                               else { "Medium" }
                    
                    $detection = @{
                        ModuleName = "EventLog"
                        Timestamp = $event.TimeCreated.ToString()
                        Type = $message
                        Severity = $severity
                        EventId = $event.Id
                    }
                    
                    # Extract info from message
                    if ($message -match 'PID:\s*(\d+)') {
                        $detection.ProcessId = [int]$matches[1]
                    }
                    if ($message -match '(?:THREAT|DETECTED|FOUND):\s*(.+?)(?:\s*\||\s*-\s*|$)') {
                        $detection.Details = $matches[1]
                    }
                    
                    # Execute response for critical/high severity
                    if ($severity -in @("Critical", "High")) {
                        $actionResults = Invoke-ResponseAction -Detection $detection -Severity $severity
                        $responses += @{
                            Detection = $detection
                            Actions = $actionResults
                            Timestamp = Get-Date
                        }
                    }
                    
                    $ProcessedThreats[$eventHash] = Get-Date
                }
            }
        } catch { }
        
        if ($responses.Count -gt 0) {
            Write-Output "STATS:$ModuleName`:Processed $($responses.Count) threats"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $responses.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    while ($true) {
        try {
            # CPU throttling - skip scan if CPU load is too high
            if (Test-CPULoadThreshold) {
                $cpuLoad = Get-CPULoad
                Write-Output "STATS:$ModuleName`:CPU load too high ($cpuLoad%), skipping scan"
                Start-Sleep -Seconds ($loopSleep * 2)  # Sleep longer when CPU is high
                continue
            }
            
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ResponseEngine
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 120  # Longer sleep on error
        }
    }
}

# --- BeaconDetection ---
# Beacon Detection Module
# Detects C2 beaconing and command & control communication - Optimized for low resource usage

$ModuleName = "BeaconDetection"
$script:LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$ConnectionBaseline = @{}

function Initialize-BeaconBaseline {
    try {
        $maxConnections = Get-ScanLimit -LimitName "MaxConnections"
        $connections = Get-NetTCPConnection -ErrorAction SilentlyContinue | 
            Where-Object { $_.State -eq "Established" } | Select-Object -First $maxConnections
        
        foreach ($conn in $connections) {
            $key = "$($conn.RemoteAddress):$($conn.RemotePort)"
            if (-not $ConnectionBaseline.ContainsKey($key)) {
                $ConnectionBaseline[$key] = @{
                    Count = 0
                    FirstSeen = Get-Date
                    LastSeen = Get-Date
                }
            }
            $ConnectionBaseline[$key].Count++
            $ConnectionBaseline[$key].LastSeen = Get-Date
        }
    } catch { }
}

function Invoke-BeaconDetection {
    $detections = @()
    
    try {
        # Monitor for periodic connections (beacon indicator)
        $maxConnections = Get-ScanLimit -LimitName "MaxConnections"
        $connections = Get-NetTCPConnection -ErrorAction SilentlyContinue | 
            Where-Object { $_.State -eq "Established" } | Select-Object -First $maxConnections
        
        # Group connections by process and remote address
        $connGroups = $connections | Group-Object -Property @{Expression={$_.OwningProcess}}, @{Expression={$_.RemoteAddress}}
        
        foreach ($group in $connGroups) {
            $procId = $group.Name.Split(',')[0].Trim()
            $remoteIP = $group.Name.Split(',')[1].Trim()
            
            try {
                $proc = Get-Process -Id $procId -ErrorAction SilentlyContinue
                if (-not $proc) { continue }
                
                # Check connection frequency (beacon pattern)
                $connTimes = $group.Group | ForEach-Object { $_.CreationTime } | Sort-Object
                
                if ($connTimes.Count -gt 3) {
                    # Calculate intervals between connections
                    $intervals = @()
                    for ($i = 1; $i -lt $connTimes.Count; $i++) {
                        $interval = ($connTimes[$i] - $connTimes[$i-1]).TotalSeconds
                        $intervals += $interval
                    }
                    
                    # Check for regular intervals (beacon indicator)
                    if ($intervals.Count -gt 2) {
                        $avgInterval = ($intervals | Measure-Object -Average).Average
                        $variance = ($intervals | ForEach-Object { [Math]::Pow($_ - $avgInterval, 2) } | Measure-Object -Average).Average
                        $stdDev = [Math]::Sqrt($variance)
                        
                        # Low variance = regular intervals = beacon
                        if ($stdDev -lt $avgInterval * 0.2 -and $avgInterval -gt 10 -and $avgInterval -lt 3600) {
                            $detections += @{
                                ProcessId = $procId
                                ProcessName = $proc.ProcessName
                                RemoteAddress = $remoteIP
                                ConnectionCount = $connTimes.Count
                                AverageInterval = [Math]::Round($avgInterval, 2)
                                Type = "Beacon Pattern Detected"
                                Risk = "High"
                            }
                        }
                    }
                }
            } catch {
                continue
            }
        }
        
        # Check for connections to suspicious TLDs
        foreach ($conn in $connections) {
            if ($conn.RemoteAddress -notmatch '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)') {
                try {
                    $dns = [System.Net.Dns]::GetHostEntry($conn.RemoteAddress).HostName
                    
                    $suspiciousTLDs = @(".onion", ".bit", ".i2p", ".tk", ".ml", ".ga", ".cf")
                    foreach ($tld in $suspiciousTLDs) {
                        if ($dns -like "*$tld") {
                            $detections += @{
                                ProcessId = $conn.OwningProcess
                                RemoteAddress = $conn.RemoteAddress
                                RemoteHost = $dns
                                Type = "Connection to Suspicious TLD"
                                Risk = "Medium"
                            }
                            break
                        }
                    }
                } catch { }
            }
        }
        
        # Check for HTTP/HTTPS connections with small data transfer (beacon)
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $procConns = $connections | Where-Object { $_.OwningProcess -eq $proc.Id }
                    $httpConns = $procConns | Where-Object { $_.RemotePort -in @(80, 443, 8080, 8443) }
                    
                    if ($httpConns.Count -gt 0) {
                        # Check network stats
                        $netStats = Get-Counter "\Process($($proc.ProcessName))\IO Data Bytes/sec" -ErrorAction SilentlyContinue
                        if ($netStats -and $netStats.CounterSamples[0].CookedValue -lt 1000 -and $netStats.CounterSamples[0].CookedValue -gt 0) {
                            # Small but consistent data transfer = beacon
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                DataRate = $netStats.CounterSamples[0].CookedValue
                                ConnectionCount = $httpConns.Count
                                Type = "Low Data Transfer Beacon Pattern"
                                Risk = "Medium"
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for processes with connections to many different IPs (C2 rotation)
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                $procConns = $connections | Where-Object { $_.OwningProcess -eq $proc.Id }
                $uniqueIPs = ($procConns | Select-Object -Unique RemoteAddress).RemoteAddress.Count
                
                if ($uniqueIPs -gt 10) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        UniqueIPs = $uniqueIPs
                        ConnectionCount = $procConns.Count
                        Type = "Multiple C2 Connections (IP Rotation)"
                        Risk = "High"
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2037 `
                    -Message "BEACON DETECTED: $($detection.Type) - $($detection.ProcessName) (PID: $($detection.ProcessId)) - $($detection.RemoteAddress -or $detection.RemoteHost)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\BeaconDetection_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|PID:$($_.ProcessId)|$($_.ProcessName)|$($_.RemoteAddress -or $_.RemoteHost)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) beacon indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    Initialize-BeaconBaseline
    Start-Sleep -Seconds (Get-Random -Minimum 30 -Maximum 90)  # Longer initial delay
    
    while ($true) {
        try {
            # CPU throttling - skip scan if CPU load is too high
            if (Test-CPULoadThreshold) {
                $cpuLoad = Get-CPULoad
                Write-Output "STATS:$ModuleName`:CPU load too high ($cpuLoad%), skipping scan"
                Start-Sleep -Seconds ($loopSleep * 2)  # Sleep longer when CPU is high
                continue
            }
            
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-BeaconDetection
                $script:LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 120  # Longer sleep on error
        }
    }
}

# --- NetworkTrafficMonitoring ---
# Optimized Network Traffic Monitoring Module
# Reduced polling and caching of connection state

$ModuleName = "NetworkTrafficMonitoring"
$LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$script:ConnectionCache = @{}
$script:KnownGoodConnections = @{}

function Invoke-NetworkTrafficMonitoringOptimized {
    $detections = @()
    $maxConnections = Get-ScanLimit -LimitName "MaxConnections"
    $batchSettings = Get-BatchSettings
    
    try {
        $tcpConnections = Get-NetTCPConnection -ErrorAction SilentlyContinue |
            Where-Object { $_.State -eq "Established" } |
            Select-Object -First $maxConnections
        
        $batchCount = 0
        foreach ($conn in $tcpConnections) {
            $key = "$($conn.LocalAddress):$($conn.LocalPort)-$($conn.RemoteAddress):$($conn.RemotePort)"
            
            if ($script:KnownGoodConnections.ContainsKey($key)) {
                continue
            }
            
            $batchCount++
            if ($batchCount % $batchSettings.BatchSize -eq 0 -and $batchSettings.BatchDelayMs -gt 0) {
                Start-Sleep -Milliseconds $batchSettings.BatchDelayMs
            }
            
            # Check for suspicious patterns (simplified checks)
            $isPrivate = $conn.RemoteAddress -match '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)'
            
            if (-not $isPrivate) {
                # Connection to public IP on ephemeral port
                if ($conn.RemotePort -gt 49152) {
                    $detections += @{
                        RemoteAddress = $conn.RemoteAddress
                        RemotePort = $conn.RemotePort
                        Type = "Connection to Public Ephemeral Port"
                        Risk = "Low"
                    }
                }
            } else {
                $script:KnownGoodConnections[$key] = $true
            }
        }
        
        if ($detections.Count -gt 0) {
            $logPath = "$env:ProgramData\Antivirus\Logs\NetworkTraffic_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.RemoteAddress):$($_.RemotePort)" |
                    Add-Content -Path $logPath
            }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) traffic anomalies"
        }
        
        Write-Output "STATS:$ModuleName`:Active connections=$($tcpConnections.Count)"
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    Start-Sleep -Seconds (Get-Random -Minimum 30 -Maximum 90)  # Longer initial delay
    
    while ($true) {
        try {
            # CPU throttling - skip scan if CPU load is too high
            if (Test-CPULoadThreshold) {
                $cpuLoad = Get-CPULoad
                Write-Output "STATS:$ModuleName`:CPU load too high ($cpuLoad%), skipping scan"
                Start-Sleep -Seconds ($loopSleep * 2)  # Sleep longer when CPU is high
                continue
            }
            
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-NetworkTrafficMonitoringOptimized
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 120  # Longer sleep on error
        }
    }
}

# --- ProcessAnomalyDetection ---
# Optimized Process Anomaly Detection Module
# Reduced resource usage with baseline caching


$ModuleName = "ProcessAnomalyDetection"
$LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$script:BaselineProcesses = @{}
$script:KnownGoodProcesses = @{}

function Initialize-BaselineOptimized {
    if ($script:BaselineProcesses.Count -gt 0) {
        return
    }
    
    try {
        $maxProcs = Get-ScanLimit -LimitName "MaxProcesses"
        
        $processes = Get-Process -ErrorAction SilentlyContinue | Select-Object -First $maxProcs
        
        foreach ($proc in $processes) {
            $key = $proc.ProcessName
            if (-not $script:BaselineProcesses.ContainsKey($key)) {
                $script:BaselineProcesses[$key] = @{
                    Count = 0
                    FirstSeen = Get-Date
                }
            }
            $script:BaselineProcesses[$key].Count++
        }
    } catch { }
}

function Test-ProcessAnomalyOptimized {
    param($Process)
    
    $anomalies = @()
    
    if ($script:KnownGoodProcesses.ContainsKey($Process.ProcessName)) {
        return $anomalies
    }
    
    if ($Process.Path) {
        $systemPaths = @("$env:SystemRoot\System32", "$env:SystemRoot\SysWOW64")
        foreach ($sysPath in $systemPaths) {
            if ($Process.Path -like "$sysPath\*") {
                try {
                    $sig = Get-CachedSignature -FilePath $Process.Path
                    if ($sig -and $sig.Status -ne "Valid") {
                        $anomalies += "Unsigned executable in system directory"
                    } elseif ($sig -and $sig.Status -eq "Valid") {
                        $script:KnownGoodProcesses[$Process.ProcessName] = $true
                    }
                } catch { }
            }
        }
    }
    
    return $anomalies
}

function Invoke-ProcessAnomalyScanOptimized {
    $detections = @()
    $batchSettings = Get-BatchSettings
    $maxProcs = Get-ScanLimit -LimitName "MaxProcesses"
    
    try {
        Initialize-BaselineOptimized
        
        $processes = Get-Process -ErrorAction SilentlyContinue | 
            Where-Object { $_.Path } |
            Select-Object -First $maxProcs
        
        $batchCount = 0
        foreach ($proc in $processes) {
            if ($script:KnownGoodProcesses.ContainsKey($proc.ProcessName)) {
                continue
            }
            
            $batchCount++
            if ($batchCount % $batchSettings.BatchSize -eq 0 -and $batchSettings.BatchDelayMs -gt 0) {
                Start-Sleep -Milliseconds $batchSettings.BatchDelayMs
            }
            
            $anomalies = Test-ProcessAnomalyOptimized -Process $proc
            if ($anomalies.Count -gt 0) {
                $detections += @{
                    ProcessId = $proc.Id
                    ProcessName = $proc.ProcessName
                    Path = $proc.Path
                    Anomalies = $anomalies
                    Risk = "High"
                }
            }
        }
        
        if ($detections.Count -gt 0) {
            $logPath = "$env:ProgramData\Antivirus\Logs\ProcessAnomaly_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|PID:$($_.ProcessId)|$($_.ProcessName)|$($_.Anomalies -join ';')" |
                    Add-Content -Path $logPath
            }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) process anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    Clear-ExpiredCache
    return $detections.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    Start-Sleep -Seconds (Get-Random -Minimum 30 -Maximum 90)  # Longer initial delay
    
    while ($true) {
        try {
            # CPU throttling - skip scan if CPU load is too high
            if (Test-CPULoadThreshold) {
                $cpuLoad = Get-CPULoad
                Write-Output "STATS:$ModuleName`:CPU load too high ($cpuLoad%), skipping scan"
                Start-Sleep -Seconds ($loopSleep * 2)  # Sleep longer when CPU is high
                continue
            }
            
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ProcessAnomalyScanOptimized
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 120  # Longer sleep on error
        }
    }
}

# --- EventLogMonitoring ---
# Optimized Event Log Monitoring Module
# Reduced Event Log query overhead

$ModuleName = "EventLogMonitoring"
$LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$script:LastEventTime = @{}

function Invoke-EventLogMonitoringOptimized {
    $detections = @()
    $maxEvents = Get-ScanLimit -LimitName "MaxEvents"
    
    try {
        $lastCheck = if ($script:LastEventTime.ContainsKey('Security')) {
            $script:LastEventTime['Security']
        } else {
            (Get-Date).AddMinutes(-$TickInterval / 60)
        }
        
        try {
            $securityEvents = Get-WinEvent -FilterHashtable @{
                LogName = 'Security'
                StartTime = $lastCheck
            } -ErrorAction SilentlyContinue -MaxEvents $maxEvents
            
            $script:LastEventTime['Security'] = Get-Date
            
            # Check for failed logons
            $failedLogons = $securityEvents | Where-Object { $_.Id -eq 4625 }
            if ($failedLogons.Count -gt 10) {
                $detections += @{
                    EventCount = $failedLogons.Count
                    Type = "Excessive Failed Logon Attempts"
                    Risk = "High"
                }
            }
            
            # Check for privilege escalation
            $privilegeEvents = $securityEvents | Where-Object { $_.Id -in @(4672, 4673, 4674) }
            if ($privilegeEvents.Count -gt 0) {
                $detections += @{
                    EventCount = $privilegeEvents.Count
                    Type = "Privilege Escalation Events"
                    Risk = "High"
                }
            }
            
            # Check for log clearing
            $logClearing = $securityEvents | Where-Object { $_.Id -eq 1102 }
            if ($logClearing.Count -gt 0) {
                $detections += @{
                    EventCount = $logClearing.Count
                    Type = "Event Log Cleared"
                    Risk = "Critical"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            $logPath = "$env:ProgramData\Antivirus\Logs\EventLogMonitoring_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|Count:$($_.EventCount)" |
                    Add-Content -Path $logPath
            }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) event log anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    Start-Sleep -Seconds (Get-Random -Minimum 5 -Maximum 20)
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-EventLogMonitoringOptimized
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 60
        }
    }
}

# --- FileEntropyDetection ---
# Optimized File Entropy Detection Module
# Reduced file I/O with smart sampling


$ModuleName = "FileEntropyDetection"
$LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$HighEntropyThreshold = 7.2
$script:ScannedFiles = @{}

function Measure-FileEntropyOptimized {
    param([string]$FilePath)
    
    try {
        if (-not (Test-Path $FilePath)) { return $null }
        
        $fileInfo = Get-Item $FilePath -ErrorAction Stop
        
        $sampleSize = Get-ScanLimit -LimitName "SampleSizeBytes"
        $sampleSize = [Math]::Min($sampleSize, $fileInfo.Length)
        
        if ($sampleSize -eq 0) { return $null }
        
        $stream = [System.IO.File]::OpenRead($FilePath)
        $bytes = New-Object byte[] $sampleSize
        $stream.Read($bytes, 0, $sampleSize) | Out-Null
        $stream.Close()
        
        # Calculate byte frequency
        $freq = @{}
        foreach ($byte in $bytes) {
            if ($freq.ContainsKey($byte)) {
                $freq[$byte]++
            } else {
                $freq[$byte] = 1
            }
        }
        
        # Calculate Shannon entropy
        $entropy = 0
        $total = $bytes.Count
        
        foreach ($count in $freq.Values) {
            $p = $count / $total
            if ($p -gt 0) {
                $entropy -= $p * [Math]::Log($p, 2)
            }
        }
        
        return @{
            Entropy = $entropy
            FileSize = $fileInfo.Length
            SampleSize = $sampleSize
        }
    } catch {
        return $null
    }
}

function Invoke-FileEntropyDetectionOptimized {
    $detections = @()
    $maxFiles = Get-ScanLimit -LimitName "MaxFiles"
    $batchSettings = Get-BatchSettings
    
    try {
        $cutoff = (Get-Date).AddHours(-2)
        $scanPaths = @("$env:APPDATA", "$env:LOCALAPPDATA\Temp", "$env:USERPROFILE\Downloads")
        
        $scannedCount = 0
        foreach ($scanPath in $scanPaths) {
            if (-not (Test-Path $scanPath)) { continue }
            if ($scannedCount -ge $maxFiles) { break }
            
            try {
                $files = Get-ChildItem -Path $scanPath -Include *.exe,*.dll,*.scr -Recurse -File -ErrorAction SilentlyContinue |
                    Where-Object { $_.LastWriteTime -gt $cutoff } |
                    Select-Object -First ($maxFiles - $scannedCount)
                
                $batchCount = 0
                foreach ($file in $files) {
                    $scannedCount++
                    
                    if ($script:ScannedFiles.ContainsKey($file.FullName)) {
                        $cached = $script:ScannedFiles[$file.FullName]
                        if ($cached.LastWrite -eq $file.LastWriteTime) {
                            continue
                        }
                    }
                    
                    $batchCount++
                    if ($batchCount % $batchSettings.BatchSize -eq 0 -and $batchSettings.BatchDelayMs -gt 0) {
                        Start-Sleep -Milliseconds $batchSettings.BatchDelayMs
                    }
                    
                    $entropyResult = Measure-FileEntropyOptimized -FilePath $file.FullName
                    
                    # Mark as scanned
                    $script:ScannedFiles[$file.FullName] = @{
                        LastWrite = $file.LastWriteTime
                        Entropy = if ($entropyResult) { $entropyResult.Entropy } else { 0 }
                    }
                    
                    if ($entropyResult -and $entropyResult.Entropy -ge $HighEntropyThreshold) {
                        $detections += @{
                            FilePath = $file.FullName
                            FileName = $file.Name
                            Entropy = [Math]::Round($entropyResult.Entropy, 2)
                            Type = "High Entropy File"
                            Risk = "Medium"
                        }
                    }
                }
            } catch {
                continue
            }
        }
        
        if ($detections.Count -gt 0) {
            $logPath = "$env:ProgramData\Antivirus\Logs\FileEntropy_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.FilePath)|Entropy:$($_.Entropy)" |
                    Add-Content -Path $logPath
            }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) high entropy files"
        }
        
        Write-Output "STATS:$ModuleName`:Scanned=$scannedCount"
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    $toRemove = $script:ScannedFiles.Keys | Where-Object { -not (Test-Path $_) }
    foreach ($key in $toRemove) {
        $script:ScannedFiles.Remove($key)
    }
    
    Clear-ExpiredCache
    return $detections.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    Start-Sleep -Seconds (Get-Random -Minimum 30 -Maximum 90)
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-FileEntropyDetectionOptimized
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 120
        }
    }
}

# --- YaraDetection ---
# YARA Detection
# Runs yara.exe against suspicious files (if present)

$ModuleName = "YaraDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 120 }
$YaraPaths = @("$env:ProgramFiles\Yara\yara64.exe", "$env:ProgramFiles (x86)\Yara\yara.exe", "yara.exe", "yara64.exe")
$RulesPaths = @("$env:ProgramData\Antivirus\Yara", "$env:ProgramData\Antivirus\Rules", "$PSScriptRoot\YaraRules")
$ScanPaths = @("$env:Temp", "$env:TEMP", "$env:SystemRoot\Temp")

function Get-YaraExe {
    foreach ($p in $YaraPaths) {
        if (Test-Path $p) { return $p }
    }
    return $null
}

function Get-RulesPath {
    foreach ($p in $RulesPaths) {
        if (Test-Path $p) {
            $rules = Get-ChildItem -Path $p -Filter *.yar -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
            if ($rules) { return $rules.Directory.FullName }
        }
    }
    return $null
}

function Invoke-YaraScan {
    $yara = Get-YaraExe
    if (-not $yara) {
        return 0
    }
    
    $rulesDir = Get-RulesPath
    if (-not $rulesDir) {
        return 0
    }
    
    $detections = @()
    foreach ($base in $ScanPaths) {
        if (-not (Test-Path $base)) { continue }
        try {
            $files = Get-ChildItem -Path $base -Include *.exe, *.dll, *.ps1 -Recurse -File -ErrorAction SilentlyContinue | Select-Object -First 100
            foreach ($f in $files) {
                try {
                    $out = & $yara -r "$rulesDir\*.yar" $f.FullName 2>&1
                    if ($out -and $out -match '\S') {
                        $detections += @{
                            File = $f.FullName
                            Match = ($out | Select-Object -First 5) -join "; "
                        }
                    }
                } catch { }
            }
        } catch { }
    }
    
    if ($detections.Count -gt 0) {
        foreach ($d in $detections) {
            Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2096 -Message "YARA: $($d.File) - $($d.Match)" -ErrorAction SilentlyContinue
        }
        $logPath = "$env:ProgramData\Antivirus\Logs\yara_detection_$(Get-Date -Format 'yyyy-MM-dd').log"
        $detections | ForEach-Object { "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.File)|$($_.Match)" | Add-Content -Path $logPath }
        Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) YARA matches"
    }
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $script:LastTick = $now
                Invoke-YaraScan | Out-Null
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- WMIPersistenceDetection ---
# WMI Persistence Detection Module
# Detects WMI-based persistence mechanisms

$ModuleName = "WMIPersistenceDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Invoke-WMIPersistenceScan {
    $detections = @()
    
    try {
        # Check WMI Event Consumers
        $eventConsumers = Get-CimInstance -Namespace root\subscription -ClassName __EventConsumer -ErrorAction SilentlyContinue
        
        foreach ($consumer in $eventConsumers) {
            # Check for suspicious consumer types
            if ($consumer.__CLASS -match 'ActiveScript|CommandLine') {
                $suspicious = $false
                $details = @{}
                
                # Check CommandLineEventConsumer
                if ($consumer.__CLASS -eq '__EventConsumer') {
                    $cmdLine = $consumer.CommandLineTemplate
                    if ($cmdLine) {
                        $details.CommandLine = $cmdLine
                        # Check for suspicious commands
                        if ($cmdLine -match 'powershell|cmd|certutil|bitsadmin|wmic' -or
                            $cmdLine -match 'http|https|ftp' -or
                            $cmdLine -match '-encodedcommand|-nop|-w.*hidden') {
                            $suspicious = $true
                        }
                    }
                }
                
                # Check ActiveScriptEventConsumer
                if ($consumer.__CLASS -match 'ActiveScript') {
                    $script = $consumer.ScriptText
                    if ($script -and ($script.Length -gt 1000 -or 
                        $script -match 'wscript|eval|exec|shell')) {
                        $suspicious = $true
                        $details.ScriptLength = $script.Length
                    }
                }
                
                if ($suspicious) {
                    $detections += @{
                        ConsumerName = $consumer.Name
                        ConsumerClass = $consumer.__CLASS
                        Details = $details
                        Risk = "High"
                    }
                }
            }
        }
        
        # Check WMI Event Filters
        $eventFilters = Get-CimInstance -Namespace root\subscription -ClassName __EventFilter -ErrorAction SilentlyContinue
        
        foreach ($filter in $eventFilters) {
            $query = $filter.Query
            if ($query) {
                # Check for suspicious event filters
                if ($query -match 'SELECT.*FROM.*__InstanceModificationEvent' -or
                    $query -match 'SELECT.*FROM.*Win32_ProcessStartTrace') {
                    $filterName = $filter.Name
                    
                    # Check if filter is bound to suspicious consumer
                    $bindings = Get-CimInstance -Namespace root\subscription -ClassName __FilterToConsumerBinding -ErrorAction SilentlyContinue |
                        Where-Object { $_.Filter -like "*$filterName*" }
                    
                    if ($bindings) {
                        $detections += @{
                            FilterName = $filterName
                            Query = $query
                            Type = "Event Filter Binding"
                            Risk = "Medium"
                        }
                    }
                }
            }
        }
        
        # Check for suspicious WMI namespaces
        try {
            $namespaces = Get-CimInstance -Namespace root -ClassName __Namespace -ErrorAction SilentlyContinue |
                Where-Object { $_.Name -match '^[a-f0-9]{32}$' }
            
            foreach ($ns in $namespaces) {
                $detections += @{
                    Namespace = $ns.Name
                    Type = "Suspicious WMI Namespace"
                    Risk = "High"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2006 `
                    -Message "WMI PERSISTENCE DETECTED: $($detection.ConsumerName -or $detection.FilterName -or $detection.Namespace) - $($detection.Type)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\WMIPersistence_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.ConsumerName -or $_.FilterName)|$($_.Type)|$($_.Risk)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) WMI persistence mechanisms"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-WMIPersistenceScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- ScheduledTaskDetection ---
# Scheduled Task Detection Module
# Detects malicious scheduled tasks

$ModuleName = "ScheduledTaskDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Invoke-ScheduledTaskScan {
    $detections = @()
    
    try {
        # Get all scheduled tasks
        $tasks = Get-ScheduledTask -ErrorAction SilentlyContinue
        
        foreach ($task in $tasks) {
            $taskInfo = Get-ScheduledTaskInfo -TaskName $task.TaskName -ErrorAction SilentlyContinue
            $taskActions = $task.Actions
            $taskSettings = $task.Settings
            $suspicious = $false
            $reasons = @()
            
            # Check task actions
            foreach ($action in $taskActions) {
                if ($action.Execute) {
                    $executeLower = $action.Execute.ToLower()
                    
                    # Check for suspicious executables
                    if ($executeLower -match 'powershell|cmd|wscript|cscript|rundll32|mshta') {
                        if ($action.Arguments) {
                            $argsLower = $action.Arguments.ToLower()
                            
                            # Check for suspicious arguments
                            if ($argsLower -match '-encodedcommand|-nop|-w.*hidden|-executionpolicy.*bypass' -or
                                $argsLower -match 'http|https|ftp' -or
                                $argsLower -match 'javascript:|\.hta|\.vbs') {
                                $suspicious = $true
                                $reasons += "Suspicious command line arguments"
                            }
                        }
                        
                        # Check for tasks running as SYSTEM
                        if ($task.Principal.RunLevel -eq "Highest" -or 
                            $task.Principal.UserId -eq "SYSTEM") {
                            $suspicious = $true
                            $reasons += "Runs as SYSTEM/High privilege"
                        }
                    }
                }
            }
            
            # Check for hidden tasks
            if ($taskSettings.Hidden) {
                $suspicious = $true
                $reasons += "Hidden task"
            }
            
            # Check for tasks that run when user is logged off
            if ($taskSettings.RunOnlyIfNetworkAvailable -and 
                $taskSettings.StartWhenAvailable) {
                $suspicious = $true
                $reasons += "Runs when network available (exfiltration risk)"
            }
            
            # Check for tasks in suspicious locations
            foreach ($action in $taskActions) {
                if ($action.WorkingDirectory) {
                    $workDir = $action.WorkingDirectory
                    if ($workDir -match '\$env:|temp|appdata' -and 
                        $workDir -notmatch '^[A-Z]:\\') {
                        $suspicious = $true
                        $reasons += "Suspicious working directory"
                    }
                }
            }
            
            # Check for recently created tasks
            $createdDate = $taskInfo | Select-Object -ExpandProperty 'CreationDate' -ErrorAction SilentlyContinue
            if ($createdDate) {
                $age = (Get-Date) - $createdDate
                if ($age.TotalDays -lt 7) {
                    $suspicious = $true
                    $reasons += "Recently created (within 7 days)"
                }
            }
            
            if ($suspicious) {
                $detections += @{
                    TaskName = $task.TaskName
                    TaskPath = $task.TaskPath
                    Actions = $taskActions
                    Reasons = $reasons
                    State = $task.State
                    Risk = "High"
                }
            }
        }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2007 `
                    -Message "SUSPICIOUS TASK: $($detection.TaskName) - $($detection.Reasons -join ', ')"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\ScheduledTask_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                $actionStr = ($_.Actions | ForEach-Object { "$($_.Execute) $($_.Arguments)" }) -join ' | '
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.TaskName)|$($_.Reasons -join ';')|$actionStr" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) suspicious scheduled tasks"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ScheduledTaskScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- RegistryPersistenceDetection ---
# Registry Persistence Detection Module
# Detects malicious registry-based persistence

$ModuleName = "RegistryPersistenceDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

$PersistenceKeys = @(
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run",
    "HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run",
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run",
    "HKLM:\SYSTEM\CurrentControlSet\Services"
)

function Test-SuspiciousRegistryValue {
    param([string]$Value)
    
    if ([string]::IsNullOrEmpty($Value)) { return $false }
    
    $valueLower = $Value.ToLower()
    
    # Check for suspicious patterns
    $suspiciousPatterns = @(
        'powershell.*-encodedcommand',
        'powershell.*-nop.*-w.*hidden',
        'cmd.*\/c.*powershell',
        'wscript.*http',
        'cscript.*http',
        'rundll32.*javascript',
        'mshta.*http',
        'certutil.*urlcache',
        'bitsadmin.*transfer',
        'regsvr32.*http',
        '\.exe.*http',
        '\.dll.*http'
    )
    
    foreach ($pattern in $suspiciousPatterns) {
        if ($valueLower -match $pattern) {
            return $true
        }
    }
    
    # Check for suspicious file locations
    if ($valueLower -match '\$env:' -and 
        ($valueLower -match 'temp|appdata|local' -or 
         $valueLower -notmatch '^[A-Z]:\\')) {
        return $true
    }
    
    # Check for unsigned executables
    if ($valueLower -like '*.exe' -or $valueLower -like '*.dll') {
        $filePath = $valueLower -replace '"', '' -split ' ' | Select-Object -First 1
        if ($filePath -and (Test-Path $filePath)) {
            try {
                $sig = Get-AuthenticodeSignature -FilePath $filePath -ErrorAction SilentlyContinue
                if ($sig.Status -ne "Valid") {
                    return $true
                }
            } catch { }
        }
    }
    
    return $false
}

function Invoke-RegistryPersistenceScan {
    $detections = @()
    
    try {
        foreach ($regPath in $PersistenceKeys) {
            if (-not (Test-Path $regPath)) { continue }
            
            try {
                $values = Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue
                if ($values) {
                    $valueProps = $values.PSObject.Properties | Where-Object { 
                        $_.Name -notin @('PSPath','PSParentPath','PSChildName','PSDrive','PSProvider')
                    }
                    
                    foreach ($prop in $valueProps) {
                        $regValue = $prop.Value
                        $regName = $prop.Name
                        
                        if (Test-SuspiciousRegistryValue -Value $regValue) {
                            $detections += @{
                                RegistryPath = $regPath
                                ValueName = $regName
                                Value = $regValue
                                Risk = "High"
                            }
                        }
                    }
                }
            } catch { }
        }
        
        # Check for suspicious service entries
        try {
            $services = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue |
                Where-Object { 
                    $_.PathName -match 'powershell|cmd|wscript|cscript|http' -or
                    $_.StartName -eq 'LocalSystem' -and $_.PathName -notmatch '^[A-Z]:\\Windows'
                }
            
            foreach ($svc in $services) {
                if (Test-SuspiciousRegistryValue -Value $svc.PathName) {
                    $detections += @{
                        RegistryPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$($svc.Name)"
                        ValueName = "ImagePath"
                        Value = $svc.PathName
                        ServiceName = $svc.Name
                        Risk = "Critical"
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2008 `
                    -Message "REGISTRY PERSISTENCE: $($detection.RegistryPath)\$($detection.ValueName) - $($detection.Value)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\RegistryPersistence_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.RegistryPath)|$($_.ValueName)|$($_.Value)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) registry persistence mechanisms"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-RegistryPersistenceScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- DLLHijackingDetection ---
# DLL Hijacking Detection Module
# Detects DLL hijacking attempts

$ModuleName = "DLLHijackingDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Test-DLLHijacking {
    param([string]$DllPath)
    
    if (-not (Test-Path $DllPath)) { return $false }
    
    # Check if DLL is in suspicious locations
    $suspiciousPaths = @(
        "$env:TEMP",
        "$env:LOCALAPPDATA\Temp",
        "$env:APPDATA",
        "$env:USERPROFILE\Downloads",
        "$env:USERPROFILE\Desktop"
    )
    
    foreach ($susPath in $suspiciousPaths) {
        if ($DllPath -like "$susPath*") {
            return $true
        }
    }
    
    # Check if DLL is unsigned
    try {
        $sig = Get-AuthenticodeSignature -FilePath $DllPath -ErrorAction SilentlyContinue
        if ($sig.Status -ne "Valid") {
            return $true
        }
    } catch { }
    
    return $false
}

function Invoke-DLLHijackingScan {
    $detections = @()
    
    try {
        # Check loaded DLLs in processes
        $processes = Get-Process -ErrorAction SilentlyContinue
        
        foreach ($proc in $processes) {
            try {
                $modules = $proc.Modules | Where-Object { $_.FileName -like "*.dll" }
                
                foreach ($module in $modules) {
                    if (Test-DLLHijacking -DllPath $module.FileName) {
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            DllPath = $module.FileName
                            DllName = $module.ModuleName
                            Risk = "High"
                        }
                    }
                }
            } catch {
                # Access denied or process exited
                continue
            }
        }
        
        # Check for DLLs in application directories
        $appPaths = @(
            "$env:ProgramFiles",
            "$env:ProgramFiles(x86)",
            "$env:SystemRoot\System32",
            "$env:SystemRoot\SysWOW64"
        )
        
        foreach ($appPath in $appPaths) {
            if (-not (Test-Path $appPath)) { continue }
            
            try {
                $dlls = Get-ChildItem -Path $appPath -Filter "*.dll" -Recurse -ErrorAction SilentlyContinue |
                    Select-Object -First 100
                
                foreach ($dll in $dlls) {
                    if ($dll.DirectoryName -ne "$appPath") {
                        # Check if DLL is signed
                        try {
                            $sig = Get-AuthenticodeSignature -FilePath $dll.FullName -ErrorAction SilentlyContinue
                            if ($sig.Status -ne "Valid") {
                                $detections += @{
                                    DllPath = $dll.FullName
                                    Type = "Unsigned DLL in application directory"
                                    Risk = "Medium"
                                }
                            }
                        } catch { }
                    }
                }
            } catch { }
        }
        
        # Check Event Log for DLL load failures
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='System'; Id=7} -ErrorAction SilentlyContinue -MaxEvents 100
            foreach ($event in $events) {
                if ($event.Message -match 'DLL.*not.*found|DLL.*load.*failed') {
                    $detections += @{
                        EventId = $event.Id
                        Message = $event.Message
                        TimeCreated = $event.TimeCreated
                        Type = "DLL Load Failure"
                        Risk = "Medium"
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2009 `
                    -Message "DLL HIJACKING: $($detection.ProcessName -or $detection.Type) - $($detection.DllPath -or $detection.Message)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\DLLHijacking_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.ProcessName -or $_.Type)|$($_.DllPath -or $_.DllName)|$($_.Risk)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) DLL hijacking indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-DLLHijackingScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- TokenManipulationDetection ---
# Token Manipulation Detection Module
# Detects token theft and impersonation

$ModuleName = "TokenManipulationDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-TokenManipulationScan {
    $detections = @()
    
    try {
        # Check for processes with unusual token privileges
        $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath, ParentProcessId
        
        foreach ($proc in $processes) {
            try {
                $procObj = Get-Process -Id $proc.ProcessId -ErrorAction Stop
                
                # Check for SeDebugPrivilege (enables token access)
                try {
                    $token = Get-CimInstance Win32_LogicalDisk -ErrorAction SilentlyContinue
                    # Indirect check - processes accessing LSASS often have this
                    if ($proc.Name -eq "lsass") {
                        # Check for processes accessing LSASS
                        $accessingProcs = Get-CimInstance Win32_Process | 
                            Where-Object { $_.ParentProcessId -eq $proc.ProcessId -and 
                                          $_.Name -notin @("svchost.exe", "dwm.exe") }
                        
                        foreach ($accProc in $accessingProcs) {
                            $detections += @{
                                ProcessId = $accProc.ProcessId
                                ProcessName = $accProc.Name
                                Type = "LSASS Access - Possible Token Theft"
                                Risk = "Critical"
                            }
                        }
                    }
                } catch { }
                
                # Check for processes running as SYSTEM but not in Windows directory
                if ($procObj.StartInfo.UserName -eq "SYSTEM" -or 
                    $proc.Name -eq "SYSTEM") {
                    if ($proc.ExecutablePath -and 
                        $proc.ExecutablePath -notlike "$env:SystemRoot\*") {
                        $detections += @{
                            ProcessId = $proc.ProcessId
                            ProcessName = $proc.Name
                            ExecutablePath = $proc.ExecutablePath
                            Type = "SYSTEM token on non-Windows executable"
                            Risk = "High"
                        }
                    }
                }
                
            } catch {
                continue
            }
        }
        
        # Check Security Event Log for token operations
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4672} -ErrorAction SilentlyContinue -MaxEvents 100
            foreach ($event in $events) {
                $xml = [xml]$event.ToXml()
                $subjectUserName = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text'
                $targetUserName = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text'
                
                # Check for unusual token impersonation
                if ($subjectUserName -ne $targetUserName -and 
                    $targetUserName -eq "SYSTEM") {
                    $detections += @{
                        EventId = $event.Id
                        SubjectUser = $subjectUserName
                        TargetUser = $targetUserName
                        Type = "Token Impersonation - SYSTEM"
                        TimeCreated = $event.TimeCreated
                        Risk = "High"
                    }
                }
            }
        } catch { }
        
        # Check for common token manipulation tools
        $tokenTools = @("incognito", "mimikatz", "invoke-tokenmanipulation", "getsystem")
        $runningProcs = Get-Process -ErrorAction SilentlyContinue
        
        foreach ($proc in $runningProcs) {
            foreach ($tool in $tokenTools) {
                if ($proc.ProcessName -like "*$tool*" -or 
                    $proc.Path -like "*$tool*") {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        ProcessPath = $proc.Path
                        Type = "Token Manipulation Tool"
                        Tool = $tool
                        Risk = "Critical"
                    }
                }
            }
        }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2010 `
                    -Message "TOKEN MANIPULATION: $($detection.ProcessName -or $detection.Type) - $($detection.Tool -or $detection.TargetUser)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\TokenManipulation_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.ProcessName -or $_.Type)|$($_.Risk)|$($_.Tool -or $_.TargetUser)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) token manipulation attempts"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-TokenManipulationScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- ProcessHollowingDetection ---
# Process Hollowing Detection Module
# Detects process hollowing attacks

$ModuleName = "ProcessHollowingDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 20 }

function Invoke-ProcessHollowingScan {
    $detections = @()
    
    try {
        $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath, CommandLine, ParentProcessId, CreationDate
        
        foreach ($proc in $processes) {
            try {
                $procObj = Get-Process -Id $proc.ProcessId -ErrorAction Stop
                $procPath = $procObj.Path
                $imgPath = $proc.ExecutablePath
                
                # Check for path mismatch (indicator of process hollowing)
                if ($procPath -and $imgPath -and $procPath -ne $imgPath) {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        ProcessPath = $procPath
                        ImagePath = $imgPath
                        Type = "Path Mismatch - Process Hollowing"
                        Risk = "Critical"
                    }
                }
                
                # Check for processes with unusual parent relationships
                if ($proc.ParentProcessId) {
                    try {
                        $parent = Get-CimInstance Win32_Process -Filter "ProcessId=$($proc.ParentProcessId)" -ErrorAction Stop
                        
                        # Check for processes spawned from non-standard parents
                        $suspiciousParents = @{
                            "explorer.exe" = @("notepad.exe", "calc.exe", "cmd.exe", "powershell.exe")
                            "winlogon.exe" = @("cmd.exe", "powershell.exe", "wmic.exe")
                            "services.exe" = @("cmd.exe", "powershell.exe", "rundll32.exe")
                        }
                        
                        if ($suspiciousParents.ContainsKey($parent.Name)) {
                            if ($proc.Name -in $suspiciousParents[$parent.Name]) {
                                $detections += @{
                                    ProcessId = $proc.ProcessId
                                    ProcessName = $proc.Name
                                    ParentProcess = $parent.Name
                                    Type = "Suspicious Parent-Child Relationship"
                                    Risk = "High"
                                }
                            }
                        }
                    } catch { }
                }
                
                # Check for processes with suspended threads
                try {
                    $threads = Get-CimInstance Win32_Thread -Filter "ProcessHandle=$($proc.ProcessId)" -ErrorAction SilentlyContinue
                    $suspendedThreads = $threads | Where-Object { $_.ThreadState -eq 5 } # Suspended
                    
                    if ($suspendedThreads.Count -gt 0 -and $suspendedThreads.Count -eq $threads.Count) {
                        $detections += @{
                            ProcessId = $proc.ProcessId
                            ProcessName = $proc.Name
                            SuspendedThreads = $suspendedThreads.Count
                            Type = "All Threads Suspended - Process Hollowing"
                            Risk = "High"
                        }
                    }
                } catch { }
                
                # Check for processes with unusual memory regions
                try {
                    $memoryRegions = Get-Process -Id $proc.ProcessId -ErrorAction Stop | 
                        Select-Object -ExpandProperty Modules -ErrorAction SilentlyContinue
                    
                    if ($memoryRegions) {
                        $unknownModules = $memoryRegions | Where-Object { 
                            $_.FileName -notlike "$env:SystemRoot\*" -and
                            $_.FileName -notlike "$env:ProgramFiles*" -and
                            $_.ModuleName -notin @("kernel32.dll", "ntdll.dll", "user32.dll")
                        }
                        
                        if ($unknownModules.Count -gt 5) {
                            $detections += @{
                                ProcessId = $proc.ProcessId
                                ProcessName = $proc.Name
                                UnknownModules = $unknownModules.Count
                                Type = "Unusual Memory Modules"
                                Risk = "Medium"
                            }
                        }
                    }
                } catch { }
                
            } catch {
                continue
            }
        }
        
        # Check for processes with unusual PE structure
        try {
            $suspiciousProcs = $processes | Where-Object {
                $_.ExecutablePath -and
                (Test-Path $_.ExecutablePath) -and
                $_.ExecutablePath -notlike "$env:SystemRoot\*"
            }
            
            foreach ($proc in $suspiciousProcs) {
                try {
                    $peInfo = Get-Item $proc.ExecutablePath -ErrorAction Stop
                    
                    # Check if executable is signed
                    $sig = Get-AuthenticodeSignature -FilePath $proc.ExecutablePath -ErrorAction SilentlyContinue
                    if ($sig.Status -ne "Valid") {
                        # Check if it's impersonating a legitimate process
                        $legitNames = @("svchost.exe", "explorer.exe", "notepad.exe", "calc.exe", "dwm.exe")
                        if ($proc.Name -in $legitNames) {
                            $detections += @{
                                ProcessId = $proc.ProcessId
                                ProcessName = $proc.Name
                                ExecutablePath = $proc.ExecutablePath
                                Type = "Unsigned Executable Impersonating Legitimate Process"
                                Risk = "Critical"
                            }
                        }
                    }
                } catch { }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2011 `
                    -Message "PROCESS HOLLOWING: $($detection.ProcessName) (PID: $($detection.ProcessId)) - $($detection.Type)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\ProcessHollowing_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|PID:$($_.ProcessId)|$($_.ProcessName)|$($_.Type)|$($_.Risk)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) process hollowing indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ProcessHollowingScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- KeyloggerDetection ---
# Keylogger Detection Module
# Detects keylogging activity

$ModuleName = "KeyloggerDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-KeyloggerScan {
    $detections = @()
    
    try {
        # Check for known keylogger processes
        $keyloggerNames = @("keylog", "keylogger", "keyspy", "keycapture", "keystroke", "keyhook", "keymon", "kl")
        
        $processes = Get-Process -ErrorAction SilentlyContinue
        foreach ($proc in $processes) {
            $procNameLower = $proc.ProcessName.ToLower()
            foreach ($keylogName in $keyloggerNames) {
                if ($procNameLower -like "*$keylogName*") {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        ProcessPath = $proc.Path
                        Type = "Known Keylogger Process"
                        Risk = "Critical"
                    }
                    break
                }
            }
        }
        
        # Check for processes with keyboard hooks
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath
            
            foreach ($proc in $processes) {
                try {
                    $procObj = Get-Process -Id $proc.ProcessId -ErrorAction Stop
                    
                    # Check for SetWindowsHookEx usage (common in keyloggers)
                    $modules = $procObj.Modules | Where-Object { 
                        $_.ModuleName -match "hook|keyboard|input" 
                    }
                    
                    if ($modules.Count -gt 0) {
                        # Check if process is signed
                        if ($proc.ExecutablePath -and (Test-Path $proc.ExecutablePath)) {
                            $sig = Get-AuthenticodeSignature -FilePath $proc.ExecutablePath -ErrorAction SilentlyContinue
                            if ($sig.Status -ne "Valid") {
                                $detections += @{
                                    ProcessId = $proc.ProcessId
                                    ProcessName = $proc.Name
                                    ExecutablePath = $proc.ExecutablePath
                                    HookModules = $modules.ModuleName -join ','
                                    Type = "Unsigned Process with Keyboard Hooks"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for processes accessing keyboard input devices
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $handles = Get-CimInstance Win32_ProcessHandle -Filter "ProcessId=$($proc.Id)" -ErrorAction SilentlyContinue
                    
                    if ($handles) {
                        # Check for keyboard device access
                        $keyboardHandles = $handles | Where-Object { 
                            $_.Name -match "keyboard|kbdclass|keybd" 
                        }
                        
                        if ($keyboardHandles.Count -gt 0) {
                            # Exclude legitimate processes
                            $legitProcesses = @("explorer.exe", "winlogon.exe", "csrss.exe")
                            if ($proc.ProcessName -notin $legitProcesses) {
                                $detections += @{
                                    ProcessId = $proc.Id
                                    ProcessName = $proc.ProcessName
                                    KeyboardHandles = $keyboardHandles.Count
                                    Type = "Direct Keyboard Device Access"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for clipboard monitoring (often used with keyloggers)
        try {
            $clipboardProcs = Get-Process | Where-Object {
                $_.Modules.ModuleName -like "*clipboard*" -or
                $_.Path -like "*clipboard*"
            }
            
            foreach ($proc in $clipboardProcs) {
                if ($proc.ProcessName -notin @("explorer.exe", "dwm.exe")) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        Type = "Clipboard Monitoring Process"
                        Risk = "Medium"
                    }
                }
            }
        } catch { }
        
        # Check Event Log for suspicious keyboard events
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='Security'} -ErrorAction SilentlyContinue -MaxEvents 500 |
                Where-Object { $_.Message -match 'keyboard|keystroke|hook' }
            
            if ($events.Count -gt 10) {
                $detections += @{
                    EventCount = $events.Count
                    Type = "Excessive Keyboard Events"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2012 `
                    -Message "KEYLOGGER DETECTED: $($detection.ProcessName -or $detection.Type) - $($detection.HookModules -or $detection.Type)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\Keylogger_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.ProcessName -or $_.Type)|$($_.Risk)|$($_.HookModules -or $_.KeyboardHandles)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) keylogger indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-KeyloggerScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- ReflectiveDLLInjectionDetection ---
# Reflective DLL Injection Detection Module
# Detects reflective DLL injection and memory-only DLLs

$ModuleName = "ReflectiveDLLInjectionDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-ReflectiveDLLInjectionDetection {
    $detections = @()
    
    try {
        # Check for processes with memory-only DLLs (reflective injection indicator)
        $processes = Get-Process -ErrorAction SilentlyContinue
        
        foreach ($proc in $processes) {
            try {
                $modules = $proc.Modules
                
                # Check for DLLs that don't exist on disk (reflective injection)
                $memoryOnlyDlls = $modules | Where-Object {
                    $_.FileName -notlike "$env:SystemRoot\*" -and
                    $_.FileName -notlike "$env:ProgramFiles*" -and
                    -not (Test-Path $_.FileName)
                }
                
                if ($memoryOnlyDlls.Count -gt 0) {
                    foreach ($dll in $memoryOnlyDlls) {
                        # Exclude known legitimate cases
                        if ($dll.ModuleName -in @("kernel32.dll", "ntdll.dll", "user32.dll")) {
                            continue
                        }
                        
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            DllName = $dll.ModuleName
                            BaseAddress = $dll.BaseAddress.ToString()
                            DllPath = $dll.FileName
                            Type = "Memory-Only DLL (Reflective Injection)"
                            Risk = "Critical"
                        }
                    }
                }
                
                # Check for unusual DLL base addresses (heap-based injection)
                $unusualAddresses = $modules | Where-Object {
                    $addr = [Int64]$_.BaseAddress
                    # DLLs loaded at unusual addresses (not typical image base)
                    ($addr -lt 0x400000 -or $addr -gt 0x7FFFFFFF0000) -and
                    $_.FileName -like "*.dll"
                }
                
                if ($unusualAddresses.Count -gt 3) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        UnusualAddressCount = $unusualAddresses.Count
                        Type = "DLLs at Unusual Memory Addresses"
                        Risk = "High"
                    }
                }
                
                # Check for processes with many unsigned DLLs in memory
                $unsignedInMemory = 0
                foreach ($mod in $modules) {
                    if ($mod.FileName -like "*.dll" -and (Test-Path $mod.FileName)) {
                        try {
                            $sig = Get-AuthenticodeSignature -FilePath $mod.FileName -ErrorAction SilentlyContinue
                            if ($sig.Status -ne "Valid" -and $mod.FileName -notlike "$env:SystemRoot\*") {
                                $unsignedInMemory++
                            }
                        } catch { }
                    }
                }
                
                if ($unsignedInMemory -gt 10) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        UnsignedDllCount = $unsignedInMemory
                        Type = "Many Unsigned DLLs in Memory"
                        Risk = "Medium"
                    }
                }
            } catch {
                continue
            }
        }
        
        # Check for processes using reflective loading APIs
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine
            
            foreach ($proc in $processes) {
                if ($proc.CommandLine) {
                    # Check for reflective loading patterns in command line
                    if ($proc.CommandLine -match 'VirtualAlloc|WriteProcessMemory|CreateRemoteThread|LoadLibrary|GetProcAddress' -or
                        $proc.CommandLine -match 'reflective|manual.*map|pe.*injection') {
                        
                        $detections += @{
                            ProcessId = $proc.ProcessId
                            ProcessName = $proc.Name
                            CommandLine = $proc.CommandLine
                            Type = "Process Using Reflective Loading APIs"
                            Risk = "High"
                        }
                    }
                }
            }
        } catch { }
        
        # Check for hollowed processes (related to reflective injection)
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath
            
            foreach ($proc in $processes) {
                try {
                    $procObj = Get-Process -Id $proc.ProcessId -ErrorAction Stop
                    $procPath = $procObj.Path
                    $imgPath = $proc.ExecutablePath
                    
                    # Check for path mismatch (process hollowing often uses reflective injection)
                    if ($procPath -and $imgPath -and $procPath -ne $imgPath) {
                        $detections += @{
                            ProcessId = $proc.ProcessId
                            ProcessName = $proc.Name
                            ProcessPath = $procPath
                            ImagePath = $imgPath
                            Type = "Process Hollowing with Reflective Injection"
                            Risk = "Critical"
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check Event Log for DLL load failures (may indicate injection attempts)
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='System'; Id=7} -ErrorAction SilentlyContinue -MaxEvents 100 |
                Where-Object {
                    (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromHours(1) -and
                    $_.Message -match 'DLL.*not.*found|DLL.*load.*failed|reflective'
                }
            
            if ($events.Count -gt 10) {
                $detections += @{
                    EventCount = $events.Count
                    Type = "Excessive DLL Load Failures (Possible Injection Attempts)"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2036 `
                    -Message "REFLECTIVE DLL INJECTION: $($detection.Type) - $($detection.ProcessName) (PID: $($detection.ProcessId))"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\ReflectiveDLL_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|PID:$($_.ProcessId)|$($_.ProcessName)|$($_.DllName -or $_.BaseAddress)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) reflective DLL injection indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ReflectiveDLLInjectionDetection
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- RansomwareDetection ---
# Ransomware Detection Module
# Detects ransomware behavior patterns and ransom notes
#Requires -Version 5.1
# Converted from GEDR C# job: JobRansomwareDetection
# Enhanced with full implementation from C# version


$ModuleName = "RansomwareDetection"
$LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName
$script:Initialized = $false

# Ransomware command-line patterns
$script:RansomwarePatterns = @(
    "vssadmin delete shadows",
    "vssadmin.exe delete", 
    "wbadmin delete catalog",
    "bcdedit",
    "shadow copy",
    "shadowcopy",
    "cryptolocker",
    "wannacry",
    ".encrypted",
    ".locked",
    ".crypto"
)

# Ransom note file names
$script:RansomNoteNames = @(
    "readme.txt",
    "decrypt.txt", 
    "how_to_decrypt.txt",
    "recover.txt",
    "restore.txt",
    "!!!readme!!!.txt",
    "readme_to_decrypt.txt",
    "decrypt_instruction.txt"
)

function Initialize-RansomwareDetection {
    if ($script:Initialized) {
        return
    }
    
    Write-Log "INFO" "Initializing Ransomware Detection module"
    $script:Initialized = $true
}

function Get-ProcessList {
    # Get process list similar to GEDR's EdrProcess.GetProcesses
    try {
        $processes = Get-CimInstance -ClassName Win32_Process -ErrorAction SilentlyContinue |
            Select-Object ProcessId, Name, CommandLine, ExecutablePath, ParentProcessId |
            Where-Object { $_.ProcessId -ne $PID }
        
        return $processes
    }
    catch {
        Write-Log "ERROR" "Failed to get process list: $($_.Exception.Message)"
        return @()
    }
}

function Test-RansomwareCommand {
    param([string]$CommandLine)
    
    if ([string]::IsNullOrEmpty($CommandLine)) {
        return $false
    }
    
    $cmdLower = $CommandLine.ToLowerInvariant()
    foreach ($pattern in $script:RansomwarePatterns) {
        if ($cmdLower.Contains($pattern.ToLowerInvariant())) {
            return $true
        }
    }
    return $false
}

function Find-RansomNotes {
    # Check for ransom notes in user directories
    try {
        $userProfile = $env:USERPROFILE
        if ([string]::IsNullOrEmpty($userProfile)) {
            return
        }
        
        $directories = @(
            Join-Path $userProfile "Documents",
            Join-Path $userProfile "Desktop", 
            Join-Path $userProfile "Pictures"
        )
        
        foreach ($directory in $directories) {
            if (-not (Test-Path $directory)) {
                continue
            }
            
            foreach ($noteName in $script:RansomNoteNames) {
                $fullPath = Join-Path $directory $noteName
                if (Test-Path $fullPath) {
                    $dedupeKey = "Ransomware_Note_$($fullPath)"
                    if (Test-Deduplication -Key $dedupeKey -Category "ransomware") {
                        Write-Log "THREAT" "RANSOMWARE: Ransom note detected: $fullPath" -Category "ransomware_detections"
                        $script:ThreatCount++
                        
                        # Trigger response
                        Invoke-ThreatResponse -ProcessId 0 -ProcessName "RansomNote" -ExecutablePath $fullPath -ThreatLevel "Critical"
                    }
                }
            }
        }
    }
    catch {
        Write-Log "ERROR" "Error checking for ransom notes: $($_.Exception.Message)"
    }
}

function Test-ShadowCopyDeletion {
    # Check if shadow copies exist (ransomware often deletes them)
    try {
        $shadowCopies = Get-CimInstance -ClassName Win32_ShadowCopy -ErrorAction SilentlyContinue
        $count = if ($shadowCopies) { $shadowCopies.Count } else { 0 }
        
        if ($count -eq 0) {
            $dedupeKey = "Ransomware_ShadowCopyZero"
            if (Test-Deduplication -Key $dedupeKey -Category "ransomware") {
                Write-Log "THREAT" "RANSOMWARE: No shadow copies present (possible ransomware deletion)" -Category "ransomware_detections"
                $script:ThreatCount++
            }
        }
    }
    catch {
        Write-Log "ERROR" "Error checking shadow copies: $($_.Exception.Message)"
    }
}

function Invoke-ThreatResponse {
    param(
        [int]$ProcessId,
        [string]$ProcessName,
        [string]$ExecutablePath, 
        [string]$ThreatLevel
    )
    
    try {
        # Log threat response
        Write-Log "ACTION" "THREAT RESPONSE: Triggering response for $ProcessName (PID: $ProcessId) - Level: $ThreatLevel" -Category "threat_responses"
        
        # Implement response actions based on threat level
        switch ($ThreatLevel) {
            "Critical" {
                # For critical threats, consider terminating process
                if ($ProcessId -gt 0) {
                    try {
                        Stop-Process -Id $ProcessId -Force -ErrorAction SilentlyContinue
                        Write-Log "ACTION" "THREAT RESPONSE: Terminated critical process $ProcessName (PID: $ProcessId)" -Category "threat_responses"
                    }
                    catch {
                        Write-Log "WARNING" "Failed to terminate process $ProcessName (PID: $ProcessId): $($_.Exception.Message)"
                    }
                }
                
                # Quarantine file if it exists
                if ($ExecutablePath -and (Test-Path $ExecutablePath)) {
                    Invoke-QuarantineFile -FilePath $ExecutablePath -Reason "Ransomware detection"
                }
            }
        }
    }
    catch {
        Write-Log "ERROR" "Error in threat response: $($_.Exception.Message)"
    }
}

function Invoke-QuarantineFile {
    param([string]$FilePath, [string]$Reason)
    
    try {
        $quarantinePath = "$env:ProgramData\Antivirus\Quarantine"
        if (-not (Test-Path $quarantinePath)) {
            New-Item -Path $quarantinePath -ItemType Directory -Force | Out-Null
        }
        
        $fileName = Split-Path $FilePath -Leaf
        $quarantineFile = Join-Path $quarantinePath "$fileName-$([Guid]::NewGuid()).quar"
        
        Move-Item -Path $FilePath -Destination $quarantineFile -Force
        Write-Log "ACTION" "QUARANTINE: $FilePath moved to $quarantineFile (Reason: $Reason)" -Category "quarantine"
    }
    catch {
        Write-Log "ERROR" "Failed to quarantine file $FilePath`: $($_.Exception.Message)"
    }
}

function Invoke-RansomwareDetection {
    try {
        Initialize-RansomwareDetection
        
        $script:ThreatCount = 0
        $processes = Get-ProcessList
        
        Write-Log "INFO" "Scanning $($processes.Count) processes for ransomware patterns"
        
        foreach ($process in $processes) {
            $cmdLine = if ($process.CommandLine) { $process.CommandLine } else { "" }
            
            if (Test-RansomwareCommand -CommandLine $cmdLine) {
                $pattern = $script:RansomwarePatterns | Where-Object { $cmdLine.ToLowerInvariant().Contains($_.ToLowerInvariant()) } | Select-Object -First 1
                
                $dedupeKey = "Ransomware_$($process.ProcessId)_$($pattern)"
                if (Test-Deduplication -Key $dedupeKey -Category "ransomware") {
                    Write-Log "THREAT" "RANSOMWARE: $($process.Name) (PID: $($process.ProcessId)) | Pattern: $pattern" -Category "ransomware_detections"
                    $script:ThreatCount++
                }
                
                # Trigger threat response
                Invoke-ThreatResponse -ProcessId $process.ProcessId -ProcessName $process.Name -ExecutablePath $process.ExecutablePath -ThreatLevel "Critical"
            }
        }
        
        # Check for ransom notes
        Find-RansomNotes
        
        # Check shadow copy status
        Test-ShadowCopyDeletion
        
        Write-Log "INFO" "Ransomware detection completed. Threats found: $script:ThreatCount"
    }
    catch {
        Write-Log "ERROR" "Error in RansomwareDetection: $($_.Exception.Message)"
    }
}

# Module exports - scheduler will call Invoke-RansomwareDetection on appropriate interval

# --- NetworkAnomalyDetection ---
# Network Anomaly Detection Module
# Detects unusual network activity

$ModuleName = "NetworkAnomalyDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }
$BaselineConnections = @{}

function Initialize-NetworkBaseline {
    try {
        $connections = Get-NetTCPConnection -ErrorAction SilentlyContinue | 
            Where-Object { $_.State -eq "Established" }
        
        foreach ($conn in $connections) {
            $key = "$($conn.LocalAddress):$($conn.LocalPort)-$($conn.RemoteAddress):$($conn.RemotePort)"
            if (-not $BaselineConnections.ContainsKey($key)) {
                $BaselineConnections[$key] = @{
                    Count = 0
                    FirstSeen = Get-Date
                }
            }
            $BaselineConnections[$key].Count++
        }
    } catch { }
}

function Invoke-NetworkAnomalyScan {
    $detections = @()
    
    try {
        # Get current network connections
        $connections = Get-NetTCPConnection -ErrorAction SilentlyContinue | 
            Where-Object { $_.State -eq "Established" }
        
        # Check for unusual destinations
        $suspiciousIPs = @()
        $suspiciousPorts = @(4444, 5555, 6666, 7777, 8888, 9999, 1337, 31337, 8080, 8443)
        
        foreach ($conn in $connections) {
            # Check for suspicious ports
            if ($conn.RemotePort -in $suspiciousPorts) {
                $detections += @{
                    LocalAddress = $conn.LocalAddress
                    LocalPort = $conn.LocalPort
                    RemoteAddress = $conn.RemoteAddress
                    RemotePort = $conn.RemotePort
                    State = $conn.State
                    Type = "Suspicious Port"
                    Risk = "High"
                }
            }
            
            # Check for connections to known bad IPs
            if ($conn.RemoteAddress -match '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)') {
                # Private IP - check if it's unusual
                $key = "$($conn.RemoteAddress):$($conn.RemotePort)"
                if (-not $BaselineConnections.ContainsKey($key)) {
                    $detections += @{
                        LocalAddress = $conn.LocalAddress
                        LocalPort = $conn.LocalPort
                        RemoteAddress = $conn.RemoteAddress
                        RemotePort = $conn.RemotePort
                        Type = "New Connection to Private IP"
                        Risk = "Medium"
                    }
                }
            }
        }
        
        # Check for processes with unusual network activity
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath
            
            foreach ($proc in $processes) {
                try {
                    $procConnections = $connections | Where-Object {
                        $owner = (Get-NetTCPConnection -OwningProcess $proc.ProcessId -ErrorAction SilentlyContinue)
                        $owner.Count -gt 0
                    }
                    
                    if ($procConnections.Count -gt 50) {
                        # High number of connections
                        $detections += @{
                            ProcessId = $proc.ProcessId
                            ProcessName = $proc.Name
                            ConnectionCount = $procConnections.Count
                            Type = "High Network Activity"
                            Risk = "Medium"
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for DNS queries to suspicious domains
        try {
            $dnsQueries = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-DNS-Client/Operational'; Id=3008} -ErrorAction SilentlyContinue -MaxEvents 100
            
            $suspiciousDomains = @(".onion", ".bit", ".i2p", "pastebin.com", "githubusercontent.com")
            foreach ($event in $dnsQueries) {
                $message = $event.Message
                foreach ($domain in $suspiciousDomains) {
                    if ($message -like "*$domain*") {
                        $detections += @{
                            EventId = $event.Id
                            Message = $message
                            Type = "Suspicious DNS Query"
                            Domain = $domain
                            Risk = "Medium"
                        }
                    }
                }
            }
        } catch { }
        
        # Check for unusual data transfer
        try {
            $netStats = Get-NetAdapterStatistics -ErrorAction SilentlyContinue
            foreach ($adapter in $netStats) {
                if ($adapter.SentBytes -gt 1GB -or $adapter.ReceivedBytes -gt 1GB) {
                    # High data transfer
                    $timeSpan = (Get-Date) - $LastTick
                    if ($timeSpan.TotalSeconds -gt 0) {
                        $bytesPerSec = $adapter.SentBytes / $timeSpan.TotalSeconds
                        if ($bytesPerSec -gt 10MB) {
                            $detections += @{
                                Adapter = $adapter.Name
                                SentBytes = $adapter.SentBytes
                                ReceivedBytes = $adapter.ReceivedBytes
                                Type = "High Data Transfer Rate"
                                Risk = "Medium"
                            }
                        }
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2015 `
                    -Message "NETWORK ANOMALY: $($detection.Type) - $($detection.ProcessName -or $detection.RemoteAddress -or $detection.Adapter)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\NetworkAnomaly_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.RemoteAddress)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) network anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    Initialize-NetworkBaseline
    Start-Sleep -Seconds 10
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-NetworkAnomalyScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- DNSExfiltrationDetection ---
# DNS Exfiltration Detection Module
# Detects data exfiltration via DNS queries

$ModuleName = "DNSExfiltrationDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-DNSExfiltrationDetection {
    $detections = @()
    
    try {
        # Monitor DNS queries
        try {
            $dnsEvents = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-DNS-Client/Operational'; Id=3008} -ErrorAction SilentlyContinue -MaxEvents 500
            
            $suspiciousQueries = @()
            
            foreach ($event in $dnsEvents) {
                try {
                    $xml = [xml]$event.ToXml()
                    $queryName = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'QueryName'}).'#text'
                    $queryType = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'QueryType'}).'#text'
                    
                    if ($queryName) {
                        # Check for base64-encoded subdomains (common in DNS exfiltration)
                        $subdomain = $queryName.Split('.')[0]
                        if ($subdomain.Length -gt 20 -and 
                            $subdomain -match '^[A-Za-z0-9+/=]+$' -and
                            $subdomain.Length -gt 50) {
                            $suspiciousQueries += @{
                                QueryName = $queryName
                                QueryType = $queryType
                                TimeCreated = $event.TimeCreated
                                Type = "Base64-Encoded DNS Query"
                                Risk = "High"
                            }
                        }
                        
                        # Check for hex-encoded subdomains
                        if ($subdomain.Length -gt 20 -and 
                            $subdomain -match '^[A-Fa-f0-9]+$' -and
                            $subdomain.Length -gt 50) {
                            $suspiciousQueries += @{
                                QueryName = $queryName
                                QueryType = $queryType
                                TimeCreated = $event.TimeCreated
                                Type = "Hex-Encoded DNS Query"
                                Risk = "High"
                            }
                        }
                        
                        # Check for unusually long domain names
                        if ($queryName.Length -gt 253) {
                            $suspiciousQueries += @{
                                QueryName = $queryName
                                QueryType = $queryType
                                TimeCreated = $event.TimeCreated
                                Type = "Unusually Long DNS Query"
                                Risk = "Medium"
                            }
                        }
                        
                        # Check for queries to suspicious TLDs
                        $suspiciousTLDs = @(".onion", ".bit", ".i2p", ".test", ".local")
                        foreach ($tld in $suspiciousTLDs) {
                            if ($queryName -like "*$tld") {
                                $suspiciousQueries += @{
                                    QueryName = $queryName
                                    QueryType = $queryType
                                    TimeCreated = $event.TimeCreated
                                    Type = "DNS Query to Suspicious TLD"
                                    TLD = $tld
                                    Risk = "Medium"
                                }
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
            
            $detections += $suspiciousQueries
            
            # Check for excessive DNS queries from single process
            try {
                $processes = Get-Process -ErrorAction SilentlyContinue
                
                foreach ($proc in $processes) {
                    try {
                        $procEvents = $dnsEvents | Where-Object {
                            $_.ProcessId -eq $proc.Id
                        } -ErrorAction SilentlyContinue
                        
                        if ($procEvents.Count -gt 100) {
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                DNSQueryCount = $procEvents.Count
                                Type = "Excessive DNS Queries from Process"
                                Risk = "High"
                            }
                        }
                    } catch {
                        continue
                    }
                }
            } catch { }
        } catch { }
        
        # Monitor DNS traffic volume
        try {
            $dnsConnections = Get-NetUDPEndpoint -ErrorAction SilentlyContinue |
                Where-Object { $_.LocalPort -eq 53 }
            
            if ($dnsConnections.Count -gt 100) {
                $detections += @{
                    ConnectionCount = $dnsConnections.Count
                    Type = "High DNS Traffic Volume"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for DNS tunneling tools
        try {
            $processes = Get-CimInstance Win32_Process | 
                Where-Object { 
                    $_.Name -match 'dnscat|iodine|dns2tcp|dnsperf'
                }
            
            foreach ($proc in $processes) {
                $detections += @{
                    ProcessId = $proc.ProcessId
                    ProcessName = $proc.Name
                    CommandLine = $proc.CommandLine
                    Type = "DNS Tunneling Tool Detected"
                    Risk = "Critical"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2029 `
                    -Message "DNS EXFILTRATION: $($detection.Type) - $($detection.QueryName -or $detection.ProcessName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\DNSExfiltration_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.QueryName -or $_.ProcessName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) DNS exfiltration indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-DNSExfiltrationDetection
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- RootkitDetection ---
# Rootkit Detection Module
# Detects rootkit installation and activity

$ModuleName = "RootkitDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Invoke-RootkitScan {
    $detections = @()
    
    try {
        # Check for hidden processes (rootkit indicator)
        $processes = Get-Process -ErrorAction SilentlyContinue
        $cimProcesses = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | 
            Select-Object ProcessId, Name
        
        $processIds = $processes | ForEach-Object { $_.Id } | Sort-Object -Unique
        $cimProcessIds = $cimProcesses | ForEach-Object { $_.ProcessId } | Sort-Object -Unique
        
        $hiddenProcesses = Compare-Object -ReferenceObject $processIds -DifferenceObject $cimProcessIds
        
        if ($hiddenProcesses) {
            foreach ($hidden in $hiddenProcesses) {
                $detections += @{
                    ProcessId = $hidden.InputObject
                    Type = "Hidden Process Detected"
                    Risk = "Critical"
                }
            }
        }
        
        # Check for hidden files/directories
        try {
            $systemDirs = @("$env:SystemRoot\System32", "$env:SystemRoot\SysWOW64")
            
            foreach ($dir in $systemDirs) {
                if (Test-Path $dir) {
                    $files = Get-ChildItem -Path $dir -Force -ErrorAction SilentlyContinue |
                        Where-Object { $_.Attributes -match 'Hidden' -or $_.Attributes -match 'System' }
                    
                    $suspiciousFiles = $files | Where-Object {
                        $_.Name -match '^(\.|\.\.|sys|drv)' -or
                        $_.Extension -match '^\.(sys|drv|dll)$'
                    }
                    
                    if ($suspiciousFiles.Count -gt 10) {
                        $detections += @{
                            Directory = $dir
                            SuspiciousFiles = $suspiciousFiles.Count
                            Type = "Suspicious Hidden Files in System Directory"
                            Risk = "High"
                        }
                    }
                }
            }
        } catch { }
        
        # Check for kernel drivers
        try {
            $drivers = Get-CimInstance Win32_SystemDriver -ErrorAction SilentlyContinue |
                Where-Object { 
                    $_.State -eq "Running" -and
                    $_.PathName -notlike "$env:SystemRoot\*" -or
                    $_.Description -match 'rootkit|stealth|hook'
                }
            
            foreach ($driver in $drivers) {
                $detections += @{
                    DriverName = $driver.Name
                    PathName = $driver.PathName
                    Description = $driver.Description
                    Type = "Suspicious Kernel Driver"
                    Risk = "Critical"
                }
            }
        } catch { }
        
        # Check for SSDT hooks (indirectly through Event Log)
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='System'; Id=6008} -ErrorAction SilentlyContinue -MaxEvents 50
            
            $hookIndicators = $events | Where-Object {
                $_.Message -match 'hook|SSDT|kernel|driver.*unexpected'
            }
            
            if ($hookIndicators.Count -gt 0) {
                $detections += @{
                    EventCount = $hookIndicators.Count
                    Type = "SSDT Hook Indicators"
                    Risk = "Critical"
                }
            }
        } catch { }
        
        # Check for processes with unusual privileges
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath
            
            foreach ($proc in $processes) {
                try {
                    $procObj = Get-Process -Id $proc.ProcessId -ErrorAction Stop
                    
                    # Check for SeDebugPrivilege (common in rootkits)
                    if ($procObj.PrivilegedProcessorTime.TotalSeconds -gt 0 -and 
                        $proc.Name -notin @("csrss.exe", "winlogon.exe", "services.exe")) {
                        # Indirect check - process with unusual privileges
                        if ($proc.ExecutablePath -and (Test-Path $proc.ExecutablePath)) {
                            $sig = Get-AuthenticodeSignature -FilePath $proc.ExecutablePath -ErrorAction SilentlyContinue
                            if ($sig.Status -ne "Valid" -and $proc.ExecutablePath -like "$env:SystemRoot\*") {
                                $detections += @{
                                    ProcessId = $proc.ProcessId
                                    ProcessName = $proc.Name
                                    ExecutablePath = $proc.ExecutablePath
                                    Type = "Unsigned Process with System Privileges"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for unusual boot entries
        try {
            $bootEntries = Get-CimInstance Win32_BootConfiguration -ErrorAction SilentlyContinue
            
            foreach ($boot in $bootEntries) {
                if ($boot.Description -match 'rootkit|stealth|hook' -or
                    $boot.Description -notlike '*Windows*') {
                    $detections += @{
                        BootEntry = $boot.Description
                        Type = "Suspicious Boot Entry"
                        Risk = "Critical"
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2017 `
                    -Message "ROOTKIT DETECTED: $($detection.Type) - $($detection.ProcessName -or $detection.DriverName -or $detection.Directory)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\Rootkit_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.DriverName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) rootkit indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-RootkitScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- ClipboardMonitoring ---
# Clipboard Monitoring Module
# Monitors clipboard for sensitive data

$ModuleName = "ClipboardMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 10 }

function Invoke-ClipboardMonitoring {
    $detections = @()
    
    try {
        # Monitor clipboard content
        Add-Type -AssemblyName System.Windows.Forms
        
        if ([System.Windows.Forms.Clipboard]::ContainsText()) {
            $clipboardText = [System.Windows.Forms.Clipboard]::GetText()
            
            if (-not [string]::IsNullOrEmpty($clipboardText)) {
                # Check for sensitive data patterns
                $sensitivePatterns = @(
                    @{Pattern = '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'; Type = 'Email Address'},
                    @{Pattern = '\b\d{3}-\d{2}-\d{4}\b'; Type = 'SSN'},
                    @{Pattern = '\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b'; Type = 'Credit Card'},
                    @{Pattern = '(?i)(password|passwd|pwd|secret|api[_-]?key|token|bearer)'; Type = 'Password/Token'},
                    @{Pattern = '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'; Type = 'IP Address'},
                    @{Pattern = '(?i)(https?://[^\s]+)'; Type = 'URL'}
                )
                
                foreach ($pattern in $sensitivePatterns) {
                    if ($clipboardText -match $pattern.Pattern) {
                        $matches = [regex]::Matches($clipboardText, $pattern.Pattern)
                        
                        if ($matches.Count -gt 0) {
                            $detections += @{
                                Type = "Sensitive Data in Clipboard"
                                DataType = $pattern.Type
                                MatchCount = $matches.Count
                                Risk = if ($pattern.Type -match 'Password|SSN|Credit Card') { "High" } else { "Medium" }
                            }
                        }
                    }
                }
                
                # Check for large clipboard content (possible exfiltration)
                if ($clipboardText.Length -gt 10000) {
                    $detections += @{
                        Type = "Large Clipboard Content"
                        ContentLength = $clipboardText.Length
                        Risk = "Medium"
                    }
                }
                
                # Check for base64 encoded content
                if ($clipboardText -match '^[A-Za-z0-9+/]+={0,2}$' -and $clipboardText.Length -gt 100) {
                    try {
                        $decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($clipboardText))
                        if ($decoded.Length -gt 0) {
                            $detections += @{
                                Type = "Base64 Encoded Content in Clipboard"
                                EncodedLength = $clipboardText.Length
                                DecodedLength = $decoded.Length
                                Risk = "Medium"
                            }
                        }
                    } catch { }
                }
            }
        }
        
        # Check for processes accessing clipboard
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $modules = $proc.Modules | Where-Object {
                        $_.ModuleName -match 'clipboard|clip'
                    }
                    
                    if ($modules.Count -gt 0) {
                        # Exclude legitimate processes
                        $legitProcesses = @("explorer.exe", "dwm.exe", "mstsc.exe")
                        if ($proc.ProcessName -notin $legitProcesses) {
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                Type = "Process Accessing Clipboard"
                                Risk = "Medium"
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2018 `
                    -Message "CLIPBOARD MONITORING: $($detection.Type) - $($detection.DataType -or $detection.ProcessName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\Clipboard_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.DataType -or $_.ProcessName)|$($_.Risk)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) clipboard anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ClipboardMonitoring
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- COMMonitoring ---
# COM Object Monitoring Module
# Monitors COM object instantiation and usage

$ModuleName = "COMMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Invoke-COMMonitoring {
    $detections = @()
    
    try {
        # Check for suspicious COM objects
        $suspiciousCOMObjects = @(
            "Shell.Application",
            "WScript.Shell",
            "Scripting.FileSystemObject",
            "Excel.Application",
            "Word.Application",
            "InternetExplorer.Application"
        )
        
        # Check running processes for COM usage
        $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine
        
        foreach ($proc in $processes) {
            try {
                # Check command line for COM object creation
                if ($proc.CommandLine) {
                    foreach ($comObj in $suspiciousCOMObjects) {
                        if ($proc.CommandLine -like "*$comObj*" -or 
                            $proc.CommandLine -like "*New-Object*$comObj*" -or
                            $proc.CommandLine -like "*CreateObject*$comObj*") {
                            
                            $detections += @{
                                ProcessId = $proc.ProcessId
                                ProcessName = $proc.Name
                                CommandLine = $proc.CommandLine
                                COMObject = $comObj
                                Type = "Suspicious COM Object Usage"
                                Risk = "Medium"
                            }
                        }
                    }
                }
            } catch {
                continue
            }
        }
        
        # Check Event Log for COM object registration
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='Application'} -ErrorAction SilentlyContinue -MaxEvents 500 |
                Where-Object { $_.Message -match 'COM|Component Object Model' }
            
            $registrationEvents = $events | Where-Object {
                $_.Message -match 'registration|registration.*failed|COM.*error'
            }
            
            if ($registrationEvents.Count -gt 5) {
                $detections += @{
                    EventCount = $registrationEvents.Count
                    Type = "Unusual COM Registration Activity"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for COM hijacking
        try {
            $comKeys = @(
                "HKCU:\SOFTWARE\Classes\CLSID",
                "HKLM:\SOFTWARE\Classes\CLSID"
            )
            
            foreach ($comKey in $comKeys) {
                if (Test-Path $comKey) {
                    $clsidKeys = Get-ChildItem -Path $comKey -ErrorAction SilentlyContinue | Select-Object -First 100
                    
                    foreach ($clsid in $clsidKeys) {
                        $inprocServer = Join-Path $clsid.PSPath "InprocServer32"
                        
                        if (Test-Path $inprocServer) {
                            $default = (Get-ItemProperty -Path $inprocServer -Name "(default)" -ErrorAction SilentlyContinue).'(default)'
                            
                            if ($default -and $default -notlike "$env:SystemRoot\*") {
                                $detections += @{
                                    CLSID = $clsid.Name
                                    InprocServer = $default
                                    Type = "COM Hijacking - Non-System InprocServer"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                }
            }
        } catch { }
        
        # Check for Excel/Word automation (common in malware)
        try {
            $excelProcs = Get-Process -Name "EXCEL" -ErrorAction SilentlyContinue
            $wordProcs = Get-Process -Name "WINWORD" -ErrorAction SilentlyContinue
            
            foreach ($proc in ($excelProcs + $wordProcs)) {
                try {
                    $commandLine = (Get-CimInstance Win32_Process -Filter "ProcessId=$($proc.Id)").CommandLine
                    
                    if ($commandLine -match '\.vbs|\.js|\.ps1|\.bat|powershell|cmd') {
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            CommandLine = $commandLine
                            Type = "Office Application with Script Execution"
                            Risk = "High"
                        }
                    }
                } catch { }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2019 `
                    -Message "COM MONITORING: $($detection.Type) - $($detection.ProcessName -or $detection.CLSID -or $detection.COMObject)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\COMMonitoring_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.COMObject -or $_.CLSID)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) COM object anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-COMMonitoring
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- BrowserExtensionMonitoring ---
# Browser Extension Monitoring Module
# Monitors browser extensions for malicious activity

$ModuleName = "BrowserExtensionMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Invoke-BrowserExtensionMonitoring {
    $detections = @()
    
    try {
        # Check Chrome extensions
        $chromeExtensionsPath = "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Extensions"
        if (Test-Path $chromeExtensionsPath) {
            $chromeExts = Get-ChildItem -Path $chromeExtensionsPath -Directory -ErrorAction SilentlyContinue
            
            foreach ($ext in $chromeExts) {
                $manifestPath = Join-Path $ext.FullName "*\manifest.json"
                $manifests = Get-ChildItem -Path $manifestPath -ErrorAction SilentlyContinue
                
                foreach ($manifest in $manifests) {
                    try {
                        $manifestContent = Get-Content $manifest.FullName -Raw | ConvertFrom-Json -ErrorAction Stop
                        
                        # Check for suspicious permissions
                        $suspiciousPermissions = @("all_urls", "tabs", "cookies", "history", "downloads", "webRequest", "webRequestBlocking")
                        $hasSuspiciousPerms = $false
                        
                        if ($manifestContent.permissions) {
                            foreach ($perm in $manifestContent.permissions) {
                                if ($perm -in $suspiciousPermissions) {
                                    $hasSuspiciousPerms = $true
                                    break
                                }
                            }
                        }
                        
                        # Check for unsigned extensions
                        $isSigned = $manifestContent.key -ne $null
                        
                        if ($hasSuspiciousPerms -or -not $isSigned) {
                            $detections += @{
                                Browser = "Chrome"
                                ExtensionId = $ext.Name
                                ExtensionName = $manifestContent.name
                                ManifestPath = $manifest.FullName
                                HasSuspiciousPermissions = $hasSuspiciousPerms
                                IsSigned = $isSigned
                                Type = "Suspicious Chrome Extension"
                                Risk = if ($hasSuspiciousPerms) { "High" } else { "Medium" }
                            }
                        }
                    } catch {
                        continue
                    }
                }
            }
        }
        
        # Check Edge extensions
        $edgeExtensionsPath = "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Extensions"
        if (Test-Path $edgeExtensionsPath) {
            $edgeExts = Get-ChildItem -Path $edgeExtensionsPath -Directory -ErrorAction SilentlyContinue
            
            foreach ($ext in $edgeExts) {
                $manifestPath = Join-Path $ext.FullName "*\manifest.json"
                $manifests = Get-ChildItem -Path $manifestPath -ErrorAction SilentlyContinue
                
                foreach ($manifest in $manifests) {
                    try {
                        $manifestContent = Get-Content $manifest.FullName -Raw | ConvertFrom-Json -ErrorAction Stop
                        
                        if ($manifestContent.permissions) {
                            $suspiciousPerms = $manifestContent.permissions | Where-Object {
                                $_ -in @("all_urls", "tabs", "cookies", "webRequest")
                            }
                            
                            if ($suspiciousPerms.Count -gt 0) {
                                $detections += @{
                                    Browser = "Edge"
                                    ExtensionId = $ext.Name
                                    ExtensionName = $manifestContent.name
                                    SuspiciousPermissions = $suspiciousPerms -join ','
                                    Type = "Suspicious Edge Extension"
                                    Risk = "Medium"
                                }
                            }
                        }
                    } catch {
                        continue
                    }
                }
            }
        }
        
        # Check Firefox extensions
        $firefoxProfilesPath = "$env:APPDATA\Mozilla\Firefox\Profiles"
        if (Test-Path $firefoxProfilesPath) {
            $profiles = Get-ChildItem -Path $firefoxProfilesPath -Directory -ErrorAction SilentlyContinue
            
            foreach ($profile in $profiles) {
                $extensionsPath = Join-Path $profile.FullName "extensions"
                if (Test-Path $extensionsPath) {
                    $firefoxExts = Get-ChildItem -Path $extensionsPath -File -ErrorAction SilentlyContinue |
                        Where-Object { $_.Extension -eq ".xpi" -or $_.Extension -eq "" }
                    
                    foreach ($ext in $firefoxExts) {
                        $detections += @{
                            Browser = "Firefox"
                            ExtensionPath = $ext.FullName
                            Type = "Firefox Extension Detected"
                            Risk = "Low"
                        }
                    }
                }
            }
        }
        
        # Check for browser processes with unusual activity
        try {
            $browserProcs = Get-Process -ErrorAction SilentlyContinue | 
                Where-Object { $_.ProcessName -match 'chrome|edge|firefox|msedge' }
            
            foreach ($proc in $browserProcs) {
                try {
                    $conns = Get-NetTCPConnection -OwningProcess $proc.Id -ErrorAction SilentlyContinue |
                        Where-Object { $_.State -eq "Established" }
                    
                    # Check for connections to suspicious domains
                    $remoteIPs = $conns.RemoteAddress | Select-Object -Unique
                    
                    foreach ($ip in $remoteIPs) {
                        try {
                            $hostname = [System.Net.Dns]::GetHostEntry($ip).HostName
                            
                            $suspiciousDomains = @(".onion", ".bit", ".i2p", "pastebin", "githubusercontent")
                            foreach ($domain in $suspiciousDomains) {
                                if ($hostname -like "*$domain*") {
                                    $detections += @{
                                        BrowserProcess = $proc.ProcessName
                                        ProcessId = $proc.Id
                                        ConnectedDomain = $hostname
                                        Type = "Browser Connecting to Suspicious Domain"
                                        Risk = "Medium"
                                    }
                                }
                            }
                        } catch { }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2020 `
                    -Message "BROWSER EXTENSION: $($detection.Type) - $($detection.ExtensionName -or $detection.BrowserProcess)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\BrowserExtension_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ExtensionName -or $_.BrowserProcess)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) browser extension anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-BrowserExtensionMonitoring
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- ShadowCopyMonitoring ---
# Shadow Copy Monitoring Module
# Monitors shadow copy deletion (ransomware indicator)

$ModuleName = "ShadowCopyMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-ShadowCopyMonitoring {
    $detections = @()
    
    try {
        # Check for shadow copies
        $shadowCopies = Get-CimInstance Win32_ShadowCopy -ErrorAction SilentlyContinue
        
        # Check shadow copy count
        if ($shadowCopies.Count -eq 0) {
            $detections += @{
                Type = "No Shadow Copies Found"
                ShadowCopyCount = 0
                Risk = "Medium"
            }
        }
        
        # Monitor shadow copy deletion
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='System'} -ErrorAction SilentlyContinue -MaxEvents 200 |
                Where-Object { 
                    $_.Message -match 'shadow|vss|volume.*snapshot' -or
                    $_.Id -in @(8221, 8222, 8223, 8224)
                }
            
            $deletionEvents = $events | Where-Object {
                $_.Message -match 'delete|deleted|remove|removed'
            }
            
            if ($deletionEvents.Count -gt 0) {
                foreach ($event in $deletionEvents) {
                    $detections += @{
                        EventId = $event.Id
                        TimeCreated = $event.TimeCreated
                        Message = $event.Message
                        Type = "Shadow Copy Deletion Detected"
                        Risk = "High"
                    }
                }
            }
        } catch { }
        
        # Check for VSSAdmin usage
        try {
            $processes = Get-CimInstance Win32_Process | 
                Where-Object { $_.Name -eq "vssadmin.exe" -or $_.CommandLine -like "*vssadmin*" }
            
            foreach ($proc in $processes) {
                if ($proc.CommandLine -match 'delete.*shadows|resize.*shadowstorage') {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        CommandLine = $proc.CommandLine
                        Type = "VSSAdmin Shadow Copy Manipulation"
                        Risk = "Critical"
                    }
                }
            }
        } catch { }
        
        # Check for Volume Shadow Copy Service status
        try {
            $vssService = Get-CimInstance Win32_Service -Filter "Name='VSS'" -ErrorAction SilentlyContinue
            
            if ($vssService) {
                if ($vssService.State -ne "Running") {
                    $detections += @{
                        ServiceState = $vssService.State
                        Type = "Volume Shadow Copy Service Not Running"
                        Risk = "High"
                    }
                }
            }
        } catch { }
        
        # Check shadow storage configuration
        try {
            $shadowStorage = Get-CimInstance Win32_ShadowStorage -ErrorAction SilentlyContinue
            
            foreach ($storage in $shadowStorage) {
                # Check if shadow storage is disabled or too small
                $allocated = $storage.AllocatedSpace
                $maxSize = $storage.MaxSpace
                
                if ($maxSize -eq 0 -or $allocated -eq 0) {
                    $detections += @{
                        Volume = $storage.Volume
                        AllocatedSpace = $allocated
                        MaxSpace = $maxSize
                        Type = "Shadow Storage Disabled or Empty"
                        Risk = "Medium"
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2021 `
                    -Message "SHADOW COPY MONITORING: $($detection.Type) - $($detection.ProcessName -or $detection.Volume -or $detection.Message)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\ShadowCopy_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.Volume)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) shadow copy anomalies"
        }
        
        Write-Output "STATS:$ModuleName`:Shadow copies=$($shadowCopies.Count)"
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ShadowCopyMonitoring
                $LastTick = $now
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- USBMonitoring ---
# USB Device Monitoring Module
# Monitors USB device connections and activity

$ModuleName = "USBMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-USBMonitoring {
    $detections = @()
    
    try {
        # Get USB devices
        $usbDevices = Get-CimInstance Win32_USBControllerDevice -ErrorAction SilentlyContinue
        
        foreach ($usbDevice in $usbDevices) {
            try {
                $device = Get-CimInstance -InputObject $usbDevice.Dependent -ErrorAction SilentlyContinue
                
                if ($device) {
                    # Check for suspicious USB device types
                    $suspiciousDevices = @{
                        "HID" = "Human Interface Device"
                        "USBSTOR" = "USB Mass Storage"
                    }
                    
                    $deviceType = $device.DeviceID
                    
                    # Check for HID devices (keyloggers, etc.)
                    if ($deviceType -match "HID") {
                        $detections += @{
                            DeviceId = $device.DeviceID
                            DeviceName = $device.Name
                            DeviceType = "HID Device"
                            Type = "USB HID Device Connected"
                            Risk = "Medium"
                        }
                    }
                    
                    # Check for USB storage devices
                    if ($deviceType -match "USBSTOR") {
                        $detections += @{
                            DeviceId = $device.DeviceID
                            DeviceName = $device.Name
                            DeviceType = "USB Storage"
                            Type = "USB Storage Device Connected"
                            Risk = "Low"
                        }
                    }
                }
            } catch {
                continue
            }
        }
        
        # Check Event Log for USB device events
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='System'; Id=20001,20002,20003} -ErrorAction SilentlyContinue -MaxEvents 100 |
                Where-Object { $_.Message -match 'USB|removable|storage' }
            
            $recentEvents = $events | Where-Object {
                (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromMinutes(5)
            }
            
            if ($recentEvents.Count -gt 5) {
                $detections += @{
                    EventCount = $recentEvents.Count
                    Type = "Excessive USB Device Activity"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for USB device autorun
        try {
            $autorunKeys = @(
                "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers",
                "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
            )
            
            foreach ($key in $autorunKeys) {
                if (Test-Path $key) {
                    $noDriveAutorun = Get-ItemProperty -Path $key -Name "NoDriveTypeAutoRun" -ErrorAction SilentlyContinue
                    
                    if ($noDriveAutorun -and $noDriveAutorun.NoDriveTypeAutoRun -eq 0) {
                        $detections += @{
                            RegistryKey = $key
                            Type = "USB Autorun Enabled"
                            Risk = "High"
                        }
                    }
                }
            }
        } catch { }
        
        # Check for processes accessing USB devices
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $modules = $proc.Modules | Where-Object {
                        $_.ModuleName -match 'usb|hid|storage'
                    }
                    
                    if ($modules.Count -gt 0) {
                        # Exclude legitimate processes
                        $legitProcesses = @("explorer.exe", "svchost.exe", "services.exe")
                        if ($proc.ProcessName -notin $legitProcesses) {
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                USBModules = $modules.ModuleName -join ','
                                Type = "Process Accessing USB Devices"
                                Risk = "Medium"
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for USB device driver modifications
        try {
            $usbDrivers = Get-CimInstance Win32_SystemDriver -ErrorAction SilentlyContinue |
                Where-Object { 
                    $_.PathName -match 'usb|hid' -and
                    $_.PathName -notlike "$env:SystemRoot\*"
                }
            
            foreach ($driver in $usbDrivers) {
                $detections += @{
                    DriverName = $driver.Name
                    DriverPath = $driver.PathName
                    Type = "Non-Standard USB Driver"
                    Risk = "High"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Information -EventId 2022 `
                    -Message "USB MONITORING: $($detection.Type) - $($detection.DeviceName -or $detection.ProcessName -or $detection.DriverName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\USBMonitoring_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.DeviceName -or $_.ProcessName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) USB device anomalies"
        }
        
        Write-Output "STATS:$ModuleName`:USB devices=$($usbDevices.Count)"
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-USBMonitoring
                $LastTick = $now
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- WebcamGuardian ---
# Webcam Guardian Module
# Monitors webcam access and protects privacy

$ModuleName = "WebcamGuardian"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 20 }

function Invoke-WebcamGuardian {
    $detections = @()
    
    try {
        # Check for webcam devices
        try {
            $webcamDevices = Get-CimInstance Win32_PnPEntity -ErrorAction SilentlyContinue |
                Where-Object { 
                    $_.Name -match 'camera|webcam|video|imaging|usb.*video' -or
                    $_.PNPDeviceID -match 'VID_.*PID_.*.*CAMERA'
                }
            
            if ($webcamDevices.Count -gt 0) {
                Write-Output "STATS:$ModuleName`:Webcam devices=$($webcamDevices.Count)"
            }
        } catch { }
        
        # Check for processes accessing webcam
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    # Check for webcam-related modules
                    $modules = $proc.Modules | Where-Object {
                        $_.ModuleName -match 'ksuser|avicap32|msvfw32|amstream|qcap|vidcap'
                    }
                    
                    if ($modules.Count -gt 0) {
                        # Check if process is authorized
                        $authorizedProcesses = @("explorer.exe", "dwm.exe", "chrome.exe", "firefox.exe", "msedge.exe", "teams.exe", "zoom.exe", "skype.exe")
                        
                        if ($proc.ProcessName -notin $authorizedProcesses) {
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                ProcessPath = $proc.Path
                                WebcamModules = $modules.ModuleName -join ','
                                Type = "Unauthorized Webcam Access"
                                Risk = "High"
                            }
                        }
                    }
                    
                    # Check for video capture libraries
                    $videoModules = $proc.Modules | Where-Object {
                        $_.ModuleName -match 'video|capture|stream|directshow|media'
                    }
                    
                    if ($videoModules.Count -gt 3 -and 
                        $proc.ProcessName -notin $authorizedProcesses) {
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            VideoModules = $videoModules.ModuleName -join ','
                            Type = "Process with Many Video Capture Modules"
                            Risk = "Medium"
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for webcam-related registry keys
        try {
            $webcamRegKeys = @(
                "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam",
                "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam"
            )
            
            foreach ($regKey in $webcamRegKeys) {
                if (Test-Path $regKey) {
                    $values = Get-ItemProperty -Path $regKey -ErrorAction SilentlyContinue
                    
                    if ($values) {
                        # Check for applications with webcam access
                        $appAccess = $values.PSObject.Properties | Where-Object {
                            $_.Name -notin @('PSPath','PSParentPath','PSChildName','PSDrive','PSProvider') -and
                            $_.Value -ne "Deny"
                        }
                        
                        foreach ($app in $appAccess) {
                            # Check if app is suspicious
                            if ($app.Name -notmatch 'microsoft|windows|explorer|chrome|firefox|edge|teams|zoom|skype') {
                                $detections += @{
                                    RegistryKey = $regKey
                                    AppName = $app.Name
                                    Access = $app.Value
                                    Type = "Suspicious App with Webcam Access"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                }
            }
        } catch { }
        
        # Check Event Log for webcam access
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='Application'} -ErrorAction SilentlyContinue -MaxEvents 500 |
                Where-Object { 
                    $_.Message -match 'camera|webcam|video.*capture|imaging.*device'
                }
            
            $webcamEvents = $events | Where-Object {
                (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromMinutes(5)
            }
            
            if ($webcamEvents.Count -gt 10) {
                $detections += @{
                    EventCount = $webcamEvents.Count
                    Type = "Excessive Webcam Access Activity"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for webcam blocking/monitoring tools
        try {
            $processes = Get-CimInstance Win32_Process | 
                Where-Object { 
                    $_.Name -match 'camtasia|obs|webcam|camera|guardian|privacy'
                }
            
            foreach ($proc in $processes) {
                # These are usually legitimate, but log them
                Write-Output "STATS:$ModuleName`:Webcam-related process=$($proc.Name)"
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2031 `
                    -Message "WEBCAM GUARDIAN: $($detection.Type) - $($detection.ProcessName -or $detection.AppName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\WebcamGuardian_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.AppName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) webcam access anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-WebcamGuardian
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- AttackToolsDetection ---
# Attack Tools Detection
# Detects Mimikatz, Cobalt Strike, Metasploit, etc.

$ModuleName = "AttackToolsDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 90 }

$AttackTools = @("mimikatz", "pwdump", "procdump", "wce", "gsecdump", "cain", "john", "hashcat", "hydra", "medusa", "nmap", "metasploit", "armitage", "cobalt")

function Invoke-AttackToolsScan {
    $detections = @()
    try {
        $processes = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Select-Object ProcessId, Name, CommandLine
        foreach ($proc in $processes) {
            $name = if ($proc.Name) { $proc.Name.ToLower() } else { "" }
            $cmd = if ($proc.CommandLine) { $proc.CommandLine.ToLower() } else { "" }
            foreach ($tool in $AttackTools) {
                if ($name -like "*$tool*" -or $cmd -like "*$tool*") {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        CommandLine = $proc.CommandLine
                        Tool = $tool
                        Type = "Attack Tool Detected"
                        Risk = "Critical"
                    }
                    break
                }
            }
        }
        
        if ($detections.Count -gt 0) {
            foreach ($d in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2092 -Message "ATTACK TOOL: $($d.Tool) - $($d.ProcessName) (PID: $($d.ProcessId))" -ErrorAction SilentlyContinue
            }
            $logPath = "$env:ProgramData\Antivirus\Logs\attack_tools_detection_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object { "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Tool)|$($_.ProcessName)|PID:$($_.ProcessId)" | Add-Content -Path $logPath }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) attack tools"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $script:LastTick = $now
                Invoke-AttackToolsScan | Out-Null
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- AdvancedThreatDetection ---
# Advanced Threat Detection
# High-entropy files in Windows\Temp, System32\Tasks

$ModuleName = "AdvancedThreatDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 90 }

$ScanPaths = @("$env:SystemRoot\Temp", "$env:SystemRoot\System32\Tasks")
$Extensions = @("*.exe", "*.dll", "*.ps1", "*.vbs")

function Measure-FileEntropy {
    param([string]$FilePath)
    try {
        $bytes = [System.IO.File]::ReadAllBytes($FilePath)
        if ($bytes.Length -eq 0) { return 0 }
        $sample = if ($bytes.Length -gt 4096) { $bytes[0..4095] } else { $bytes }
        $freq = @{}
        foreach ($b in $sample) {
            if (-not $freq.ContainsKey($b)) { $freq[$b] = 0 }
            $freq[$b]++
        }
        $entropy = 0
        foreach ($c in $freq.Values) {
            $p = $c / $sample.Count
            $entropy -= $p * [Math]::Log($p, 2)
        }
        return $entropy
    } catch { return 0 }
}

function Invoke-AdvancedThreatScan {
    $detections = @()
    foreach ($basePath in $ScanPaths) {
        if (-not (Test-Path $basePath)) { continue }
        foreach ($ext in $Extensions) {
            try {
                Get-ChildItem -Path $basePath -Filter $ext -File -ErrorAction SilentlyContinue | ForEach-Object {
                    $ent = Measure-FileEntropy -FilePath $_.FullName
                    if ($ent -gt 7.5) {
                        $detections += @{
                            Path = $_.FullName
                            Entropy = [Math]::Round($ent, 2)
                            Type = "High-Entropy File"
                            Risk = "High"
                        }
                    }
                }
            } catch { }
        }
    }
    
    if ($detections.Count -gt 0) {
        $logPath = "$env:ProgramData\Antivirus\Logs\advanced_threat_detection_$(Get-Date -Format 'yyyy-MM-dd').log"
        $detections | ForEach-Object {
            "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Path)|Entropy:$($_.Entropy)" | Add-Content -Path $logPath
            Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2091 -Message "ADVANCED THREAT: $($_.Path)" -ErrorAction SilentlyContinue
        }
        Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) high-entropy files"
    }
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $script:LastTick = $now
                Invoke-AdvancedThreatScan | Out-Null
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- FirewallRuleMonitoring ---
# Firewall Rule Monitoring Module
# Monitors firewall rules for suspicious changes

$ModuleName = "FirewallRuleMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }
$BaselineRules = @{}

function Initialize-FirewallBaseline {
    try {
        $rules = Get-NetFirewallRule -ErrorAction SilentlyContinue
        
        foreach ($rule in $rules) {
            $key = "$($rule.Name)|$($rule.Direction)|$($rule.Action)"
            if (-not $BaselineRules.ContainsKey($key)) {
                $BaselineRules[$key] = @{
                    Name = $rule.Name
                    Direction = $rule.Direction
                    Action = $rule.Action
                    Enabled = $rule.Enabled
                    FirstSeen = Get-Date
                }
            }
        }
    } catch { }
}

function Invoke-FirewallRuleMonitoring {
    $detections = @()
    
    try {
        # Get current firewall rules
        $rules = Get-NetFirewallRule -ErrorAction SilentlyContinue
        
        # Check for new or modified rules
        foreach ($rule in $rules) {
            $key = "$($rule.Name)|$($rule.Direction)|$($rule.Action)"
            
            if (-not $BaselineRules.ContainsKey($key)) {
                # New rule detected
                $detections += @{
                    RuleName = $rule.Name
                    Direction = $rule.Direction
                    Action = $rule.Action
                    Enabled = $rule.Enabled
                    Type = "New Firewall Rule"
                    Risk = "Medium"
                }
                
                # Update baseline
                $BaselineRules[$key] = @{
                    Name = $rule.Name
                    Direction = $rule.Direction
                    Action = $rule.Action
                    Enabled = $rule.Enabled
                    FirstSeen = Get-Date
                }
            } else {
                # Check if rule was modified
                $baseline = $BaselineRules[$key]
                if ($rule.Enabled -ne $baseline.Enabled) {
                    $detections += @{
                        RuleName = $rule.Name
                        OldState = $baseline.Enabled
                        NewState = $rule.Enabled
                        Type = "Firewall Rule State Changed"
                        Risk = "High"
                    }
                    
                    $baseline.Enabled = $rule.Enabled
                }
            }
        }
        
        # Check for suspicious firewall rules
        foreach ($rule in $rules) {
            try {
                $ruleFilters = Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $rule -ErrorAction SilentlyContinue
                $ruleAppFilters = Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $rule -ErrorAction SilentlyContinue
                
                # Check for rules allowing all traffic
                if ($ruleFilters) {
                    if ($ruleFilters.RemoteAddress -eq "*" -and $rule.Action -eq "Allow") {
                        $detections += @{
                            RuleName = $rule.Name
                            RemoteAddress = $ruleFilters.RemoteAddress
                            Type = "Firewall Rule Allows All Traffic"
                            Risk = "High"
                        }
                    }
                }
                
                # Check for rules allowing unsigned applications
                if ($ruleAppFilters -and $ruleAppFilters.Program) {
                    foreach ($program in $ruleAppFilters.Program) {
                        if ($program -and (Test-Path $program)) {
                            $sig = Get-AuthenticodeSignature -FilePath $program -ErrorAction SilentlyContinue
                            if ($sig.Status -ne "Valid" -and $rule.Action -eq "Allow") {
                                $detections += @{
                                    RuleName = $rule.Name
                                    Program = $program
                                    Type = "Firewall Rule Allows Unsigned Application"
                                    Risk = "Medium"
                                }
                            }
                        }
                    }
                }
                
                # Check for rules with unusual port ranges
                $portFilters = Get-NetFirewallPortFilter -AssociatedNetFirewallRule $rule -ErrorAction SilentlyContinue
                if ($portFilters) {
                    if ($portFilters.LocalPort -eq "*" -or 
                        ($portFilters.LocalPort -is [Array] -and $portFilters.LocalPort.Count -gt 100)) {
                        $detections += @{
                            RuleName = $rule.Name
                            LocalPort = $portFilters.LocalPort
                            Type = "Firewall Rule with Unusual Port Range"
                            Risk = "Medium"
                        }
                    }
                }
            } catch {
                continue
            }
        }
        
        # Check for firewall service status
        try {
            $fwService = Get-CimInstance Win32_Service -Filter "Name='MpsSvc'" -ErrorAction SilentlyContinue
            
            if ($fwService -and $fwService.State -ne "Running") {
                $detections += @{
                    ServiceState = $fwService.State
                    Type = "Windows Firewall Service Not Running"
                    Risk = "Critical"
                }
            }
        } catch { }
        
        # Check for firewall profiles
        try {
            $profiles = Get-NetFirewallProfile -ErrorAction SilentlyContinue
            
            foreach ($profile in $profiles) {
                if ($profile.Enabled -eq $false) {
                    $detections += @{
                        ProfileName = $profile.Name
                        Type = "Firewall Profile Disabled"
                        Risk = "Critical"
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2024 `
                    -Message "FIREWALL RULE MONITORING: $($detection.Type) - $($detection.RuleName -or $detection.ProfileName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\FirewallRule_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.RuleName -or $_.ProfileName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) firewall rule anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    Initialize-FirewallBaseline
    Start-Sleep -Seconds 10
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-FirewallRuleMonitoring
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- ServiceMonitoring ---
# Service Monitoring Module
# Monitors Windows services for suspicious activity

$ModuleName = "ServiceMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }
$BaselineServices = @{}

function Initialize-ServiceBaseline {
    try {
        $services = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue
        
        foreach ($svc in $services) {
            $key = "$($svc.Name)|$($svc.PathName)"
            if (-not $BaselineServices.ContainsKey($key)) {
                $BaselineServices[$key] = @{
                    Name = $svc.Name
                    DisplayName = $svc.DisplayName
                    PathName = $svc.PathName
                    State = $svc.State
                    StartMode = $svc.StartMode
                    StartName = $svc.StartName
                    FirstSeen = Get-Date
                }
            }
        }
    } catch { }
}

function Invoke-ServiceMonitoring {
    $detections = @()
    
    try {
        $services = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue
        
        foreach ($svc in $services) {
            $key = "$($svc.Name)|$($svc.PathName)"
            
            # Check for new services
            if (-not $BaselineServices.ContainsKey($key)) {
                $detections += @{
                    ServiceName = $svc.Name
                    DisplayName = $svc.DisplayName
                    PathName = $svc.PathName
                    State = $svc.State
                    StartMode = $svc.StartMode
                    Type = "New Service Detected"
                    Risk = "High"
                }
                
                # Update baseline
                $BaselineServices[$key] = @{
                    Name = $svc.Name
                    DisplayName = $svc.DisplayName
                    PathName = $svc.PathName
                    State = $svc.State
                    StartMode = $svc.StartMode
                    StartName = $svc.StartName
                    FirstSeen = Get-Date
                }
            } else {
                # Check for service state changes
                $baseline = $BaselineServices[$key]
                if ($svc.State -ne $baseline.State) {
                    $detections += @{
                        ServiceName = $svc.Name
                        OldState = $baseline.State
                        NewState = $svc.State
                        Type = "Service State Changed"
                        Risk = "Medium"
                    }
                    $baseline.State = $svc.State
                }
            }
            
            # Check for suspicious service properties
            if ($svc.PathName -and (Test-Path $svc.PathName)) {
                # Check for unsigned service executables
                $sig = Get-AuthenticodeSignature -FilePath $svc.PathName -ErrorAction SilentlyContinue
                if ($sig.Status -ne "Valid") {
                    $detections += @{
                        ServiceName = $svc.Name
                        PathName = $svc.PathName
                        Type = "Unsigned Service Executable"
                        Risk = "High"
                    }
                }
                
                # Check for services not in system directories
                if ($svc.PathName -notlike "$env:SystemRoot\*" -and 
                    $svc.PathName -notlike "$env:ProgramFiles*") {
                    $detections += @{
                        ServiceName = $svc.Name
                        PathName = $svc.PathName
                        Type = "Service Executable Outside System/Program Directories"
                        Risk = "Medium"
                    }
                }
                
                # Check for services with suspicious command line arguments
                if ($svc.PathName -match 'powershell|cmd|wscript|cscript|http') {
                    $detections += @{
                        ServiceName = $svc.Name
                        PathName = $svc.PathName
                        Type = "Service with Suspicious Command Line"
                        Risk = "High"
                    }
                }
            }
            
            # Check for services running as SYSTEM with suspicious paths
            if ($svc.StartName -eq "LocalSystem" -or $svc.StartName -eq "NT AUTHORITY\SYSTEM") {
                if ($svc.PathName -notlike "$env:SystemRoot\*") {
                    $detections += @{
                        ServiceName = $svc.Name
                        StartName = $svc.StartName
                        PathName = $svc.PathName
                        Type = "SYSTEM Service Outside System Directory"
                        Risk = "Critical"
                    }
                }
            }
            
            # Check for services with unusual display names
            if ($svc.DisplayName -match 'update|installer|system|security|windows' -and
                $svc.Name -notmatch '^[A-Z][a-z]') {
                # Suspicious display name pattern
                $detections += @{
                    ServiceName = $svc.Name
                    DisplayName = $svc.DisplayName
                    Type = "Service with Suspicious Display Name"
                    Risk = "Medium"
                }
            }
        }
        
        # Check for stopped critical services
        $criticalServices = @("WinDefend", "SecurityHealthService", "MpsSvc", "BITS")
        foreach ($criticalSvc in $criticalServices) {
            $svc = $services | Where-Object { $_.Name -eq $criticalSvc } | Select-Object -First 1
            if ($svc -and $svc.State -ne "Running") {
                $detections += @{
                    ServiceName = $svc.Name
                    State = $svc.State
                    Type = "Critical Service Stopped"
                    Risk = "High"
                }
            }
        }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2025 `
                    -Message "SERVICE MONITORING: $($detection.Type) - $($detection.ServiceName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\ServiceMonitoring_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ServiceName)|$($_.PathName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) service anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    Initialize-ServiceBaseline
    Start-Sleep -Seconds 10
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ServiceMonitoring
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- FilelessDetection ---
# Fileless Malware Detection Module
# Detects fileless malware techniques

$ModuleName = "FilelessDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 20 }

function Invoke-FilelessDetection {
    $detections = @()
    
    try {
        # Check for PowerShell in memory execution
        $psProcesses = Get-Process -Name "powershell*","pwsh*" -ErrorAction SilentlyContinue
        
        foreach ($psProc in $psProcesses) {
            try {
                $commandLine = (Get-CimInstance Win32_Process -Filter "ProcessId=$($psProc.Id)").CommandLine
                
                if ($commandLine) {
                    # Check for encoded commands
                    if ($commandLine -match '-encodedcommand|-enc|-e\s+[A-Za-z0-9+/=]{100,}') {
                        $detections += @{
                            ProcessId = $psProc.Id
                            ProcessName = $psProc.ProcessName
                            CommandLine = $commandLine
                            Type = "PowerShell Encoded Command Execution"
                            Risk = "High"
                        }
                    }
                    
                    # Check for IEX/Invoke-Expression usage
                    if ($commandLine -match '(?i)(iex|invoke-expression|invoke-expression)') {
                        $detections += @{
                            ProcessId = $psProc.Id
                            ProcessName = $psProc.ProcessName
                            CommandLine = $commandLine
                            Type = "PowerShell IEX Execution"
                            Risk = "High"
                        }
                    }
                    
                    # Check for download and execute
                    if ($commandLine -match '(?i)(downloadstring|downloadfile|webclient|invoke-webrequest).*(http|https|ftp)') {
                        $detections += @{
                            ProcessId = $psProc.Id
                            ProcessName = $psProc.ProcessName
                            CommandLine = $commandLine
                            Type = "PowerShell Download and Execute"
                            Risk = "Critical"
                        }
                    }
                }
            } catch {
                continue
            }
        }
        
        # Check for WMI event consumers (fileless persistence)
        try {
            $wmiConsumers = Get-CimInstance -Namespace root\subscription -ClassName __EventConsumer -ErrorAction SilentlyContinue
            
            foreach ($consumer in $wmiConsumers) {
                if ($consumer.__CLASS -match 'ActiveScript|CommandLine') {
                    $detections += @{
                        ConsumerName = $consumer.Name
                        ConsumerClass = $consumer.__CLASS
                        Type = "WMI Fileless Persistence"
                        Risk = "High"
                    }
                }
            }
        } catch { }
        
        # Check for Registry-based fileless execution
        try {
            $regKeys = @(
                "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
                "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
            )
            
            foreach ($regKey in $regKeys) {
                if (Test-Path $regKey) {
                    $values = Get-ItemProperty -Path $regKey -ErrorAction SilentlyContinue
                    if ($values) {
                        $valueProps = $values.PSObject.Properties | Where-Object {
                            $_.Name -notin @('PSPath','PSParentPath','PSChildName','PSDrive','PSProvider')
                        }
                        
                        foreach ($prop in $valueProps) {
                            $value = $prop.Value
                            
                            # Check for registry-based script execution
                            if ($value -match 'powershell.*-enc|wscript|javascript|vbscript' -and
                                -not (Test-Path $value)) {
                                $detections += @{
                                    RegistryPath = $regKey
                                    ValueName = $prop.Name
                                    Value = $value
                                    Type = "Registry-Based Fileless Execution"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                }
            }
        } catch { }
        
        # Check for .NET reflection-based execution
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $modules = $proc.Modules | Where-Object {
                        $_.ModuleName -match 'System\.Reflection|System\.CodeDom'
                    }
                    
                    if ($modules.Count -gt 0) {
                        # Check for unsigned processes using reflection
                        if ($proc.Path -and (Test-Path $proc.Path)) {
                            $sig = Get-AuthenticodeSignature -FilePath $proc.Path -ErrorAction SilentlyContinue
                            if ($sig.Status -ne "Valid") {
                                $detections += @{
                                    ProcessId = $proc.Id
                                    ProcessName = $proc.ProcessName
                                    ReflectionModules = $modules.ModuleName -join ','
                                    Type = "Unsigned Process Using Reflection"
                                    Risk = "Medium"
                                }
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for memory-only modules
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $modules = $proc.Modules | Where-Object {
                        $_.FileName -notlike "$env:SystemRoot\*" -and
                        $_.FileName -notlike "$env:ProgramFiles*" -and
                        -not (Test-Path $_.FileName)
                    }
                    
                    if ($modules.Count -gt 5) {
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            MemoryModules = $modules.Count
                            Type = "Process with Many Memory-Only Modules"
                            Risk = "High"
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check Event Log for fileless execution indicators
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'} -ErrorAction SilentlyContinue -MaxEvents 200 |
                Where-Object {
                    $_.Message -match 'encodedcommand|iex|invoke-expression|downloadstring'
                }
            
            foreach ($event in $events) {
                $detections += @{
                    EventId = $event.Id
                    TimeCreated = $event.TimeCreated
                    Message = $event.Message
                    Type = "Event Log Fileless Execution Indicator"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2026 `
                    -Message "FILELESS DETECTION: $($detection.Type) - $($detection.ProcessName -or $detection.ConsumerName -or $detection.ValueName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\FilelessDetection_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.ConsumerName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) fileless malware indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-FilelessDetection
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- MemoryScanning ---
# Optimized Memory Scanning Module
# Reduced CPU/RAM/Disk usage with caching and batching


$ModuleName = "MemoryScanning"
$script:LastTick = Get-Date
$TickInterval = Get-TickInterval -ModuleName $ModuleName

$script:ProcessBaseline = @{}
$script:LastBaselineUpdate = Get-Date

function Update-ProcessBaseline {
    $now = Get-Date
    if (($now - $script:LastBaselineUpdate).TotalMinutes -lt 5) {
        return
    }
    
    $script:LastBaselineUpdate = $now
    $maxProcs = Get-ScanLimit -LimitName "MaxProcesses"
    
    try {
        $processes = Get-Process -ErrorAction SilentlyContinue | 
            Where-Object { $_.WorkingSet64 -gt 10MB } |
            Select-Object -First $maxProcs
        
        foreach ($proc in $processes) {
            $key = "$($proc.ProcessName)|$($proc.Id)"
            if (-not $script:ProcessBaseline.ContainsKey($key)) {
                $script:ProcessBaseline[$key] = @{
                    FirstSeen = $now
                    Scanned = $false
                }
            }
        }
        
        $toRemove = @()
        foreach ($key in $script:ProcessBaseline.Keys) {
            $pid = $key.Split('|')[1]
            try {
                $null = Get-Process -Id $pid -ErrorAction Stop
            } catch {
                $toRemove += $key
            }
        }
        foreach ($key in $toRemove) {
            $script:ProcessBaseline.Remove($key)
        }
    } catch { }
}

function Invoke-MemoryScanningOptimized {
    $detections = @()
    $batchSettings = Get-BatchSettings
    $maxProcs = Get-ScanLimit -LimitName "MaxProcesses"
    
    try {
        Update-ProcessBaseline
        
        $processes = Get-Process -ErrorAction SilentlyContinue |
            Where-Object { $_.WorkingSet64 -gt 10MB } |
            Select-Object -First $maxProcs
        
        $batchCount = 0
        foreach ($proc in $processes) {
            try {
                $key = "$($proc.ProcessName)|$($proc.Id)"
                
                if ($script:ProcessBaseline.ContainsKey($key) -and $script:ProcessBaseline[$key].Scanned) {
                    continue
                }
                
                $batchCount++
                if ($batchCount % $batchSettings.BatchSize -eq 0 -and $batchSettings.BatchDelayMs -gt 0) {
                    Start-Sleep -Milliseconds $batchSettings.BatchDelayMs
                }
                
                $modules = $proc.Modules | Where-Object {
                    $_.FileName -notlike "$env:SystemRoot\*" -and
                    $_.FileName -notlike "$env:ProgramFiles*"
                }
                
                if ($modules.Count -gt 5) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        SuspiciousModules = $modules.Count
                        Type = "Process with Many Non-System Modules"
                        Risk = "Medium"
                    }
                }
                
                if ($script:ProcessBaseline.ContainsKey($key)) {
                    $script:ProcessBaseline[$key].Scanned = $true
                }
                
            } catch {
                continue
            }
        }
        
        $now = Get-Date
        foreach ($key in $script:ProcessBaseline.Keys) {
            if (($now - $script:ProcessBaseline[$key].FirstSeen).TotalSeconds -gt $TickInterval) {
                $script:ProcessBaseline[$key].Scanned = $false
                $script:ProcessBaseline[$key].FirstSeen = $now
            }
        }
        
        if ($detections.Count -gt 0) {
            $logPath = "$env:ProgramData\Antivirus\Logs\MemoryScanning_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName)|$($_.ProcessId)" |
                    Add-Content -Path $logPath
            }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) memory anomalies"
        }
        
        Write-Output "STATS:$ModuleName`:Scanned $($processes.Count) processes"
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    Clear-ExpiredCache
    
    return $detections.Count
}

function Start-Module {

    $loopSleep = Get-LoopSleep
    
    while ($true) {
        try {
            # CPU throttling - skip scan if CPU load is too high
            if (Test-CPULoadThreshold) {
                $cpuLoad = Get-CPULoad
                Write-Output "STATS:$ModuleName`:CPU load too high ($cpuLoad%), skipping scan"
                Start-Sleep -Seconds ($loopSleep * 2)  # Sleep longer when CPU is high
                continue
            }
            
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-MemoryScanningOptimized
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 120  # Longer sleep on error
        }
    }
}

# --- NamedPipeMonitoring ---
# Named Pipe Monitoring Module
# Monitors named pipes for malicious activity

$ModuleName = "NamedPipeMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Invoke-NamedPipeMonitoring {
    $detections = @()
    
    try {
        # Get named pipes using WMI
        $pipes = Get-CimInstance Win32_NamedPipe -ErrorAction SilentlyContinue
        
        # Check for suspicious named pipes
        $suspiciousPatterns = @(
            "paexec",
            "svchost",
            "lsass",
            "spoolsv",
            "psexec",
            "mimikatz",
            "impacket"
        )
        
        foreach ($pipe in $pipes) {
            $pipeNameLower = $pipe.Name.ToLower()
            
            foreach ($pattern in $suspiciousPatterns) {
                if ($pipeNameLower -match $pattern) {
                    $detections += @{
                        PipeName = $pipe.Name
                        Pattern = $pattern
                        Type = "Suspicious Named Pipe Pattern"
                        Risk = "Medium"
                    }
                    break
                }
            }
            
            # Check for pipes with unusual names (random characters)
            if ($pipe.Name -match '^[A-Za-z0-9]{32,}$' -and 
                $pipe.Name -notmatch 'microsoft|windows|system') {
                $detections += @{
                    PipeName = $pipe.Name
                    Type = "Named Pipe with Random-Like Name"
                    Risk = "Low"
                }
            }
        }
        
        # Check for processes creating named pipes
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $procPipes = $pipes | Where-Object {
                        $_.Instances -gt 0
                    }
                    
                    # Check for processes creating many named pipes
                    $pipeCount = ($procPipes | Measure-Object).Count
                    
                    if ($pipeCount -gt 10 -and 
                        $proc.ProcessName -notin @("svchost.exe", "spoolsv.exe", "services.exe")) {
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            PipeCount = $pipeCount
                            Type = "Process Creating Many Named Pipes"
                            Risk = "Medium"
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check Event Log for named pipe errors
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='System'} -ErrorAction SilentlyContinue -MaxEvents 200 |
                Where-Object { 
                    $_.Message -match 'named.*pipe|pipe.*error|pipe.*failed'
                }
            
            $pipeErrors = $events | Where-Object {
                $_.LevelDisplayName -eq "Error"
            }
            
            if ($pipeErrors.Count -gt 5) {
                $detections += @{
                    EventCount = $pipeErrors.Count
                    Type = "Excessive Named Pipe Errors"
                    Risk = "Low"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Information -EventId 2028 `
                    -Message "NAMED PIPE MONITORING: $($detection.Type) - $($detection.PipeName -or $detection.ProcessName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\NamedPipe_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.PipeName -or $_.ProcessName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) named pipe anomalies"
        }
        
        Write-Output "STATS:$ModuleName`:Active pipes=$($pipes.Count)"
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-NamedPipeMonitoring
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- CodeInjectionDetection ---
# Code Injection Detection Module
# Detects various code injection techniques

$ModuleName = "CodeInjectionDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-CodeInjectionDetection {
    $detections = @()
    
    try {
        # Check for processes with unusual memory regions (injection indicator)
        $processes = Get-Process -ErrorAction SilentlyContinue
        
        foreach ($proc in $processes) {
            try {
                $modules = $proc.Modules
                
                # Check for RWX memory regions (code injection indicator)
                # We'll use heuristics since we can't directly query memory protection
                
                # Check for processes with modules in unusual locations
                $unusualModules = $modules | Where-Object {
                    $_.FileName -notlike "$env:SystemRoot\*" -and
                    $_.FileName -notlike "$env:ProgramFiles*" -and
                    -not (Test-Path $_.FileName) -and
                    $_.ModuleName -like "*.dll"
                }
                
                if ($unusualModules.Count -gt 5) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        UnusualModules = $unusualModules.Count
                        Type = "Many Unusual Memory Modules (Code Injection)"
                        Risk = "High"
                    }
                }
                
                # Check for processes with unusual thread counts (injection indicator)
                if ($proc.Threads.Count -gt 50 -and $proc.ProcessName -notin @("chrome.exe", "msedge.exe", "firefox.exe")) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        ThreadCount = $proc.Threads.Count
                        Type = "Unusual Thread Count (Possible Injection)"
                        Risk = "Medium"
                    }
                }
            } catch {
                continue
            }
        }
        
        # Check for processes using injection APIs
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine
            
            foreach ($proc in $processes) {
                if ($proc.CommandLine) {
                    # Check for code injection API usage
                    $injectionPatterns = @(
                        'VirtualAllocEx',
                        'WriteProcessMemory',
                        'CreateRemoteThread',
                        'NtCreateThreadEx',
                        'RtlCreateUserThread',
                        'SetThreadContext',
                        'QueueUserAPC',
                        'ProcessHollowing',
                        'DLL.*injection',
                        'code.*injection'
                    )
                    
                    foreach ($pattern in $injectionPatterns) {
                        if ($proc.CommandLine -match $pattern) {
                            $detections += @{
                                ProcessId = $proc.ProcessId
                                ProcessName = $proc.Name
                                CommandLine = $proc.CommandLine
                                InjectionPattern = $pattern
                                Type = "Code Injection API Usage"
                                Risk = "High"
                            }
                            break
                        }
                    }
                }
            }
        } catch { }
        
        # Check for processes with unusual handle counts (injection indicator)
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue |
                Where-Object { $_.HandleCount -gt 1000 }
            
            foreach ($proc in $processes) {
                # Exclude legitimate processes
                $legitProcesses = @("chrome.exe", "msedge.exe", "firefox.exe", "explorer.exe", "svchost.exe")
                if ($proc.ProcessName -notin $legitProcesses) {
                    $detections += @{
                        ProcessId = $proc.Id
                        ProcessName = $proc.ProcessName
                        HandleCount = $proc.HandleCount
                        Type = "Unusual Handle Count (Possible Injection)"
                        Risk = "Medium"
                    }
                }
            }
        } catch { }
        
        # Check for processes accessing other processes (injection indicator)
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ExecutablePath
            
            foreach ($proc in $processes) {
                try {
                    # Check if process has SeDebugPrivilege (enables injection)
                    # Indirect check through process properties
                    if ($proc.ExecutablePath -and (Test-Path $proc.ExecutablePath)) {
                        $sig = Get-AuthenticodeSignature -FilePath $proc.ExecutablePath -ErrorAction SilentlyContinue
                        
                        # Unsigned processes accessing system processes
                        if ($sig.Status -ne "Valid" -and $proc.Name -match 'debug|inject|hollow') {
                            $detections += @{
                                ProcessId = $proc.ProcessId
                                ProcessName = $proc.Name
                                ExecutablePath = $proc.ExecutablePath
                                Type = "Suspicious Process Name (Injection Tool)"
                                Risk = "High"
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2038 `
                    -Message "CODE INJECTION: $($detection.Type) - $($detection.ProcessName) (PID: $($detection.ProcessId))"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\CodeInjection_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|PID:$($_.ProcessId)|$($_.ProcessName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) code injection indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-CodeInjectionDetection
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- DataExfiltrationDetection ---
# Data Exfiltration Detection Module
# Comprehensive data exfiltration detection beyond DNS

$ModuleName = "DataExfiltrationDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }
$BaselineTransfer = @{}

function Invoke-DataExfiltrationDetection {
    $detections = @()
    
    try {
        # Check for large outbound data transfers
        try {
            $connections = Get-NetTCPConnection -ErrorAction SilentlyContinue |
                Where-Object { $_.State -eq "Established" -and $_.RemoteAddress -notmatch '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)' }
            
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $procConns = $connections | Where-Object { $_.OwningProcess -eq $proc.Id }
                    
                    if ($procConns.Count -gt 0) {
                        # Check network statistics
                        $netStats = Get-Counter "\Process($($proc.ProcessName))\IO Data Bytes/sec" -ErrorAction SilentlyContinue
                        if ($netStats) {
                            $bytesPerSec = $netStats.CounterSamples[0].CookedValue
                            
                            # Large outbound transfer
                            if ($bytesPerSec -gt 1MB) {
                                $baselineKey = $proc.ProcessName
                                $baseline = if ($BaselineTransfer.ContainsKey($baselineKey)) { $BaselineTransfer[$baselineKey] } else { 0 }
                                
                                if ($bytesPerSec -gt $baseline * 2 -and $bytesPerSec -gt 1MB) {
                                    $detections += @{
                                        ProcessId = $proc.Id
                                        ProcessName = $proc.ProcessName
                                        BytesPerSecond = [Math]::Round($bytesPerSec / 1MB, 2)
                                        ConnectionCount = $procConns.Count
                                        Type = "Large Outbound Data Transfer"
                                        Risk = "High"
                                    }
                                }
                                
                                $BaselineTransfer[$baselineKey] = $bytesPerSec
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for file uploads to cloud storage/suspicious domains
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue |
                Where-Object { $_.ProcessName -match 'curl|wget|powershell|certutil|bitsadmin' }
            
            foreach ($proc in $processes) {
                try {
                    $procObj = Get-CimInstance Win32_Process -Filter "ProcessId=$($proc.Id)" -ErrorAction SilentlyContinue
                    
                    if ($procObj.CommandLine) {
                        $uploadPatterns = @(
                            'upload|PUT|POST',
                            'dropbox|google.*drive|onedrive|mega|wetransfer',
                            'pastebin|github|paste.*bin',
                            'http.*upload|ftp.*put',
                            '-OutFile.*http',
                            'Invoke-WebRequest.*-Method.*Put'
                        )
                        
                        foreach ($pattern in $uploadPatterns) {
                            if ($procObj.CommandLine -match $pattern -and 
                                $procObj.CommandLine -notmatch 'download|get|GET') {
                                $detections += @{
                                    ProcessId = $proc.Id
                                    ProcessName = $proc.ProcessName
                                    CommandLine = $procObj.CommandLine
                                    Pattern = $pattern
                                    Type = "File Upload to External Service"
                                    Risk = "High"
                                }
                                break
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for clipboard with large data (possible exfiltration)
        try {
            Add-Type -AssemblyName System.Windows.Forms
            
            if ([System.Windows.Forms.Clipboard]::ContainsText()) {
                $clipboardText = [System.Windows.Forms.Clipboard]::GetText()
                
                if ($clipboardText.Length -gt 50000) {
                    # Large clipboard content
                    $detections += @{
                        ClipboardSize = $clipboardText.Length
                        Type = "Large Clipboard Content (Possible Exfiltration)"
                        Risk = "Medium"
                    }
                }
            }
        } catch { }
        
        # Check for processes accessing many files then connecting externally
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    $handles = Get-CimInstance Win32_ProcessHandle -Filter "ProcessId=$($proc.Id)" -ErrorAction SilentlyContinue
                    $fileHandles = $handles | Where-Object { $_.Name -like "*.txt" -or $_.Name -like "*.doc*" -or $_.Name -like "*.pdf" -or $_.Name -like "*.xls*" }
                    
                    if ($fileHandles.Count -gt 20) {
                        $conns = Get-NetTCPConnection -OwningProcess $proc.Id -ErrorAction SilentlyContinue |
                            Where-Object { 
                                $_.State -eq "Established" -and 
                                $_.RemoteAddress -notmatch '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)'
                            }
                        
                        if ($conns.Count -gt 0) {
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                FileHandleCount = $fileHandles.Count
                                ExternalConnections = $conns.Count
                                Type = "File Access Followed by External Connection"
                                Risk = "High"
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for processes reading sensitive files then connecting externally
        try {
            $sensitivePaths = @(
                "$env:USERPROFILE\Documents",
                "$env:USERPROFILE\Desktop",
                "$env:APPDATA\..\Local\Credentials"
            )
            
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                try {
                    foreach ($sensitivePath in $sensitivePaths) {
                        if (Test-Path $sensitivePath) {
                            $files = Get-ChildItem -Path $sensitivePath -File -ErrorAction SilentlyContinue |
                                Where-Object { (Get-Date) - $_.LastAccessTime -lt [TimeSpan]::FromMinutes(5) }
                            
                            if ($files.Count -gt 5) {
                                $conns = Get-NetTCPConnection -OwningProcess $proc.Id -ErrorAction SilentlyContinue |
                                    Where-Object { $_.State -eq "Established" -and $_.RemoteAddress -notmatch '^(10\.|192\.168\.)' }
                                
                                if ($conns.Count -gt 0) {
                                    $detections += @{
                                        ProcessId = $proc.Id
                                        ProcessName = $proc.ProcessName
                                        SensitiveFilesAccessed = $files.Count
                                        ExternalConnections = $conns.Count
                                        Type = "Sensitive File Access Followed by External Connection"
                                        Risk = "Critical"
                                    }
                                    break
                                }
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2040 `
                    -Message "DATA EXFILTRATION: $($detection.Type) - $($detection.ProcessName -or 'System')"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\DataExfiltration_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) data exfiltration indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-DataExfiltrationDetection
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- HoneypotMonitoring ---
# Honeypot Monitoring
# Creates decoy files and processes to detect unauthorized access

$ModuleName = "HoneypotMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 300 }
$HoneypotFiles = @()
$HoneypotPaths = @(
    "$env:USERPROFILE\Desktop\passwords.txt",
    "$env:USERPROFILE\Documents\credentials.xlsx",
    "$env:USERPROFILE\Documents\credit_cards.txt",
    "$env:USERPROFILE\Desktop\private_keys.txt",
    "$env:APPDATA\credentials.db",
    "$env:USERPROFILE\Documents\financial_data.xlsx"
)

function Initialize-Honeypots {
    try {
        foreach ($honeypotPath in $HoneypotPaths) {
            $dir = Split-Path -Parent $honeypotPath
            if (-not (Test-Path $dir)) {
                New-Item -Path $dir -ItemType Directory -Force -ErrorAction SilentlyContinue | Out-Null
            }
            
            if (-not (Test-Path $honeypotPath)) {
                # Create honeypot file with fake but realistic content
                $content = switch -Wildcard ([System.IO.Path]::GetFileName($honeypotPath)) {
                    "*password*" { "FAKE_PASSWORD_FILE_DO_NOT_USE`r`nusername: admin`r`npassword: fake_password_123`r`nLastModified: $(Get-Date -Format 'yyyy-MM-dd')" }
                    "*credential*" { "FAKE_CREDENTIAL_FILE_DO_NOT_USE`r`nAccount: fake_account`r`nPassword: fake_pass_123`r`nCreated: $(Get-Date -Format 'yyyy-MM-dd')" }
                    "*credit*" { "FAKE_CREDIT_CARD_FILE_DO_NOT_USE`r`nCard: 4111-1111-1111-1111`r`nCVV: 123`r`nExpiry: 12/25" }
                    "*key*" { "FAKE_PRIVATE_KEY_FILE_DO_NOT_USE`r`n-----BEGIN FAKE RSA PRIVATE KEY-----`r`nFAKE_KEY_DATA`r`n-----END FAKE RSA PRIVATE KEY-----" }
                    "*financial*" { "FAKE_FINANCIAL_DATA_FILE_DO_NOT_USE`r`nAccount: 123456789`r`nBalance: $0.00`r`nTransaction: None" }
                    default { "FAKE_FILE_DO_NOT_USE - Created: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" }
                }
                
                Set-Content -Path $honeypotPath -Value $content -ErrorAction SilentlyContinue
                
                # Mark as honeypot with file attribute
                try {
                    $file = Get-Item $honeypotPath -ErrorAction Stop
                    $file.Attributes = $file.Attributes -bor [System.IO.FileAttributes]::Hidden
                } catch { }
                
                $script:HoneypotFiles += @{
                    Path = $honeypotPath
                    Created = Get-Date
                    LastAccessed = $null
                    AccessCount = 0
                }
                
                Write-Output "STATS:$ModuleName`:Created honeypot: $honeypotPath"
            }
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:Failed to initialize honeypots: $_"
    }
}

function Invoke-HoneypotMonitoring {
    $detections = @()
    
    try {
        # Check honeypot file access
        foreach ($honeypot in $script:HoneypotFiles) {
            $honeypotPath = $honeypot.Path
            
            if (Test-Path $honeypotPath) {
                try {
                    $file = Get-Item $honeypotPath -ErrorAction Stop
                    $lastAccess = $file.LastAccessTime
                    
                    # Check if file was accessed recently
                    if ($honeypot.LastAccessed -and $lastAccess -gt $honeypot.LastAccessed) {
                        $honeypot.AccessCount++
                        
                        # Detect unauthorized access
                        if ($honeypot.AccessCount -gt 0) {
                            # Find process that accessed the file
                            $accessingProcesses = @()
                            try {
                                $processes = Get-Process -ErrorAction SilentlyContinue
                                
                                foreach ($proc in $processes) {
                                    try {
                                        $procObj = Get-CimInstance Win32_Process -Filter "ProcessId=$($proc.Id)" -ErrorAction SilentlyContinue
                                        
                                        if ($procObj.CommandLine -like "*$([System.IO.Path]::GetFileName($honeypotPath))*") {
                                            $accessingProcesses += $proc.ProcessName
                                        }
                                    } catch { }
                                }
                            } catch { }
                            
                            $detections += @{
                                HoneypotPath = $honeypotPath
                                LastAccess = $lastAccess
                                AccessCount = $honeypot.AccessCount
                                AccessingProcesses = $accessingProcesses -join ','
                                Type = "Honeypot File Accessed"
                                Risk = "Critical"
                            }
                            
                            # Log honeypot trigger
                            Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2041 `
                                -Message "HONEYPOT TRIGGERED: $honeypotPath was accessed - Processes: $($accessingProcesses -join ', ')"
                        }
                        
                        $honeypot.LastAccessed = $lastAccess
                    }
                } catch {
                    # File may have been deleted or moved
                    if (-not $honeypot.LastAccessed -or ((Get-Date) - $honeypot.Created).TotalMinutes -lt 5) {
                        $detections += @{
                            HoneypotPath = $honeypotPath
                            Type = "Honeypot File Deleted/Moved"
                            Risk = "Critical"
                        }
                        
                        Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2041 `
                            -Message "HONEYPOT DELETED: $honeypotPath was deleted or moved"
                        
                        # Recreate honeypot
                        Initialize-Honeypots
                    }
                }
            } else {
                # File doesn't exist - recreate
                Initialize-Honeypots
            }
        }
        
        # Check for processes accessing multiple honeypots (malware scanning)
        if ($detections.Count -gt 2) {
            $detections += @{
                HoneypotCount = $detections.Count
                Type = "Multiple Honeypots Accessed (Systematic Scanning)"
                Risk = "Critical"
            }
        }
        
        if ($detections.Count -gt 0) {
            $logPath = "$env:ProgramData\Antivirus\Logs\Honeypot_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.HoneypotPath)|$($_.AccessingProcesses)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) honeypot access events"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    Initialize-Honeypots
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $count = Invoke-HoneypotMonitoring
                $script:LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- LateralMovementDetection ---
# Lateral Movement Detection Module
# Detects lateral movement techniques (SMB, RDP, WMI, PsExec, etc.)

$ModuleName = "LateralMovementDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }

function Invoke-LateralMovementDetection {
    $detections = @()
    
    try {
        # Check for SMB shares enumeration/access
        try {
            $smbEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=5145} -ErrorAction SilentlyContinue -MaxEvents 100 |
                Where-Object {
                    (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromHours(1) -and
                    $_.Message -match 'SMB|share|\\\\.*\\'
                }
            
            if ($smbEvents.Count -gt 10) {
                $detections += @{
                    EventCount = $smbEvents.Count
                    Type = "Excessive SMB Share Access (Lateral Movement)"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for RDP connections
        try {
            $rdpEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -ErrorAction SilentlyContinue -MaxEvents 200 |
                Where-Object {
                    (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromHours(1) -and
                    $_.Message -match 'RDP|Terminal Services|logon.*type.*10'
                }
            
            if ($rdpEvents.Count -gt 5) {
                foreach ($event in $rdpEvents) {
                    $xml = [xml]$event.ToXml()
                    $subjectUserName = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text'
                    $targetUserName = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text'
                    
                    if ($subjectUserName -ne $targetUserName) {
                        $detections += @{
                            EventId = $event.Id
                            SubjectUser = $subjectUserName
                            TargetUser = $targetUserName
                            TimeCreated = $event.TimeCreated
                            Type = "RDP Lateral Movement"
                            Risk = "High"
                        }
                    }
                }
            }
        } catch { }
        
        # Check for PsExec usage
        try {
            $processes = Get-CimInstance Win32_Process | 
                Where-Object { 
                    $_.Name -eq "psexec.exe" -or 
                    $_.CommandLine -like "*psexec*" -or
                    $_.CommandLine -like "*paexec*"
                }
            
            foreach ($proc in $processes) {
                $detections += @{
                    ProcessId = $proc.ProcessId
                    ProcessName = $proc.Name
                    CommandLine = $proc.CommandLine
                    Type = "PsExec Lateral Movement Tool"
                    Risk = "High"
                }
            }
        } catch { }
        
        # Check for WMI remote execution
        try {
            $wmiEvents = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-WMI-Activity/Trace'} -ErrorAction SilentlyContinue -MaxEvents 100 |
                Where-Object {
                    (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromHours(1) -and
                    ($_.Message -match 'remote|Win32_Process.*Create' -or $_.Message -match '\\\\')
                }
            
            if ($wmiEvents.Count -gt 5) {
                $detections += @{
                    EventCount = $wmiEvents.Count
                    Type = "WMI Remote Execution (Lateral Movement)"
                    Risk = "High"
                }
            }
        } catch { }
        
        # Check for pass-the-hash tools
        try {
            $pthTools = @("mimikatz", "psexec", "wmiexec", "pth-winexe", "crackmapexec")
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                foreach ($tool in $pthTools) {
                    if ($proc.ProcessName -like "*$tool*" -or $proc.Path -like "*$tool*") {
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            Tool = $tool
                            Type = "Pass-the-Hash Tool Detected"
                            Risk = "Critical"
                        }
                    }
                }
            }
        } catch { }
        
        # Check for suspicious network connections to internal IPs
        try {
            $connections = Get-NetTCPConnection -ErrorAction SilentlyContinue |
                Where-Object { 
                    $_.State -eq "Established" -and
                    $_.RemoteAddress -match '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)' -and
                    $_.RemotePort -in @(445, 3389, 135, 5985, 5986)  # SMB, RDP, RPC, WinRM
                }
            
            $procGroups = $connections | Group-Object OwningProcess
            
            foreach ($group in $procGroups) {
                $uniqueIPs = ($group.Group | Select-Object -Unique RemoteAddress).RemoteAddress.Count
                
                if ($uniqueIPs -gt 5) {
                    try {
                        $proc = Get-Process -Id $group.Name -ErrorAction SilentlyContinue
                        if ($proc) {
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                InternalIPCount = $uniqueIPs
                                ConnectionCount = $group.Count
                                Type = "Multiple Internal Network Connections (Lateral Movement)"
                                Risk = "High"
                            }
                        }
                    } catch { }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2039 `
                    -Message "LATERAL MOVEMENT: $($detection.Type) - $($detection.ProcessName -or $detection.Tool -or $detection.SubjectUser)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\LateralMovement_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.Tool -or $_.SubjectUser)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) lateral movement indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-LateralMovementDetection
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- ProcessCreationDetection ---
# Process Creation Detection Module
# Detects WMI-based process creation blocking and suspicious process creation patterns

$ModuleName = "ProcessCreationDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

function Invoke-ProcessCreationDetection {
    $detections = @()
    
    try {
        # Check for WMI process creation filters (blockers)
        try {
            $filters = Get-CimInstance -Namespace root\subscription -ClassName __EventFilter -ErrorAction SilentlyContinue |
                Where-Object { 
                    $_.Query -match 'Win32_ProcessStartTrace|__InstanceCreationEvent.*Win32_Process'
                }
            
            foreach ($filter in $filters) {
                # Check if filter is bound to a consumer that blocks processes
                $bindings = Get-CimInstance -Namespace root\subscription -ClassName __FilterToConsumerBinding -ErrorAction SilentlyContinue |
                    Where-Object { $_.Filter -like "*$($filter.Name)*" }
                
                if ($bindings) {
                    foreach ($binding in $bindings) {
                        $consumer = Get-CimInstance -Namespace root\subscription -ClassName CommandLineEventConsumer -ErrorAction SilentlyContinue |
                            Where-Object { $_.Name -like "*$($binding.Consumer)*" }
                        
                        if ($consumer) {
                            # Check if consumer command blocks process creation
                            if ($consumer.CommandLineTemplate -match 'taskkill|Stop-Process|Remove-Process' -or
                                $consumer.CommandLineTemplate -match 'block|deny|prevent') {
                                $detections += @{
                                    FilterName = $filter.Name
                                    ConsumerName = $consumer.Name
                                    CommandLine = $consumer.CommandLineTemplate
                                    Type = "WMI Process Creation Blocker Detected"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                }
            }
        } catch { }
        
        # Check Event Log for process creation failures
        try {
            $events = Get-WinEvent -FilterHashtable @{LogName='System'; Id=7034} -ErrorAction SilentlyContinue -MaxEvents 100 |
                Where-Object {
                    $_.Message -match 'process.*failed|service.*failed.*start|start.*failed'
                }
            
            $processFailures = $events | Where-Object {
                (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromHours(1)
            }
            
            if ($processFailures.Count -gt 10) {
                $detections += @{
                    EventCount = $processFailures.Count
                    Type = "Excessive Process Creation Failures"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for processes with unusual creation patterns
        try {
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ParentProcessId, CreationDate, ExecutablePath
            
            # Check for processes spawned in rapid succession
            $recentProcs = $processes | Where-Object {
                (Get-Date) - $_.CreationDate -lt [TimeSpan]::FromMinutes(5)
            }
            
            # Group by parent process
            $parentGroups = $recentProcs | Group-Object ParentProcessId
            
            foreach ($group in $parentGroups) {
                if ($group.Count -gt 20) {
                    try {
                        $parent = Get-CimInstance Win32_Process -Filter "ProcessId=$($group.Name)" -ErrorAction SilentlyContinue
                        if ($parent) {
                            $detections += @{
                                ParentProcessId = $group.Name
                                ParentProcessName = $parent.Name
                                ChildCount = $group.Count
                                Type = "Rapid Process Creation Spawning"
                                Risk = "Medium"
                            }
                        }
                    } catch { }
                }
            }
        } catch { }
        
        # Check for processes with unusual parent relationships
        try {
            $suspiciousParents = @{
                "winlogon.exe" = @("cmd.exe", "powershell.exe", "wmic.exe")
                "services.exe" = @("cmd.exe", "powershell.exe", "rundll32.exe")
                "explorer.exe" = @("notepad.exe", "calc.exe")
            }
            
            $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, ParentProcessId
            
            foreach ($proc in $processes) {
                if ($proc.ParentProcessId) {
                    try {
                        $parent = Get-CimInstance Win32_Process -Filter "ProcessId=$($proc.ParentProcessId)" -ErrorAction SilentlyContinue
                        
                        if ($parent) {
                            foreach ($suspParent in $suspiciousParents.Keys) {
                                if ($parent.Name -eq $suspParent -and 
                                    $proc.Name -in $suspiciousParents[$suspParent]) {
                                    
                                    $detections += @{
                                        ProcessId = $proc.ProcessId
                                        ProcessName = $proc.Name
                                        ParentProcessId = $proc.ParentProcessId
                                        ParentProcessName = $parent.Name
                                        Type = "Suspicious Parent-Child Process Relationship"
                                        Risk = "Medium"
                                    }
                                }
                            }
                        }
                    } catch { }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2035 `
                    -Message "PROCESS CREATION: $($detection.Type) - $($detection.ProcessName -or $detection.FilterName -or $detection.ParentProcessName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\ProcessCreation_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.FilterName)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) process creation anomalies"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-ProcessCreationDetection
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- QuarantineManagement ---
# Quarantine Management Module
# Manages file quarantine operations and tracks quarantined files

$ModuleName = "QuarantineManagement"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 300 }
$QuarantinePath = "$env:ProgramData\Antivirus\Quarantine"

function Initialize-Quarantine {
    try {
        if (-not (Test-Path $QuarantinePath)) {
            New-Item -Path $QuarantinePath -ItemType Directory -Force | Out-Null
        }
        
        # Create quarantine log
        $quarantineLog = Join-Path $QuarantinePath "quarantine_log.txt"
        if (-not (Test-Path $quarantineLog)) {
            "Timestamp|FilePath|QuarantinePath|Reason|FileHash" | Add-Content -Path $quarantineLog
        }
        
        return $true
    } catch {
        Write-Output "ERROR:$ModuleName`:Failed to initialize quarantine: $_"
        return $false
    }
}

function Invoke-QuarantineFile {
    param(
        [string]$FilePath,
        [string]$Reason = "Threat Detected",
        [string]$Source = "Unknown"
    )
    
    try {
        if (-not (Test-Path $FilePath)) {
            Write-Output "ERROR:$ModuleName`:File not found: $FilePath"
            return $false
        }
        
        $fileName = Split-Path -Leaf $FilePath
        $fileDir = Split-Path -Parent $FilePath
        $fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($fileName)
        $fileExt = [System.IO.Path]::GetExtension($fileName)
        
        # Generate unique quarantine filename with timestamp
        $timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
        $quarantineFileName = "${fileBaseName}_${timestamp}${fileExt}"
        $quarantineFilePath = Join-Path $QuarantinePath $quarantineFileName
        
        # Calculate file hash before moving
        $fileHash = $null
        try {
            $hashObj = Get-FileHash -Path $FilePath -Algorithm SHA256 -ErrorAction SilentlyContinue
            $fileHash = $hashObj.Hash
        } catch { }
        
        # Move file to quarantine
        Move-Item -Path $FilePath -Destination $quarantineFilePath -Force -ErrorAction Stop
        
        # Log quarantine action
        $quarantineLog = Join-Path $QuarantinePath "quarantine_log.txt"
        $logEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$FilePath|$quarantineFilePath|$Reason|$fileHash"
        Add-Content -Path $quarantineLog -Value $logEntry
        
        # Write Event Log
        Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2034 `
            -Message "QUARANTINE: File quarantined: $fileName - Reason: $Reason - Source: $Source"
        
        Write-Output "STATS:$ModuleName`:File quarantined: $fileName"
        return $true
    } catch {
        Write-Output "ERROR:$ModuleName`:Failed to quarantine $FilePath`: $_"
        return $false
    }
}

function Invoke-QuarantineManagement {
    $stats = @{
        QuarantinedFiles = 0
        QuarantineSize = 0
        OldFiles = 0
    }
    
    try {
        # Initialize quarantine if needed
        if (-not (Test-Path $QuarantinePath)) {
            Initialize-Quarantine
        }
        
        # Check quarantine status
        if (Test-Path $QuarantinePath) {
            $quarantinedFiles = Get-ChildItem -Path $QuarantinePath -File -ErrorAction SilentlyContinue |
                Where-Object { $_.Name -ne "quarantine_log.txt" }
            
            $stats.QuarantinedFiles = $quarantinedFiles.Count
            
            # Calculate total quarantine size
            foreach ($file in $quarantinedFiles) {
                $stats.QuarantineSize += $file.Length
            }
            
            # Check for old quarantined files (older than 90 days)
            $cutoffDate = (Get-Date).AddDays(-90)
            $oldFiles = $quarantinedFiles | Where-Object { $_.LastWriteTime -lt $cutoffDate }
            $stats.OldFiles = $oldFiles.Count
            
            # Optionally remove old files
            if ($stats.OldFiles -gt 0 -and $stats.QuarantineSize -gt 1GB) {
                foreach ($oldFile in $oldFiles) {
                    try {
                        Remove-Item -Path $oldFile.FullName -Force -ErrorAction SilentlyContinue
                        Write-Output "STATS:$ModuleName`:Removed old quarantined file: $($oldFile.Name)"
                    } catch { }
                }
            }
        }
        
        # Check quarantine log integrity
        $quarantineLog = Join-Path $QuarantinePath "quarantine_log.txt"
        if (Test-Path $quarantineLog) {
            $logEntries = Get-Content -Path $quarantineLog -ErrorAction SilentlyContinue
            if ($logEntries.Count -gt 10000) {
                # Archive old log entries
                $archivePath = Join-Path $QuarantinePath "quarantine_log_$(Get-Date -Format 'yyyy-MM-dd').txt"
                Copy-Item -Path $quarantineLog -Destination $archivePath -ErrorAction SilentlyContinue
                "Timestamp|FilePath|QuarantinePath|Reason|FileHash" | Set-Content -Path $quarantineLog
            }
        }
        
        Write-Output "STATS:$ModuleName`:Quarantined=$($stats.QuarantinedFiles), Size=$([Math]::Round($stats.QuarantineSize/1MB, 2))MB, Old=$($stats.OldFiles)"
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $stats
}

function Start-Module {

    Initialize-Quarantine
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $stats = Invoke-QuarantineManagement
                $LastTick = $now
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# Export quarantine function for use by other modules
if ($ModuleConfig) {
    $ModuleConfig.QuarantineFunction = ${function:Invoke-QuarantineFile}
}

# --- PrivacyForgeSpoofing ---
# PrivacyForge Spoofing Module
# Identity and Fingerprint Spoofing - Generates fake identity data to prevent browser fingerprinting
#Requires -Version 5.1


$ModuleName = "PrivacyForgeSpoofing"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { (Get-TickInterval $ModuleName) }

# PrivacyForge Configuration
$Script:Config = @{
    BaseDir = "$env:ProgramData\Antivirus"
    LogDir = "$env:ProgramData\Antivirus\Logs"
    RotationIntervalSeconds = 3600  # 1 hour
    DataThreshold = 50  # Rotate after this much simulated data collection
    EnableClipboardSpoofing = $false  # Disabled by default - can overwrite user clipboard
    EnableNetworkSpoofing = $true
    DebugMode = $false
}

# State variables
$Script:PrivacyForgeIdentity = @{}
$Script:PrivacyForgeDataCollected = 0
$Script:PrivacyForgeLastRotation = $null

# ===================== Logging =====================
# Uses standard Write-Log from imported modules

# ===================== Identity Generation =====================

function Invoke-PrivacyForgeGenerateIdentity {
    <#
    .SYNOPSIS
    Generates a fake identity profile for spoofing purposes
    #>
    
    $firstNames = @("John", "Jane", "Michael", "Sarah", "David", "Emily", "James", "Jessica", 
                    "Robert", "Amanda", "William", "Ashley", "Richard", "Melissa", "Joseph", "Nicole",
                    "Thomas", "Jennifer", "Charles", "Elizabeth", "Christopher", "Samantha", "Daniel", "Rebecca")
    $lastNames = @("Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", 
                   "Rodriguez", "Martinez", "Hernandez", "Lopez", "Wilson", "Anderson", "Thomas", "Taylor",
                   "Moore", "Jackson", "Martin", "Lee", "Thompson", "White", "Harris", "Clark")
    $domains = @("gmail.com", "yahoo.com", "outlook.com", "hotmail.com", "protonmail.com", "icloud.com", "aol.com")
    $cities = @("New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", 
                "San Antonio", "San Diego", "Dallas", "San Jose", "Austin", "Jacksonville",
                "Fort Worth", "Columbus", "Charlotte", "Seattle", "Denver", "Boston")
    $countries = @("United States", "Canada", "United Kingdom", "Australia", "Germany", "France", "Spain", "Italy", "Netherlands", "Sweden")
    $languages = @("en-US", "en-GB", "fr-FR", "es-ES", "de-DE", "it-IT", "pt-BR", "nl-NL", "sv-SE")
    $interests = @("tech", "gaming", "news", "sports", "music", "movies", "travel", "food", 
                   "fitness", "books", "photography", "cooking", "art", "science", "finance")
    
    $firstName = Get-Random -InputObject $firstNames
    $lastName = Get-Random -InputObject $lastNames
    $username = "$firstName$lastName" + (Get-Random -Minimum 100 -Maximum 9999)
    $domain = Get-Random -InputObject $domains
    $email = "$username@$domain".ToLower()
    
    $userAgents = @(
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/120.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
    )
    
    $resolutions = @("1920x1080", "2560x1440", "1366x768", "1536x864", "1440x900", "1280x720", "3840x2160")
    
    return @{
        "name" = "$firstName $lastName"
        "email" = $email
        "username" = $username
        "location" = Get-Random -InputObject $cities
        "country" = Get-Random -InputObject $countries
        "user_agent" = Get-Random -InputObject $userAgents
        "screen_resolution" = Get-Random -InputObject $resolutions
        "interests" = (Get-Random -InputObject $interests -Count 4)
        "device_id" = [System.Guid]::NewGuid().ToString()
        "mac_address" = "{0:X2}-{1:X2}-{2:X2}-{3:X2}-{4:X2}-{5:X2}" -f `
            (Get-Random -Minimum 0 -Maximum 256), (Get-Random -Minimum 0 -Maximum 256), `
            (Get-Random -Minimum 0 -Maximum 256), (Get-Random -Minimum 0 -Maximum 256), `
            (Get-Random -Minimum 0 -Maximum 256), (Get-Random -Minimum 0 -Maximum 256)
        "language" = Get-Random -InputObject $languages
        "timezone" = (Get-TimeZone).Id
        "timestamp" = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
        "canvas_hash" = [System.Guid]::NewGuid().ToString("N").Substring(0, 16)
        "webgl_vendor" = Get-Random -InputObject @("Google Inc.", "Intel Inc.", "NVIDIA Corporation", "AMD")
        "webgl_renderer" = Get-Random -InputObject @("ANGLE (Intel, Intel(R) UHD Graphics 630)", "ANGLE (NVIDIA, GeForce GTX 1080)", "ANGLE (AMD, Radeon RX 580)")
        "platform" = Get-Random -InputObject @("Win32", "Win64", "MacIntel", "Linux x86_64")
        "cpu_cores" = Get-Random -InputObject @(4, 6, 8, 12, 16)
        "memory_gb" = Get-Random -InputObject @(8, 16, 32, 64)
    }
}

function Invoke-PrivacyForgeRotateIdentity {
    <#
    .SYNOPSIS
    Rotates to a new fake identity
    #>
    
    $Script:PrivacyForgeIdentity = Invoke-PrivacyForgeGenerateIdentity
    $Script:PrivacyForgeDataCollected = 0
    $Script:PrivacyForgeLastRotation = Get-Date
    
    Write-Log "INFO" "Identity rotated - Name: $($Script:PrivacyForgeIdentity.name), Username: $($Script:PrivacyForgeIdentity.username)"
    
    # Output identity rotation in standard format
    Write-Output "SPOOF:$ModuleName`:Identity rotated - $($Script:PrivacyForgeIdentity.name)"
}

# ===================== Spoofing Functions =====================

function Invoke-PrivacyForgeSpoofSoftwareMetadata {
    <#
    .SYNOPSIS
    Sends spoofed HTTP headers to confuse trackers
    #>
    
    if (-not $Script:Config.EnableNetworkSpoofing) { return }
    
    try {
        $headers = @{
            "User-Agent" = $Script:PrivacyForgeIdentity.user_agent
            "Cookie" = "session_id=$(Get-Random -Minimum 1000 -Maximum 9999); fake_id=$([System.Guid]::NewGuid().ToString())"
            "X-Device-ID" = $Script:PrivacyForgeIdentity.device_id
            "Accept-Language" = $Script:PrivacyForgeIdentity.language
            "X-Timezone" = $Script:PrivacyForgeIdentity.timezone
            "X-Screen-Resolution" = $Script:PrivacyForgeIdentity.screen_resolution
        }
        
        # Send to a test endpoint (non-blocking, fire and forget)
        $null = Start-Job -ScriptBlock {
            param($headers)
            try {
                Invoke-WebRequest -Uri "https://httpbin.org/headers" -Headers $headers -TimeoutSec 5 -UseBasicParsing -ErrorAction SilentlyContinue | Out-Null
            } catch {}
        } -ArgumentList $headers
        
        Write-Log "DEBUG" "Sent spoofed software metadata headers"
    } catch {
        Write-Log "WARN" "Error spoofing software metadata - $_"
    }
}

function Invoke-PrivacyForgeSpoofGameTelemetry {
    <#
    .SYNOPSIS
    Generates fake game telemetry data
    #>
    
    try {
        $fakeTelemetry = @{
            "player_id" = [System.Guid]::NewGuid().ToString()
            "hardware_id" = -join ((1..32) | ForEach-Object { '{0:X}' -f (Get-Random -Maximum 16) })
            "latency" = Get-Random -Minimum 20 -Maximum 200
            "game_version" = "$(Get-Random -Minimum 1 -Maximum 5).$(Get-Random -Minimum 0 -Maximum 9).$(Get-Random -Minimum 0 -Maximum 99)"
            "fps" = Get-Random -Minimum 30 -Maximum 144
            "session_id" = [System.Guid]::NewGuid().ToString()
            "playtime_minutes" = Get-Random -Minimum 10 -Maximum 500
        }
        
        Write-Log "DEBUG" "Spoofed game telemetry - Player ID: $($fakeTelemetry.player_id)"
    } catch {
        Write-Log "WARN" "Error spoofing game telemetry - $_"
    }
}

function Invoke-PrivacyForgeSpoofSensors {
    <#
    .SYNOPSIS
    Generates random sensor data to confuse fingerprinting
    #>
    
    try {
        # Generate sensor data for fingerprinting confusion
        # Data is generated but not used - the purpose is to create noise for trackers
        [math]::Round((Get-Random -Minimum -1000 -Maximum 1000) / 100.0, 2) | Out-Null  # accelerometer
        [math]::Round((Get-Random -Minimum -18000 -Maximum 18000) / 100.0, 2) | Out-Null  # gyroscope
        [math]::Round((Get-Random -Minimum -5000 -Maximum 5000) / 100.0, 2) | Out-Null  # magnetometer
        Get-Random -Minimum 0 -Maximum 1000 | Out-Null  # light sensor
        Get-Random -InputObject @(0, 5, 10) | Out-Null  # proximity sensor
        [math]::Round((Get-Random -Minimum 1500 -Maximum 3500) / 100.0, 1) | Out-Null  # ambient temp
        [math]::Round((Get-Random -Minimum 2000 -Maximum 4000) / 100.0, 1) | Out-Null  # battery temp
        
        Write-Log "DEBUG" "Spoofed sensor data"
    } catch {
        Write-Log "WARN" "Error spoofing sensors - $_"
    }
}

function Invoke-PrivacyForgeSpoofSystemMetrics {
    <#
    .SYNOPSIS
    Generates fake system performance metrics
    #>
    
    try {
        $fakeMetrics = @{
            "cpu_usage" = [math]::Round((Get-Random -Minimum 500 -Maximum 5000) / 100.0, 1)
            "memory_usage" = [math]::Round((Get-Random -Minimum 3000 -Maximum 8500) / 100.0, 1)
            "battery_level" = Get-Random -Minimum 20 -Maximum 100
            "charging" = (Get-Random -InputObject @($true, $false))
            "disk_usage" = [math]::Round((Get-Random -Minimum 2000 -Maximum 9000) / 100.0, 1)
            "network_latency" = Get-Random -Minimum 5 -Maximum 150
            "uptime_hours" = Get-Random -Minimum 1 -Maximum 720
        }
        
        Write-Log "DEBUG" "Spoofed system metrics - CPU: $($fakeMetrics.cpu_usage)%, Memory: $($fakeMetrics.memory_usage)%"
    } catch {
        Write-Log "WARN" "Error spoofing system metrics - $_"
    }
}

function Invoke-PrivacyForgeSpoofClipboard {
    <#
    .SYNOPSIS
    Overwrites clipboard with fake data (disabled by default)
    #>
    
    if (-not $Script:Config.EnableClipboardSpoofing) { return }
    
    try {
        $fakeContent = "PrivacyForge: $(Get-Random -Minimum 100000 -Maximum 999999) - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
        Set-Clipboard -Value $fakeContent -ErrorAction SilentlyContinue
        Write-Log "DEBUG" "Spoofed clipboard content"
    } catch {
        Write-Log "WARN" "Error spoofing clipboard - $_"
    }
}

# ===================== Main Detection Function =====================

function Invoke-PrivacyForgeSpoofing {
    <#
    .SYNOPSIS
    Main spoofing tick function - manages identity rotation and spoofing operations
    #>
    
    # Initialize on first run
    if (-not $Script:PrivacyForgeLastRotation) {
        $Script:PrivacyForgeLastRotation = Get-Date
        Invoke-PrivacyForgeRotateIdentity
    }
    
    try {
        # Check if rotation is needed
        $timeSinceRotation = (Get-Date) - $Script:PrivacyForgeLastRotation
        $shouldRotate = $false
        
        if ($timeSinceRotation.TotalSeconds -ge $Script:Config.RotationIntervalSeconds) {
            $shouldRotate = $true
            Write-Log "INFO" "Time-based rotation triggered"
        }
        
        if ($Script:PrivacyForgeDataCollected -ge $Script:Config.DataThreshold) {
            $shouldRotate = $true
            Write-Log "INFO" "Data threshold reached ($Script:PrivacyForgeDataCollected/$($Script:Config.DataThreshold))"
        }
        
        if ($shouldRotate -or (-not $Script:PrivacyForgeIdentity.ContainsKey("name"))) {
            Invoke-PrivacyForgeRotateIdentity
        }
        
        # Simulate data collection increment
        $Script:PrivacyForgeDataCollected += Get-Random -Minimum 1 -Maximum 6
        
        # Perform spoofing operations
        Invoke-PrivacyForgeSpoofSoftwareMetadata
        Invoke-PrivacyForgeSpoofGameTelemetry
        Invoke-PrivacyForgeSpoofSensors
        Invoke-PrivacyForgeSpoofSystemMetrics
        Invoke-PrivacyForgeSpoofClipboard
        
        Write-Log "INFO" "Spoofing active - Data collected: $Script:PrivacyForgeDataCollected/$($Script:Config.DataThreshold)"
        
        # Output spoofing activity in standard format
        Write-Output "SPOOF:$ModuleName`:Identity rotation active - Data: $Script:PrivacyForgeDataCollected/$($Script:Config.DataThreshold)"
        
    } catch {
        Write-Log "ERROR" "Error in main spoofing loop - $_"
    }
}

# ===================== Module Start Function =====================

function Start-Module {

    Write-Log "INFO" "========================================"
    Write-Log "INFO" "PrivacyForge Spoofing Module Starting"
    Write-Log "INFO" "Tick Interval: $TickInterval seconds"
    Write-Log "INFO" "Rotation Interval: $($Script:Config.RotationIntervalSeconds)s"
    Write-Log "INFO" "Data Threshold: $($Script:Config.DataThreshold)"
    Write-Log "INFO" "Clipboard Spoofing: $($Script:Config.EnableClipboardSpoofing)"
    Write-Log "INFO" "Network Spoofing: $($Script:Config.EnableNetworkSpoofing)"
    Write-Log "INFO" "========================================"
    
    # Initial identity generation
    Invoke-PrivacyForgeRotateIdentity
    
    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $script:LastTick = $now
                Invoke-PrivacyForgeSpoofing
            }
            Start-Sleep -Seconds (Get-LoopSleep)
        } catch {
            Write-Output "ERROR:$ModuleName`':$_"
            Start-Sleep -Seconds 10
        }
    }
}

# Start module if not running with configuration

# --- PasswordManagement ---
# Password Management Module
# Monitors password policies and storage

$ModuleName = "PasswordManagement"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 300 }

function Invoke-PasswordManagement {
    $detections = @()
    
    try {
        # Check password policy
        try {
            $passwordPolicy = Get-LocalUser | ForEach-Object {
                $_.PasswordNeverExpires
            }
            
            $expiredPasswords = $passwordPolicy | Where-Object { $_ -eq $true }
            
            if ($expiredPasswords.Count -gt 0) {
                $detections += @{
                    ExpiredPasswordCount = $expiredPasswords.Count
                    Type = "Accounts with Non-Expiring Passwords"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for weak passwords (indirectly through failed logon attempts)
        try {
            $securityEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -ErrorAction SilentlyContinue -MaxEvents 100
            
            $failedLogons = $securityEvents | Where-Object {
                (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromHours(24)
            }
            
            if ($failedLogons.Count -gt 50) {
                $detections += @{
                    FailedLogonCount = $failedLogons.Count
                    Type = "Excessive Failed Logon Attempts - Possible Weak Passwords"
                    Risk = "Medium"
                }
            }
        } catch { }
        
        # Check for password storage in plain text
        try {
            $searchPaths = @(
                "$env:USERPROFILE\Desktop",
                "$env:USERPROFILE\Documents",
                "$env:USERPROFILE\Downloads",
                "$env:TEMP"
            )
            
            $passwordFiles = @()
            foreach ($path in $searchPaths) {
                if (Test-Path $path) {
                    try {
                        $files = Get-ChildItem -Path $path -Filter "*.txt","*.log","*.csv" -File -ErrorAction SilentlyContinue |
                            Select-Object -First 50
                        
                        foreach ($file in $files) {
                            try {
                                $content = Get-Content $file.FullName -Raw -ErrorAction SilentlyContinue
                                if ($content -match '(?i)(password|pwd|passwd)\s*[:=]\s*\S+') {
                                    $passwordFiles += @{
                                        File = $file.FullName
                                        Type = "Plain Text Password Storage"
                                        Risk = "High"
                                    }
                                }
                            } catch { }
                        }
                    } catch { }
                }
            }
            
            $detections += $passwordFiles
        } catch { }
        
        # Check for credential dumping tools
        try {
            $credDumpTools = @("mimikatz", "lsadump", "pwdump", "fgdump", "hashdump")
            $processes = Get-Process -ErrorAction SilentlyContinue
            
            foreach ($proc in $processes) {
                foreach ($tool in $credDumpTools) {
                    if ($proc.ProcessName -like "*$tool*" -or 
                        $proc.Path -like "*$tool*") {
                        $detections += @{
                            ProcessId = $proc.Id
                            ProcessName = $proc.ProcessName
                            Tool = $tool
                            Type = "Credential Dumping Tool"
                            Risk = "Critical"
                        }
                    }
                }
            }
        } catch { }
        
        # Check for SAM database access
        try {
            $securityEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4656,4663} -ErrorAction SilentlyContinue -MaxEvents 500 |
                Where-Object { $_.Message -match 'SAM|SECURITY|SYSTEM' -and $_.Message -match 'Read|Write' }
            
            if ($securityEvents.Count -gt 0) {
                foreach ($event in $securityEvents) {
                    $detections += @{
                        EventId = $event.Id
                        TimeCreated = $event.TimeCreated
                        Message = $event.Message
                        Type = "SAM Database Access Attempt"
                        Risk = "High"
                    }
                }
            }
        } catch { }
        
        # Check for LSA secrets access
        try {
            $lsaEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4656} -ErrorAction SilentlyContinue -MaxEvents 200 |
                Where-Object { $_.Message -match 'LSA|Local.*Security.*Authority' }
            
            if ($lsaEvents.Count -gt 5) {
                $detections += @{
                    EventCount = $lsaEvents.Count
                    Type = "Excessive LSA Access Attempts"
                    Risk = "High"
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2030 `
                    -Message "PASSWORD MANAGEMENT: $($detection.Type) - $($detection.ProcessName -or $detection.File -or $detection.Tool)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\PasswordManagement_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.File)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) password management issues"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-PasswordManagement
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- IdsDetection ---
# IDS Detection
# Command-line IDS patterns (meterpreter, certutil -urlcache, etc.)

$ModuleName = "IdsDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 60 }

$Patterns = @(
    @{ Pattern = "meterpreter"; Desc = "Metasploit meterpreter" }
    @{ Pattern = "certutil\s+-urlcache"; Desc = "Certutil download" }
    @{ Pattern = "bitsadmin\s+/transfer"; Desc = "Bitsadmin download" }
    @{ Pattern = "powershell\s+-enc"; Desc = "Base64 encoded PS" }
    @{ Pattern = "powershell\s+-w\s+hidden"; Desc = "Hidden window PS" }
    @{ Pattern = "invoke-expression"; Desc = "IEX usage" }
    @{ Pattern = "iex\s*\("; Desc = "IEX usage" }
    @{ Pattern = "downloadstring"; Desc = "DownloadString" }
    @{ Pattern = "downloadfile"; Desc = "DownloadFile" }
    @{ Pattern = "webclient"; Desc = "WebClient" }
    @{ Pattern = "net\.webclient"; Desc = "Net.WebClient" }
    @{ Pattern = "bypass.*-executionpolicy"; Desc = "Execution policy bypass" }
    @{ Pattern = "wmic\s+process\s+call\s+create"; Desc = "WMI process creation" }
    @{ Pattern = "reg\s+add.*HKLM.*Run"; Desc = "Registry Run key" }
    @{ Pattern = "schtasks\s+/create"; Desc = "Scheduled task creation" }
    @{ Pattern = "netsh\s+firewall"; Desc = "Firewall modification" }
    @{ Pattern = "sc\s+create"; Desc = "Service creation" }
    @{ Pattern = "rundll32.*\.dll"; Desc = "Rundll32 DLL" }
    @{ Pattern = "regsvr32\s+.*/s"; Desc = "Regsvr32 silent" }
    @{ Pattern = "mshta\s+http"; Desc = "Mshta remote script" }
)

function Invoke-IdsScan {
    $detections = @()
    try {
        $processes = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Select-Object ProcessId, Name, CommandLine
        foreach ($proc in $processes) {
            $cmd = if ($proc.CommandLine) { $proc.CommandLine } else { "" }
            foreach ($p in $Patterns) {
                if ($cmd -match $p.Pattern) {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        Pattern = $p.Pattern
                        Description = $p.Desc
                        CommandLine = $cmd.Substring(0, [Math]::Min(500, $cmd.Length))
                    }
                    break
                }
            }
        }
        
        if ($detections.Count -gt 0) {
            foreach ($d in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2095 -Message "IDS: $($d.Description) - $($d.ProcessName) PID:$($d.ProcessId)" -ErrorAction SilentlyContinue
            }
            $logPath = "$env:ProgramData\Antivirus\Logs\ids_detection_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object { "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Description)|$($_.ProcessName)|PID:$($_.ProcessId)" | Add-Content -Path $logPath }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) IDS matches"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $script:LastTick = $now
                Invoke-IdsScan
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- CredentialDumpDetection ---
# Credential Dumping Detection Module
# Detects attempts to dump credentials from memory

$ModuleName = "CredentialDumpDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 20 }

$CredentialDumpTools = @(
    "mimikatz", "sekurlsa", "lsadump", "wce", "fgdump", 
    "pwdump", "hashdump", "gsecdump", "cachedump",
    "procDump", "dumpert", "nanodump", "mslsa"
)

function Invoke-CredentialDumpScan {
    $detections = @()
    
    try {
        # Check running processes
        $processes = Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine, ExecutablePath
        
        foreach ($proc in $processes) {
            $procNameLower = $proc.Name.ToLower()
            $cmdLineLower = if ($proc.CommandLine) { $proc.CommandLine.ToLower() } else { "" }
            $pathLower = if ($proc.ExecutablePath) { $proc.ExecutablePath.ToLower() } else { "" }
            
            # Check for credential dumping tools
            foreach ($tool in $CredentialDumpTools) {
                if ($procNameLower -like "*$tool*" -or 
                    $cmdLineLower -like "*$tool*" -or 
                    $pathLower -like "*$tool*") {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        CommandLine = $proc.CommandLine
                        Tool = $tool
                        Risk = "Critical"
                    }
                    break
                }
            }
            
            # Check for suspicious LSASS access
            if ($proc.Name -match "lsass|sam|security") {
                try {
                    $lsassProc = Get-Process -Name "lsass" -ErrorAction SilentlyContinue
                    if ($lsassProc) {
                        # Check if process has handle to LSASS
                        $handles = Get-CimInstance Win32_ProcessHandle -Filter "ProcessId=$($proc.ProcessId)" -ErrorAction SilentlyContinue
                        if ($handles) {
                            $detections += @{
                                ProcessId = $proc.ProcessId
                                ProcessName = $proc.Name
                                Type = "LSASS Memory Access"
                                Risk = "High"
                            }
                        }
                    }
                } catch { }
            }
        }
        
        # Check for credential dumping API calls in Event Log
        try {
            $securityEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4656,4663} -ErrorAction SilentlyContinue -MaxEvents 500
            foreach ($event in $securityEvents) {
                if ($event.Message -match 'lsass|sam|security' -and 
                    $event.Message -match 'Read|Write') {
                    $xml = [xml]$event.ToXml()
                    $objectName = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'ObjectName'}).'#text'
                    if ($objectName -match 'SAM|SECURITY|SYSTEM') {
                        $detections += @{
                            EventId = $event.Id
                            Type = "Registry Credential Access"
                            ObjectName = $objectName
                            Risk = "High"
                        }
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2005 `
                    -Message "CREDENTIAL DUMP DETECTED: $($detection.ProcessName -or $detection.Type) - $($detection.Tool -or $detection.ObjectName)"
            }
            
            $logPath = "$env:ProgramData\Antivirus\Logs\CredentialDump_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.ProcessName -or $_.Type)|$($_.Tool -or $_.ObjectName)|$($_.Risk)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) credential dump attempts"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-CredentialDumpScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- LOLBinDetection ---
# Living-Off-The-Land Binary Detection
# Detects legitimate tools used maliciously

$ModuleName = "LOLBinDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 30 }
$LOLBinPatterns = @{
    "cmd.exe" = @("\/c.*certutil|powershell|bitsadmin|regsvr32")
    "powershell.exe" = @("-nop.*-w.*hidden|-EncodedCommand|-ExecutionPolicy.*Bypass")
    "wmic.exe" = @("process.*call.*create")
    "mshta.exe" = @("http|https|\.hta")
    "rundll32.exe" = @("javascript:|\.dll.*\,")
    "regsvr32.exe" = @("\/s.*\/i.*http|\.sct")
    "certutil.exe" = @("-urlcache|-decode|\.exe")
    "bitsadmin.exe" = @("/transfer|/rawreturn")
    "schtasks.exe" = @("/create.*/tn.*http|/create.*/tr.*powershell")
    "msbuild.exe" = @("\.xml.*http|\.csproj.*http")
    "csc.exe" = @("\.cs.*http")
}
$DetectionCount = 0

function Get-RunningProcesses {
    try {
        return Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine, CreationDate, ParentProcessId
    } catch {
        return @()
    }
}

function Test-LOLBinCommandLine {
    param(
        [string]$ProcessName,
        [string]$CommandLine
    )
    
    if ([string]::IsNullOrEmpty($CommandLine)) { return $null }
    
    $processNameLower = $ProcessName.ToLower()
    $cmdLineLower = $CommandLine.ToLower()
    
    if ($LOLBinPatterns.ContainsKey($processNameLower)) {
        foreach ($pattern in $LOLBinPatterns[$processNameLower]) {
            if ($cmdLineLower -match $pattern) {
                return @{
                    Process = $ProcessName
                    CommandLine = $CommandLine
                    Pattern = $pattern
                    Risk = "High"
                }
            }
        }
    }
    
    # Additional heuristics
    if ($cmdLineLower -match 'powershell.*-encodedcommand' -and 
        $cmdLineLower.Length -gt 500) {
        return @{
            Process = $ProcessName
            CommandLine = $CommandLine
            Pattern = "Long encoded PowerShell command"
            Risk = "High"
        }
    }
    
    if ($cmdLineLower -match '(http|https)://[^\s]+' -and 
        $processNameLower -in @('cmd.exe','rundll32.exe','mshta.exe')) {
        return @{
            Process = $ProcessName
            CommandLine = $CommandLine
            Pattern = "Network download from LOLBin"
            Risk = "High"
        }
    }
    
    return $null
}

function Invoke-LOLBinScan {
    $detections = @()
    $processes = Get-RunningProcesses
    
    foreach ($proc in $processes) {
        $result = Test-LOLBinCommandLine -ProcessName $proc.Name -CommandLine $proc.CommandLine
        if ($result) {
            $detections += @{
                ProcessId = $proc.ProcessId
                ProcessName = $proc.Name
                CommandLine = $proc.CommandLine
                Pattern = $result.Pattern
                Risk = $result.Risk
                ParentProcessId = $proc.ParentProcessId
                CreationDate = $proc.CreationDate
            }
        }
    }
    
    if ($detections.Count -gt 0) {
        $script:DetectionCount += $detections.Count
        
        foreach ($detection in $detections) {
            Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Warning -EventId 2002 `
                -Message "LOLBIN DETECTED: $($detection.ProcessName) (PID: $($detection.ProcessId)) - $($detection.Pattern)"
            
            # Log details
            $logPath = "$env:ProgramData\Antivirus\Logs\LOLBinDetection_$(Get-Date -Format 'yyyy-MM-dd').log"
            "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|PID:$($detection.ProcessId)|$($detection.ProcessName)|$($detection.Pattern)|$($detection.CommandLine)" | 
                Add-Content -Path $logPath
        }
        
        Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) LOLBin instances"
    }
    
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $LastTick).TotalSeconds -ge $TickInterval) {
                $count = Invoke-LOLBinScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Scanned processes, Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- MemoryAcquisitionDetection ---
# Memory Acquisition Detection
# Detects WinPmem, pmem, FTK Imager, etc.

$ModuleName = "MemoryAcquisitionDetection"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 90 }

$ProcessPatterns = @("winpmem", "pmem", "osxpmem", "aff4imager", "winpmem_mini", "memdump", "rawdump")
$CmdPatterns = @("winpmem", "pmem", "\.\pmem", "/dev/pmem", ".aff4", "-o .raw", "-o .aff4", "image.raw", "memory.raw", "physical memory", "memory acquisition", "physicalmemory")

function Invoke-MemoryAcquisitionScan {
    $detections = @()
    try {
        $processes = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Select-Object ProcessId, Name, CommandLine, ExecutablePath
        foreach ($proc in $processes) {
            $name = if ($proc.Name) { $proc.Name.ToLower() } else { "" }
            $cmd = (if ($proc.CommandLine) { $proc.CommandLine } else { "" }) + " " + (if ($proc.ExecutablePath) { $proc.ExecutablePath } else { "" })
            
            foreach ($pat in $ProcessPatterns) {
                if ($name -like "*$pat*") {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        Pattern = $pat
                        Type = "Memory Acquisition Tool"
                        Risk = "Critical"
                    }
                    break
                }
            }
            if ($detections[-1].ProcessId -eq $proc.ProcessId) { continue }
            
            foreach ($pat in $CmdPatterns) {
                if ($cmd -like "*$pat*") {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        Pattern = "cmd:$pat"
                        Type = "Memory Acquisition (cmd)"
                        Risk = "Critical"
                    }
                    break
                }
            }
        }
        
        if ($detections.Count -gt 0) {
            foreach ($d in $detections) {
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Error -EventId 2093 -Message "MEMORY ACQUISITION: $($d.Pattern) - $($d.ProcessName) (PID: $($d.ProcessId))" -ErrorAction SilentlyContinue
            }
            $logPath = "$env:ProgramData\Antivirus\Logs\memory_acquisition_detections_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object { "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.ProcessName)|PID:$($_.ProcessId)" | Add-Content -Path $logPath }
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) memory acquisition indicators"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    return $detections.Count
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $script:LastTick = $now
                Invoke-MemoryAcquisitionScan | Out-Null
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- MobileDeviceMonitoring ---
# Mobile Device Monitoring
# Win32_PnPEntity for portable/USB/MTP devices

$ModuleName = "MobileDeviceMonitoring"
$LastTick = Get-Date
$TickInterval = if ($ModuleConfig.TickInterval) { $ModuleConfig.TickInterval } else { 90 }

$DeviceClasses = @("USB", "Bluetooth", "Image", "WPD", "PortableDevice", "MTP")
$KnownDevices = @{}

function Invoke-MobileDeviceScan {
    $newDevices = @()
    try {
        $devices = Get-CimInstance Win32_PnPEntity -ErrorAction SilentlyContinue | Where-Object {
            foreach ($cls in $DeviceClasses) {
                if (($_.PNPClass -eq $cls) -or ($_.Service -like "*$cls*")) {
                    return $true
                }
            }
            return $false
        }
        
        foreach ($d in $devices) {
            $key = $d.DeviceID
            if (-not $script:KnownDevices.ContainsKey($key)) {
                $script:KnownDevices[$key] = $true
                $newDevices += @{
                    DeviceID = $d.DeviceID
                    Name = $d.Name
                    PNPClass = $d.PNPClass
                    Status = $d.Status
                }
            }
        }
        
        if ($newDevices.Count -gt 0) {
            $logPath = "$env:ProgramData\Antivirus\Logs\mobile_device_$(Get-Date -Format 'yyyy-MM-dd').log"
            foreach ($nd in $newDevices) {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|New device|$($nd.Name)|$($nd.PNPClass)|$($nd.DeviceID)" | Add-Content -Path $logPath
                Write-EventLog -LogName Application -Source "AntivirusEDR" -EntryType Information -EventId 2094 -Message "MOBILE DEVICE: $($nd.Name) - $($nd.PNPClass)" -ErrorAction SilentlyContinue
            }
            Write-Output "STATS:$ModuleName`:Logged $($newDevices.Count) new mobile/USB devices"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
}

function Start-Module {

    while ($true) {
        try {
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $script:TickInterval) {
                $script:LastTick = $now
                Invoke-MobileDeviceScan
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}

# --- Scheduler ---
$script:ModuleLastRun = @{}
$schedule = @(
    @{ Name = 'Initializer'; Interval = 300; Invoke = 'Invoke-Initialization' }
    @{ Name = 'HashDetection'; Interval = 90; Invoke = 'Invoke-HashScanOptimized' }
    @{ Name = 'AMSIBypassDetection'; Interval = 90; Invoke = 'Invoke-AMSIBypassScan' }
    @{ Name = 'GFocus'; Interval = 2; Invoke = 'Invoke-GFocusTick' }
    @{ Name = 'ResponseEngine'; Interval = 180; Invoke = 'Invoke-ResponseEngine' }
    @{ Name = 'BeaconDetection'; Interval = 60; Invoke = 'Invoke-BeaconDetection' }
    @{ Name = 'NetworkTrafficMonitoring'; Interval = 45; Invoke = 'Invoke-NetworkTrafficMonitoringOptimized' }
    @{ Name = 'ProcessAnomalyDetection'; Interval = 90; Invoke = 'Invoke-ProcessAnomalyScanOptimized' }
    @{ Name = 'EventLogMonitoring'; Interval = 90; Invoke = 'Invoke-EventLogMonitoringOptimized' }
    @{ Name = 'FileEntropyDetection'; Interval = 120; Invoke = 'Invoke-FileEntropyDetectionOptimized' }
    @{ Name = 'YaraDetection'; Interval = 120; Invoke = 'Invoke-YaraScan' }
    @{ Name = 'WMIPersistenceDetection'; Interval = 60; Invoke = 'Invoke-WMIPersistenceScan' }
    @{ Name = 'ScheduledTaskDetection'; Interval = 60; Invoke = 'Invoke-ScheduledTaskScan' }
    @{ Name = 'RegistryPersistenceDetection'; Interval = 60; Invoke = 'Invoke-RegistryPersistenceScan' }
    @{ Name = 'DLLHijackingDetection'; Interval = 60; Invoke = 'Invoke-DLLHijackingScan' }
    @{ Name = 'TokenManipulationDetection'; Interval = 30; Invoke = 'Invoke-TokenManipulationScan' }
    @{ Name = 'ProcessHollowingDetection'; Interval = 20; Invoke = 'Invoke-ProcessHollowingScan' }
    @{ Name = 'KeyloggerDetection'; Interval = 30; Invoke = 'Invoke-KeyloggerScan' }
    @{ Name = 'ReflectiveDLLInjectionDetection'; Interval = 30; Invoke = 'Invoke-ReflectiveDLLInjectionDetection' }
    @{ Name = 'RansomwareDetection'; Interval = 15; Invoke = 'Invoke-RansomwareScan' }
    @{ Name = 'NetworkAnomalyDetection'; Interval = 30; Invoke = 'Invoke-NetworkAnomalyScan' }
    @{ Name = 'DNSExfiltrationDetection'; Interval = 60; Invoke = 'Invoke-DNSExfiltrationDetection' }
    @{ Name = 'RootkitDetection'; Interval = 60; Invoke = 'Invoke-RootkitScan' }
    @{ Name = 'ClipboardMonitoring'; Interval = 10; Invoke = 'Invoke-ClipboardMonitoring' }
    @{ Name = 'COMMonitoring'; Interval = 60; Invoke = 'Invoke-COMMonitoring' }
    @{ Name = 'BrowserExtensionMonitoring'; Interval = 60; Invoke = 'Invoke-BrowserExtensionMonitoring' }
    @{ Name = 'ShadowCopyMonitoring'; Interval = 30; Invoke = 'Invoke-ShadowCopyMonitoring' }
    @{ Name = 'USBMonitoring'; Interval = 30; Invoke = 'Invoke-USBMonitoring' }
    @{ Name = 'WebcamGuardian'; Interval = 20; Invoke = 'Invoke-WebcamGuardian' }
    @{ Name = 'AttackToolsDetection'; Interval = 60; Invoke = 'Invoke-AttackToolsScan' }
    @{ Name = 'AdvancedThreatDetection'; Interval = 60; Invoke = 'Invoke-AdvancedThreatScan' }
    @{ Name = 'FirewallRuleMonitoring'; Interval = 60; Invoke = 'Invoke-FirewallRuleMonitoring' }
    @{ Name = 'ServiceMonitoring'; Interval = 60; Invoke = 'Invoke-ServiceMonitoring' }
    @{ Name = 'FilelessDetection'; Interval = 20; Invoke = 'Invoke-FilelessDetection' }
    @{ Name = 'MemoryScanning'; Interval = 90; Invoke = 'Invoke-MemoryScanningOptimized' }
    @{ Name = 'NamedPipeMonitoring'; Interval = 60; Invoke = 'Invoke-NamedPipeMonitoring' }
    @{ Name = 'CodeInjectionDetection'; Interval = 30; Invoke = 'Invoke-CodeInjectionDetection' }
    @{ Name = 'DataExfiltrationDetection'; Interval = 60; Invoke = 'Invoke-DataExfiltrationDetection' }
    @{ Name = 'HoneypotMonitoring'; Interval = 300; Invoke = 'Invoke-HoneypotMonitoring' }
    @{ Name = 'LateralMovementDetection'; Interval = 30; Invoke = 'Invoke-LateralMovementDetection' }
    @{ Name = 'ProcessCreationDetection'; Interval = 60; Invoke = 'Invoke-ProcessCreationDetection' }
    @{ Name = 'QuarantineManagement'; Interval = 300; Invoke = 'Invoke-QuarantineManagement' }
    @{ Name = 'PrivacyForgeSpoofing'; Interval = 300; Invoke = 'Invoke-PrivacyForgeSpoofing' }
    @{ Name = 'PasswordManagement'; Interval = 300; Invoke = 'Invoke-PasswordManagement' }
    @{ Name = 'IdsDetection'; Interval = 60; Invoke = 'Invoke-IdsScan' }
    @{ Name = 'CredentialDumpDetection'; Interval = 20; Invoke = 'Invoke-CredentialDumpScan' }
    @{ Name = 'LOLBinDetection'; Interval = 30; Invoke = 'Invoke-LOLBinScan' }
    @{ Name = 'MemoryAcquisitionDetection'; Interval = 90; Invoke = 'Invoke-MemoryAcquisitionScan' }
    @{ Name = 'MobileDeviceMonitoring'; Interval = 90; Invoke = 'Invoke-MobileDeviceScan' }
)

if ($RemoveRules) {
    if (Get-Command Remove-BlockedRules -ErrorAction SilentlyContinue) { Remove-BlockedRules }; exit 0
}

Invoke-Initialization | Out-Null

$loopSleep = 5
while ($true) {
    $now = Get-Date
    foreach ($m in $schedule) {
        if (-not $script:ModuleLastRun.ContainsKey($m.Name)) { $script:ModuleLastRun[$m.Name] = [datetime]::MinValue }
        if (($now - $script:ModuleLastRun[$m.Name]).TotalSeconds -ge $m.Interval) {
            $script:ModuleName = $m.Name
            try { & $m.Invoke | Out-Null } catch { Write-Output "ERROR:$($m.Name):$_" }
            $script:ModuleLastRun[$m.Name] = $now
        }
    }
    Start-Sleep -Seconds $loopSleep
}

Editor is loading...
Leave a Comment