Gorstaks Antivirus

 avatar
unknown
powershell
2 months ago
362 kB
7
No Index
# Antivirus.ps1
# Author: Gorstak

#Requires -RunAsAdministrator

param(
    [Parameter(Mandatory=$false)]
    [switch]$RemoveRules = $false,
    [Parameter(Mandatory=$false)]
    [string]$Module = $null
)

$script:GEDRRoot = "C:\ProgramData\GEDR"

# Optimized configuration for GEDR EDR modules
# Provides tick intervals, scan limits, batch settings, CPU throttling
$script:ModuleTickIntervals = @{
    "HashDetection" = 90
    "ResponseEngine" = 180
    "MemoryScanning" = 90
    "BeaconDetection" = 60
    "NetworkTrafficMonitoring" = 45
    "AMSIBypassDetection" = 90
    "ProcessAnomalyDetection" = 90
    "EventLogMonitoring" = 90
    "FileEntropyDetection" = 120
    "Initializer" = 300
    "GFocus" = 2
    "WebcamGuardian" = 5
}

$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
}


# Cache Manager Module - GEDR agents
# Provides caching to reduce repeated expensive operations

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

function Get-CachedSignature {
    param([string]$FilePath)
    $now = Get-Date
    $ttl = 60
    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 = "SHA256")
    $now = Get-Date
    $ttl = 120
    $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
    $script:SignatureCache.Keys | Where-Object { ($now - $script:SignatureCache[$_].Timestamp).TotalMinutes -gt 60 } | ForEach-Object { $script:SignatureCache.Remove($_) }
    $script:HashCache.Keys | Where-Object { ($now - $script:HashCache[$_].Timestamp).TotalMinutes -gt 120 } | ForEach-Object { $script:HashCache.Remove($_) }
}


# Initializer Module - GEDR EDR environment setup



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

function Invoke-Initialization {
    try {
        Write-Output "STATS:$ModuleName`:Starting GEDR environment initialization"
        $root = $script:GEDRRoot
        $directories = @(
            $root,
            "$root\Logs",
            "$root\Data",
            "$root\Quarantine",
            "$root\Reports",
            "$root\HashDatabase"
        )
        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"
            }
        }
        $logFiles = @(
            "$root\Logs\System_$(Get-Date -Format 'yyyy-MM-dd').log",
            "$root\Logs\Threats_$(Get-Date -Format 'yyyy-MM-dd').log",
            "$root\Logs\Responses_$(Get-Date -Format 'yyyy-MM-dd').log"
        )
        foreach ($logFile in $logFiles) {
            if (-not (Test-Path $logFile)) {
                $header = "# GEDR 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"
            }
        }
        try {
            if (-not [System.Diagnostics.EventLog]::SourceExists("GEDR")) {
                [System.Diagnostics.EventLog]::CreateEventSource("GEDR", "Application")
                Write-Output "STATS:$ModuleName`:Created Event Log source: GEDR"
            }
        } catch { Write-Output "ERROR:$ModuleName`:Failed to create Event Log source: $_" }
        $configFile = "$root\Data\config.json"
        if (-not (Test-Path $configFile)) {
            $defaultConfig = @{
                Version = "1.0"
                Initialized = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
                Settings = @{ MaxLogSizeMB = 100; QuarantineRetentionDays = 30 }
            }
            $defaultConfig | ConvertTo-Json -Depth 3 | Set-Content -Path $configFile
            Write-Output "STATS:$ModuleName`:Created configuration file"
        }
        $statusFile = "$root\Data\agent_status.json"
        if (-not (Test-Path $statusFile)) {
            @{ LastCheck = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'); ActiveAgents = @(); TotalDetections = 0 } | ConvertTo-Json -Depth 3 | Set-Content -Path $statusFile
        }
        "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|Initializer|Environment|GEDR environment initialized" | Add-Content -Path "$root\Logs\System_$(Get-Date -Format 'yyyy-MM-dd').log"
        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 {
            if ($script:Initialized -and (Test-CPULoadThreshold)) {
                Start-Sleep -Seconds ($loopSleep * 2)
                continue
            }
            $now = Get-Date
            if (($now - $script:LastTick).TotalSeconds -ge $TickInterval) {
                if (-not $script:Initialized) {
                    $count = Invoke-Initialization
                    if ($count -gt 0) { $script:Initialized = $true }
                } else {
                    $statusFile = "$script:GEDRRoot\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
                    }
                }
                $script:LastTick = $now
            }
            Start-Sleep -Seconds $loopSleep
        } catch { Write-Output "ERROR:$ModuleName`:$_"; Start-Sleep -Seconds 120 }
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{} }


# region 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 {
    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 = "C:\ProgramData\GEDR\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 "GEDR" -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
        }
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{ TickInterval = 90 } }
# endregion

# region AMSIBypassDetection
# AMSI Bypass Detection Module
# Detects attempts to bypass Windows AMSI - Optimized for low resource usage



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

function Invoke-AMSIBypassScan {
    $detections = @()
    
    # Check for AMSI bypass techniques in running processes
    try {
        $maxProcs = Get-ScanLimit -LimitName "MaxProcesses"
        $processes = Get-CimInstance Win32_Process | Where-Object { $_.Name -like "*powershell*" -or $_.Name -like "*wscript*" -or $_.Name -like "*cscript*" } | Select-Object -First $maxProcs
        
        foreach ($proc in $processes) {
            $cmdLine = $proc.CommandLine
            if ([string]::IsNullOrEmpty($cmdLine)) { continue }
            
            # Enhanced AMSI bypass patterns
            $bypassPatterns = @(
                '[Ref].Assembly.GetType.*System.Management.Automation.AmsiUtils',
                '[Ref].Assembly.GetType.*AmsiUtils',
                'AmsiScanBuffer',
                'amsiInitFailed',
                'Bypass',
                'amsi.dll',
                'S`y`s`t`e`m.Management.Automation',
                'Hacking',
                'AMSI',
                'amsiutils',
                'amsiInitFailed',
                'Context',
                'AmsiContext',
                'AMSI_RESULT_CLEAN',
                'PatchAmsi',
                'DisableAmsi',
                'ForceAmsi',
                'Remove-Amsi',
                'Invoke-AmsiBypass',
                'AMSI.*bypass',
                'bypass.*AMSI',
                '-nop.*-w.*hidden.*-enc',
                'amsi.*off',
                'amsi.*disable',
                'Set-Amsi',
                'Override.*AMSI'
            )
            
            foreach ($pattern in $bypassPatterns) {
                if ($cmdLine -match $pattern) {
                    $detections += @{
                        ProcessId = $proc.ProcessId
                        ProcessName = $proc.Name
                        CommandLine = $cmdLine
                        BypassPattern = $pattern
                        Risk = "Critical"
                    }
                    break
                }
            }
            
            # Check for obfuscated AMSI bypass (base64, hex, etc.)
            if ($cmdLine -match '-enc|-encodedcommand' -and $cmdLine.Length -gt 500) {
                # Long encoded command - try to decode
                try {
                    $encodedPart = $cmdLine -split '-enc\s+' | Select-Object -Last 1 -ErrorAction SilentlyContinue
                    if ($encodedPart) {
                        $decoded = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($encodedPart.Trim()))
                        if ($decoded -match 'amsi|AmsiScanBuffer|bypass' -or $decoded.Length -gt 1000) {
                            $detections += @{
                                ProcessId = $proc.ProcessId
                                ProcessName = $proc.Name
                                CommandLine = $cmdLine
                                BypassPattern = "Obfuscated AMSI Bypass (Encoded)"
                                DecodedLength = $decoded.Length
                                Risk = "Critical"
                            }
                        }
                    }
                } catch { }
            }
        }
        
        # Check PowerShell script blocks in memory
        try {
            $psProcesses = Get-Process -Name "powershell*","pwsh*" -ErrorAction SilentlyContinue
            foreach ($psProc in $psProcesses) {
                # Check for AMSI-related .NET assemblies loaded
                $modules = $psProc.Modules | Where-Object {
                    $_.ModuleName -match 'amsi|System.Management.Automation'
                }
                
                if ($modules.Count -gt 0) {
                    # Check Event Log for AMSI script block logging
                    try {
                        $psEvents = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104} -ErrorAction SilentlyContinue -MaxEvents 50 |
                            Where-Object {
                                (Get-Date) - $_.TimeCreated -lt [TimeSpan]::FromMinutes(5) -and
                                ($_.Message -match 'amsi|bypass|AmsiScanBuffer' -or $_.Message.Length -gt 5000)
                            }
                        
                        if ($psEvents.Count -gt 0) {
                            foreach ($event in $psEvents) {
                                $detections += @{
                                    ProcessId = $psProc.Id
                                    ProcessName = $psProc.ProcessName
                                    Type = "AMSI Bypass in PowerShell Script Block"
                                    Message = $event.Message.Substring(0, [Math]::Min(500, $event.Message.Length))
                                    TimeCreated = $event.TimeCreated
                                    Risk = "Critical"
                                }
                            }
                        }
                    } catch { }
                }
            }
        } catch { }
        
        # Check Event Log for AMSI events
        try {
            $amsiEvents = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Windows Defender/Operational'; Id=1116,1117,1118} -ErrorAction SilentlyContinue -MaxEvents 100
            foreach ($event in $amsiEvents) {
                if ($event.Message -match 'AmsiScanBuffer|bypass|blocked') {
                    $detections += @{
                        EventId = $event.Id
                        Message = $event.Message
                        TimeCreated = $event.TimeCreated
                        Risk = "High"
                    }
                }
            }
        } catch { }
        
        # Check for AMSI registry tampering
        try {
            $amsiKey = "HKLM:\SOFTWARE\Microsoft\AMSI"
            if (Test-Path $amsiKey) {
                $amsiValue = Get-ItemProperty -Path $amsiKey -ErrorAction SilentlyContinue
                if ($amsiValue -and $amsiValue.DisableAMSI) {
                    $detections += @{
                        Type = "Registry Tampering"
                        Path = $amsiKey
                        Risk = "Critical"
                    }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "GEDR" -EntryType Error -EventId 2004 `
                    -Message "AMSI BYPASS DETECTED: $($detection.ProcessName -or $detection.Type) - $($detection.BypassPattern -or $detection.Message)"
            }
            
            $logPath = "C:\ProgramData\GEDR\Logs\AMSIBypass_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.ProcessName -or $_.Type)|$($_.BypassPattern -or $_.Message)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) AMSI bypass attempts"
        }
    } catch {
        Write-Output "ERROR:$ModuleName`:$_"
    }
    
    return $detections.Count
}

function Start-Module {
    
    $loopSleep = Get-LoopSleep
    $maxProcs = Get-ScanLimit -LimitName "MaxProcesses"
    
    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-AMSIBypassScan
                $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
        }
    }
}
}
# endregion

# region 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 = ($proc.Name ?? "").ToLower()
            $cmd = ($proc.CommandLine ?? "").ToLower()
            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 "GEDR" -EntryType Error -EventId 2092 -Message "ATTACK TOOL: $($d.Tool) - $($d.ProcessName) (PID: $($d.ProcessId))" -ErrorAction SilentlyContinue
            }
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{ TickInterval = 90 } }
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2037 `
                    -Message "BEACON DETECTED: $($detection.Type) - $($detection.ProcessName) (PID: $($detection.ProcessId)) - $($detection.RemoteAddress -or $detection.RemoteHost)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2020 `
                    -Message "BROWSER EXTENSION: $($detection.Type) - $($detection.ExtensionName -or $detection.BrowserProcess)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region CleanGuard
# CleanGuard.ps1
# Author: Gorstak

$ErrorActionPreference = "SilentlyContinue"

# Configuration
$Config = @{
    InstallPath = "$env:ProgramData\CleanGuard"
    TaskName = "CleanGuard"
}

# Get current script path
$IsScript = $false
if ($PSCommandPath) {
    $CurrentPath = $PSCommandPath
    $IsScript = ($PSCommandPath -match '\.ps1$')
} else {
    $CurrentPath = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
    $IsScript = ($CurrentPath -match '\.ps1$')
}

# Determine installation path based on whether we're a script or exe
if ($IsScript) {
    $InstalledScriptPath = Join-Path $Config.InstallPath "CleanGuard.ps1"
    $InstallExe = $InstalledScriptPath  # For compatibility with rest of script
} else {
    $InstalledScriptPath = Join-Path $Config.InstallPath "CleanGuard.exe"
    $InstallExe = $InstalledScriptPath
}

# Check if already installed
function Test-CleanGuardInstalled {
    $task = Get-ScheduledTask -TaskName $Config.TaskName -ErrorAction SilentlyContinue
    return ($null -ne $task -and (Test-Path $InstalledScriptPath))
}

# Install CleanGuard service
function Install-CleanGuardService {
    Write-Host "Installing CleanGuard..." -ForegroundColor Cyan
    
    # Create install directory
    if (!(Test-Path $Config.InstallPath)) {
        New-Item -ItemType Directory -Path $Config.InstallPath -Force | Out-Null
    }
    
    # Copy script to ProgramData
    Copy-Item -Path $CurrentPath -Destination $InstalledScriptPath -Force
    Write-Host "Copied script to $InstalledScriptPath" -ForegroundColor Gray
    
    # Remove existing task if present
    $existingTask = Get-ScheduledTask -TaskName $Config.TaskName -ErrorAction SilentlyContinue
    if ($existingTask) {
        Write-Host "Removing existing task..." -ForegroundColor Gray
        Unregister-ScheduledTask -TaskName $Config.TaskName -Confirm:$false
    }
    
    # Create task action
    if ($IsScript) {
        $action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
            -Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$InstalledScriptPath`""
    } else {
        $action = New-ScheduledTaskAction -Execute $InstalledScriptPath
    }
    
    # Create task trigger (at startup)
    $trigger = New-ScheduledTaskTrigger -AtStartup
    
    # Create task principal (run as SYSTEM)
    $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
    
    # Create task settings
    $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries `
        -StartWhenAvailable -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
    
    # Register the task
    Register-ScheduledTask -TaskName $Config.TaskName `
        -Action $action `
        -Trigger $trigger `
        -Principal $principal `
        -Settings $settings `
        -Description "CleanGuard - Real-time file protection (Author: Gorstak)" | Out-Null
    
    Write-Host ""
    Write-Host "[SUCCESS] CleanGuard installed successfully!" -ForegroundColor Green
    
    Write-Host "Starting CleanGuard service..." -ForegroundColor Cyan
    Start-ScheduledTask -TaskName $Config.TaskName
    Start-Sleep -Seconds 2
    
    Write-Host "Service started!" -ForegroundColor Green
    Write-Host ""
    
    exit 0
}

# Auto-install if not already installed
if (!(Test-CleanGuardInstalled)) {
    Write-Host "CleanGuard is not installed. Installing now..." -ForegroundColor Yellow
    Write-Host ""
    Install-CleanGuardService
    # Function exits with exit 0
}

# If we're not running from the installed location, launch the installed version and exit
$normalizedCurrent = [System.IO.Path]::GetFullPath($CurrentPath)
$normalizedInstalled = [System.IO.Path]::GetFullPath($InstalledScriptPath)
if ($normalizedCurrent -ne $normalizedInstalled -and $normalizedCurrent.ToLower() -ne $normalizedInstalled.ToLower()) {
    if (Test-Path $InstalledScriptPath) {
        if ($IsScript) {
            Start-Process -FilePath "PowerShell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$InstalledScriptPath`"" -ErrorAction SilentlyContinue
        } else {
            Start-Process -FilePath $InstalledScriptPath -ErrorAction SilentlyContinue
        }
        exit
    }
}

$Quarantine = "$env:ProgramData\CleanGuard\Quarantine"
$Backup     = "$env:ProgramData\CleanGuard\Backup"
$LogFile    = "$env:ProgramData\CleanGuard\log.txt"
$LastFile   = "$env:ProgramData\CleanGuard\Quarantine\.last"

@($Quarantine, $Backup, (Split-Path $LogFile -Parent)) | ForEach-Object {
    if (!(Test-Path $_)) {
        New-Item -ItemType Directory -Path $_ -Force | Out-Null
    }
}

function Log($msg) {
    "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | $msg" | Out-File -FilePath $LogFile -Append -Encoding UTF8
}

Log "CleanGuard started - monitoring .exe, .dll, .sys and .winmd"

function Get-SHA256($path) {
    (Get-FileHash -Path $path -Algorithm SHA256).Hash.ToLower()
}

# Identify CleanGuard's own executable/script
# Use the installed path if available, otherwise current path
if (Test-Path $InstallExe) {
    $SelfPath = $InstallExe
} elseif ($PSCommandPath) {
    $SelfPath = $PSCommandPath
} else {
    $SelfPath = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
}
$SelfHash = Get-SHA256 $SelfPath

# Allow-list containing CleanGuard itself
$AllowList = @($SelfHash)

function Test-AllowList($hash) {
    return $AllowList -contains $hash
}

function Test-KnownGood($hash) {
    try {
        $json = Invoke-RestMethod -Uri "https://hashlookup.circl.lu/lookup/sha256/$hash" -TimeoutSec 8
        return ($json.'hashlookup:trust' -gt 50)
    } catch {
        return $false
    }
}

function Test-MalwareBazaar($hash) {
    $body = @{ query = "get_info"; hash = $hash } | ConvertTo-Json -Compress
    try {
        $resp = Invoke-RestMethod -Method Post -Uri "https://mb-api.abuse.ch/api/v1/" -Body $body -ContentType "application/json" -TimeoutSec 12
        return ($resp.query_status -eq "hash_found")
    } catch {
        return $false
    }
}

function Test-SignedByMicrosoft($path) {
    try {
        $sig = Get-AuthenticodeSignature -FilePath $path
        if ($sig.Status -eq "Valid") {
            if ($sig.SignerCertificate.Subject -match "O=Microsoft Corporation") { return $true }
            if ($sig.SignerCertificate.Thumbprint -match "109F2DD82E0C9D1E6B2B9A46B2D4B5E4F5B9F5D6|3A2F5E8F4E5D6C8B9A1F2E3D4C5B6A7F8E9D0C1B") { return $true }
        }
    } catch {}
    return $false
}

function Move-ToQuarantine($file) {
    $name = [IO.Path]::GetFileName($file)
    $ts   = Get-Date -Format "yyyyMMdd_HHmmss_fff"
    $bak  = Join-Path $Backup ($name + "_" + $ts + ".bak")
    $q    = Join-Path $Quarantine ($name + "_" + $ts)

    Copy-Item $file $bak -Force
    Move-Item $file $q -Force

    "$bak|$file" | Out-File $LastFile -Encoding UTF8

    Log "QUARANTINED -> $q"
}

function Undo-LastQuarantine {
    if (!(Test-Path $LastFile)) { return }

    $line = Get-Content $LastFile -ErrorAction SilentlyContinue
    if (-not $line) { return }

    $bak, $orig = $line.Split('|', 2)
    if (Test-Path $orig) {
        Remove-Item $orig -Force
    }
    if (Test-Path $bak) {
        Move-Item $bak $orig -Force
        $name = [IO.Path]::GetFileName($orig)
        Log "UNDO -> restored $name"
    }

    Remove-Item $LastFile -Force
}

# Real-time monitoring
$drives   = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DriveType -in (2, 3, 4) }
$watchers = @()

foreach ($drive in $drives) {
    $root = $drive.DeviceID + "\"
    Log "Setting up FileSystemWatcher for drive: $root"

    try {
        $watcher = New-Object System.IO.FileSystemWatcher
        $watcher.Path = $root
        $watcher.IncludeSubdirectories = $true
        $watcher.NotifyFilter = [System.IO.NotifyFilters]'FileName, LastWrite'
        $watchers += $watcher
    } catch {
        Log "Failed to create watcher for $root : $_"
    }
}

$action = {
    $path = $Event.SourceEventArgs.FullPath
    if ($path -notmatch '\.(exe|dll|sys|winmd)$') { return }

    Start-Sleep -Milliseconds 1200
    if (!(Test-Path $path)) { return }

    $name = [IO.Path]::GetFileName($path)
    $hash = Get-SHA256 $path

    if (Test-AllowList $hash) {
        Log "Allow-listed: $name"
        return
    }

    if (Test-KnownGood $hash) {
        Log "Known-good (CIRCL): $name"
        return
    }

    if (Test-SignedByMicrosoft $path) {
        Log "Trusted Microsoft: $name"
        return
    }

    if (Test-MalwareBazaar $hash) {
        Log "MALWARE DETECTED (MalwareBazaar): $name"
        Move-ToQuarantine $path
        return
    }

    $lower = $path.ToLower()
    if ($lower -notmatch 'c:\\windows\\|c:\\program files\\|c:\\program files \(x86\)\\|c:\\windowsapps\\') {
        Log "SUSPICIOUS unsigned file: $name - auto-quarantining"
        Move-ToQuarantine $path
    }
}

foreach ($watcher in $watchers) {
    Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action | Out-Null
    Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $action | Out-Null
    $watcher.EnableRaisingEvents = $true
}

Log "Real-time protection ACTIVE"

# Keep script alive
try {
    while ($true) {
        Start-Sleep -Seconds 3600
    }
}
finally {
    if ($watchers) {
        $watchers | ForEach-Object { $_.Dispose() }
    }
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2018 `
                    -Message "CLIPBOARD MONITORING: $($detection.Type) - $($detection.DataType -or $detection.ProcessName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2038 `
                    -Message "CODE INJECTION: $($detection.Type) - $($detection.ProcessName) (PID: $($detection.ProcessId))"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2019 `
                    -Message "COM MONITORING: $($detection.Type) - $($detection.ProcessName -or $detection.CLSID -or $detection.COMObject)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Error -EventId 2005 `
                    -Message "CREDENTIAL DUMP DETECTED: $($detection.ProcessName -or $detection.Type) - $($detection.Tool -or $detection.ObjectName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region CrudePayloadGuard
# CrudePayloadGuard.ps1 by Gorstak

function Register-SystemLogonScript {
    param (
        [string]$TaskName = "RunCrudePayloadGuardAtLogon"
    )

    # Define paths
    $scriptSource = $MyInvocation.MyCommand.Path
    if (-not $scriptSource) {
        # Fallback to determine script path
        $scriptSource = $PSCommandPath
        if (-not $scriptSource) {
            Write-Output "Error: Could not determine script path."
            return
        }
    }

    $targetFolder = "C:\Windows\Setup\Scripts\Bin"
    $targetPath = Join-Path $targetFolder (Split-Path $scriptSource -Leaf)

    # Create required folders
    if (-not (Test-Path $targetFolder)) {
        New-Item -Path $targetFolder -ItemType Directory -Force | Out-Null
        Write-Output "Created folder: $targetFolder"
    }

    # Copy the script
    try {
        Copy-Item -Path $scriptSource -Destination $targetPath -Force -ErrorAction Stop
        Write-Output "Copied script to: $targetPath"
    } catch {
        Write-Output "Failed to copy script: $_"
        return
    }

    # Define the scheduled task action and trigger
    $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"$targetPath`""
    $trigger = New-ScheduledTaskTrigger -AtLogOn
    $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest

    # Register the task
    try {
        Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
        Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal
        Write-Output "Scheduled task '$TaskName' created to run at user logon under SYSTEM."
    } catch {
        Write-Output "Failed to register task: $_"
    }
}

# Run the functionMore actions
Register-SystemLogonScript

$job = Start-Job -ScriptBlock {
    $pattern = '(?i)(<script|javascript:|onerror=|onload=|alert\()'

    function Disable-Network-Briefly {
        $adapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }
        foreach ($adapter in $adapters) {
            Disable-NetAdapter -Name $adapter.Name -Confirm:$false -ErrorAction SilentlyContinue
        }
        Start-Sleep -Seconds 3
        foreach ($adapter in $adapters) {
            Enable-NetAdapter -Name $adapter.Name -Confirm:$false -ErrorAction SilentlyContinue
        }
        Write-Host "🌐 Network briefly disabled"
    }

    function Add-XSSFirewallRule {
        try {
            $uri = [System.Uri]::new($url)
            $domain = $uri.Host
            $ruleName = "Block_XSS_$domain"

            if (-not (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue)) {
                New-NetFirewallRule -DisplayName $ruleName `
                    -Direction Outbound `
                    -Action Block `
                    -RemoteAddress $domain `
                    -Protocol TCP `
                    -Profile Any `
                    -Description "Blocked due to potential XSS in URL"
                Write-Host "🚫 Domain blocked via firewall: $domain"
            }
        } catch {
            Write-Warning "⚠️ Could not block: $url"
        }
    }

    Register-WmiEvent -Query "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'" -Action {
        $proc = $Event.SourceEventArgs.NewEvent.TargetInstance
        $cmdline = $proc.CommandLine

        if ($cmdline -match $pattern) {
            Write-Host "`n❌ Potential XSS detected in: $cmdline"

            if ($cmdline -match 'https?://[^\s"]+') {
                $url = $matches[0]
                Disable-Network-Briefly
                Add-XSSFirewallRule -url $url
            }
        }
    } | Out-Null

    while ($true) { Start-Sleep -Seconds 5 }
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2040 `
                    -Message "DATA EXFILTRATION: $($detection.Type) - $($detection.ProcessName -or 'System')"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 {
    
    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 "GEDR" -EntryType Warning -EventId 2009 `
                    -Message "DLL HIJACKING: $($detection.ProcessName -or $detection.Type) - $($detection.DllPath -or $detection.Message)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2029 `
                    -Message "DNS EXFILTRATION: $($detection.Type) - $($detection.QueryName -or $detection.ProcessName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region DriverWatcher
function Enforce-AllowedDrivers {
    param (
        [string[]]$AllowedVendors = @(
            "Microsoft",
            "Realtek",
            "Dolby",
            "Intel",
            "Advanced Micro Devices", # AMD full name
            "AMD",
            "NVIDIA",
            "MediaTek"
        )
    )

    Write-Host "Starting driver enforcement monitor..." -ForegroundColor Cyan

    Start-Job -ScriptBlock {

        while ($true) {
            try {
                # Get driver info (include InfName for pnputil)
                $drivers = Get-WmiObject Win32_PnPSignedDriver |
                           Select-Object DeviceName, Manufacturer, DriverProviderName, DriverVersion, InfName

                foreach ($driver in $drivers) {
                    $vendor = $driver.DriverProviderName

                    if ($vendor -notin $Vendors) {
                        Write-Warning "Unauthorized driver detected: $($driver.DeviceName) | Vendor: $vendor | Version: $($driver.DriverVersion)"

                        # Force delete driver package
                        try {
                            pnputil /delete-driver $driver.InfName /uninstall /force | Out-Null
                            Write-Host "Removed driver $($driver.InfName)" -ForegroundColor Yellow
                        } catch {
                            Write-Warning "Failed to remove driver $($driver.InfName)"
                        }
                    }
                }
            } catch {
                Write-Warning "Error during driver scan: $_"
            }

            # Sleep 60 seconds before next scan (adjust as needed)
            Start-Sleep -Seconds 60
        }
    } -ArgumentList ($AllowedVendors)
}
# endregion

# region 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 = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 {
    
    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 = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2026 `
                    -Message "FILELESS DETECTION: $($detection.Type) - $($detection.ProcessName -or $detection.ConsumerName -or $detection.ValueName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2024 `
                    -Message "FIREWALL RULE MONITORING: $($detection.Type) - $($detection.RuleName -or $detection.ProfileName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 = "C:\ProgramData\GEDR\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 = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -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 "GEDR" -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 = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 = $proc.CommandLine ?? ""
            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 "GEDR" -EntryType Warning -EventId 2095 -Message "IDS: $($d.Description) - $($d.ProcessName) PID:$($d.ProcessId)" -ErrorAction SilentlyContinue
            }
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{ TickInterval = 60 } }
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2012 `
                    -Message "KEYLOGGER DETECTED: $($detection.ProcessName -or $detection.Type) - $($detection.HookModules -or $detection.Type)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region KeyScramblerManagement
# Key Scrambler Management
# Anti-keylogger measures (placeholder - matches AV)


$ModuleName = "KeyScramblerManagement"

function Start-Module {
    while ($true) {
        Start-Sleep -Seconds 60
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{} }
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2039 `
                    -Message "LATERAL MOVEMENT: $($detection.Type) - $($detection.ProcessName -or $detection.Tool -or $detection.SubjectUser)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2002 `
                -Message "LOLBIN DETECTED: $($detection.ProcessName) (PID: $($detection.ProcessId)) - $($detection.Pattern)"
            
            # Log details
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 = ($proc.Name ?? "").ToLower()
            $cmd = ($proc.CommandLine ?? "") + " " + ($proc.ExecutablePath ?? "")
            
            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 "GEDR" -EntryType Error -EventId 2093 -Message "MEMORY ACQUISITION: $($d.Pattern) - $($d.ProcessName) (PID: $($d.ProcessId))" -ErrorAction SilentlyContinue
            }
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{ TickInterval = 90 } }
# endregion

# region 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 = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region MitreMapping
# MITRE ATT&CK Mapping
# Maps detections to MITRE ATT&CK and logs stats


$ModuleName = "MitreMapping"

$TechniqueMap = @{
    "HashDetection" = "T1204"
    "LOLBin" = "T1218"
    "ProcessAnomaly" = "T1055"
    "AMSIBypass" = "T1562.006"
    "CredentialDump" = "T1003"
    "MemoryAcquisition" = "T1119"
    "WMIPersistence" = "T1547.003"
    "ScheduledTask" = "T1053.005"
    "RegistryPersistence" = "T1547.001"
    "DLLHijacking" = "T1574.001"
    "TokenManipulation" = "T1134"
    "ProcessHollowing" = "T1055.012"
    "Keylogger" = "T1056.001"
    "Ransomware" = "T1486"
    "NetworkAnomaly" = "T1041"
    "Beacon" = "T1071"
    "DNSExfiltration" = "T1048"
    "Rootkit" = "T1014"
    "Clipboard" = "T1115"
    "ShadowCopy" = "T1490"
    "USB" = "T1052"
    "Webcam" = "T1125"
    "AttackTools" = "T1588"
    "AdvancedThreat" = "T1204"
    "EventLog" = "T1562.006"
    "FirewallRule" = "T1562.004"
    "Fileless" = "T1059"
    "MemoryScanning" = "T1003"
    "CodeInjection" = "T1055"
    "DataExfiltration" = "T1048"
    "FileEntropy" = "T1204"
    "Honeypot" = "T1204"
    "LateralMovement" = "T1021"
    "ProcessCreation" = "T1059"
    "YaraDetection" = "T1204"
    "IdsDetection" = "T1059"
}

function Map-ToMitre {
    $tech = $TechniqueMap[$DetectionSource]
    if ($tech) {
        $entry = @{
            Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            DetectionSource = $DetectionSource
            MITRETechnique = $tech
            Details = $Details
        }
        $logPath = "C:\ProgramData\GEDR\Logs\mitre_mapping_$(Get-Date -Format 'yyyy-MM-dd').log"
        "$($entry.Timestamp)|$($entry.DetectionSource)|$($entry.MITRETechnique)|$($entry.Details)" | Add-Content -Path $logPath -ErrorAction SilentlyContinue
        return $tech
    }
    return $null
}

function Start-Module {
    while ($true) {
        Start-Sleep -Seconds 60
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{} }
# endregion

# region 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 = "C:\ProgramData\GEDR\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 "GEDR" -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
        }
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{ TickInterval = 90 } }
# endregion

# region 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 "GEDR" -EntryType Information -EventId 2028 `
                    -Message "NAMED PIPE MONITORING: $($detection.Type) - $($detection.PipeName -or $detection.ProcessName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2015 `
                    -Message "NETWORK ANOMALY: $($detection.Type) - $($detection.ProcessName -or $detection.RemoteAddress -or $detection.Adapter)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2030 `
                    -Message "PASSWORD MANAGEMENT: $($detection.Type) - $($detection.ProcessName -or $detection.File -or $detection.Tool)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region PrivacyForgeSpoofing
<#
.SYNOPSIS
    PrivacyForge Spoofing - Identity and Fingerprint Spoofing Module
.DESCRIPTION
    Generates and rotates fake identity data to prevent browser fingerprinting
    and tracking. Spoofs software metadata, game telemetry, sensors, system
    metrics, and clipboard to create noise for trackers.
.NOTES
    Author: EDR System
    Requires: PowerShell 5.1+
    Interval: 60 seconds (default)
#>

#Requires -Version 5.1

# ===================== Configuration =====================

$Script:Config = @{
    BaseDir = "C:\ProgramData\GEDR"
    LogDir = "C:\ProgramData\GEDR\Logs"
    TickIntervalSeconds = 60
    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 =====================

function Write-AVLog {
    param(
        [string]$Message,
        [ValidateSet("INFO", "WARN", "ERROR", "DEBUG", "DETECTION")]
        [string]$Level = "INFO"
    )
    
    if ($Level -eq "DEBUG" -and -not $Script:Config.DebugMode) { return }
    
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logMessage = "[$timestamp] [$Level] [PrivacyForge] $Message"
    
    # Ensure log directory exists
    if (-not (Test-Path $Script:Config.LogDir)) {
        New-Item -ItemType Directory -Path $Script:Config.LogDir -Force | Out-Null
    }
    
    $logFile = Join-Path $Script:Config.LogDir "PrivacyForge_$(Get-Date -Format 'yyyyMMdd').log"
    Add-Content -Path $logFile -Value $logMessage -ErrorAction SilentlyContinue
    
    # Console output with color
    $color = switch ($Level) {
        "ERROR" { "Red" }
        "WARN" { "Yellow" }
        "DETECTION" { "Magenta" }
        "DEBUG" { "Gray" }
        default { "White" }
    }
    Write-Host $logMessage -ForegroundColor $color
}

# ===================== 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-AVLog "Identity rotated - Name: $($Script:PrivacyForgeIdentity.name), Username: $($Script:PrivacyForgeIdentity.username)" "INFO"
}

# ===================== 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 {
            try {
                Invoke-WebRequest -Uri "https://httpbin.org/headers" -Headers $headers -TimeoutSec 5 -UseBasicParsing -ErrorAction SilentlyContinue | Out-Null
            } catch {}
        } -ArgumentList $headers
        
        Write-AVLog "Sent spoofed software metadata headers" "DEBUG"
    } catch {
        Write-AVLog "Error spoofing software metadata - $_" "WARN"
    }
}

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-AVLog "Spoofed game telemetry - Player ID: $($fakeTelemetry.player_id)" "DEBUG"
    } catch {
        Write-AVLog "Error spoofing game telemetry - $_" "WARN"
    }
}

function Invoke-PrivacyForgeSpoofSensors {
    <#
    .SYNOPSIS
    Generates random sensor data to confuse fingerprinting
    #>
    
    try {
        $sensorData = @{
            "accelerometer" = @{
                "x" = [math]::Round((Get-Random -Minimum -1000 -Maximum 1000) / 100.0, 2)
                "y" = [math]::Round((Get-Random -Minimum -1000 -Maximum 1000) / 100.0, 2)
                "z" = [math]::Round((Get-Random -Minimum -1000 -Maximum 1000) / 100.0, 2)
            }
            "gyroscope" = @{
                "pitch" = [math]::Round((Get-Random -Minimum -18000 -Maximum 18000) / 100.0, 2)
                "roll" = [math]::Round((Get-Random -Minimum -18000 -Maximum 18000) / 100.0, 2)
                "yaw" = [math]::Round((Get-Random -Minimum -18000 -Maximum 18000) / 100.0, 2)
            }
            "magnetometer" = @{
                "x" = [math]::Round((Get-Random -Minimum -5000 -Maximum 5000) / 100.0, 2)
                "y" = [math]::Round((Get-Random -Minimum -5000 -Maximum 5000) / 100.0, 2)
                "z" = [math]::Round((Get-Random -Minimum -5000 -Maximum 5000) / 100.0, 2)
            }
            "light_sensor" = Get-Random -Minimum 0 -Maximum 1000
            "proximity_sensor" = Get-Random -InputObject @(0, 5, 10)
            "ambient_temperature" = [math]::Round((Get-Random -Minimum 1500 -Maximum 3500) / 100.0, 1)
            "battery_temperature" = [math]::Round((Get-Random -Minimum 2000 -Maximum 4000) / 100.0, 1)
        }
        
        Write-AVLog "Spoofed sensor data" "DEBUG"
    } catch {
        Write-AVLog "Error spoofing sensors - $_" "WARN"
    }
}

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-AVLog "Spoofed system metrics - CPU: $($fakeMetrics.cpu_usage)%, Memory: $($fakeMetrics.memory_usage)%" "DEBUG"
    } catch {
        Write-AVLog "Error spoofing system metrics - $_" "WARN"
    }
}

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-AVLog "Spoofed clipboard content" "DEBUG"
    } catch {
        Write-AVLog "Error spoofing clipboard - $_" "WARN"
    }
}

# ===================== 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-AVLog "Time-based rotation triggered" "INFO"
        }
        
        if ($Script:PrivacyForgeDataCollected -ge $Script:Config.DataThreshold) {
            $shouldRotate = $true
            Write-AVLog "Data threshold reached ($Script:PrivacyForgeDataCollected/$($Script:Config.DataThreshold))" "INFO"
        }
        
        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-AVLog "Spoofing active - Data collected: $Script:PrivacyForgeDataCollected/$($Script:Config.DataThreshold)" "INFO"
        
    } catch {
        Write-AVLog "Error in main spoofing loop - $_" "ERROR"
    }
}

# ===================== Main Loop =====================

Write-AVLog "========================================" "INFO"
Write-AVLog "PrivacyForge Spoofing Module Starting" "INFO"
Write-AVLog "Tick Interval: $($Script:Config.TickIntervalSeconds)s" "INFO"
Write-AVLog "Rotation Interval: $($Script:Config.RotationIntervalSeconds)s" "INFO"
Write-AVLog "Data Threshold: $($Script:Config.DataThreshold)" "INFO"
Write-AVLog "Clipboard Spoofing: $($Script:Config.EnableClipboardSpoofing)" "INFO"
Write-AVLog "Network Spoofing: $($Script:Config.EnableNetworkSpoofing)" "INFO"
Write-AVLog "========================================" "INFO"

# Initial identity generation
Invoke-PrivacyForgeRotateIdentity

while ($true) {
    try {
        Invoke-PrivacyForgeSpoofing
    } catch {
        Write-AVLog "Unhandled error: $_" "ERROR"
    }
    
    Start-Sleep -Seconds $Script:Config.TickIntervalSeconds
}
# endregion

# region 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 {
    
    $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 = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2035 `
                    -Message "PROCESS CREATION: $($detection.Type) - $($detection.ProcessName -or $detection.FilterName -or $detection.ParentProcessName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Error -EventId 2011 `
                    -Message "PROCESS HOLLOWING: $($detection.ProcessName) (PID: $($detection.ProcessId)) - $($detection.Type)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 = "C:\ProgramData\GEDR\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 "GEDR" -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}
}
}
# endregion

# region RansomwareDetection
# Ransomware Detection Module
# Detects ransomware encryption patterns


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

function Invoke-RansomwareScan {
    $detections = @()
    
    try {
        # Check for rapid file modifications (encryption indicator)
        $userDirs = @(
            "$env:USERPROFILE\Documents",
            "$env:USERPROFILE\Desktop",
            "$env:USERPROFILE\Pictures",
            "$env:USERPROFILE\Videos"
        )
        
        $recentFiles = @()
        foreach ($dir in $userDirs) {
            if (Test-Path $dir) {
                try {
                    $files = Get-ChildItem -Path $dir -Recurse -File -ErrorAction SilentlyContinue |
                        Where-Object { (Get-Date) - $_.LastWriteTime -lt [TimeSpan]::FromMinutes(5) } |
                        Select-Object -First 100
                    
                    $recentFiles += $files
                } catch { }
            }
        }
        
        # Check for files with suspicious extensions
        $suspiciousExts = @(".encrypted", ".locked", ".crypto", ".vault", ".xxx", ".zzz", ".xyz")
        $encryptedFiles = $recentFiles | Where-Object {
            $ext = $_.Extension.ToLower()
            $ext -in $suspiciousExts -or
            ($ext -notin @(".txt", ".doc", ".pdf", ".jpg", ".png") -and $ext.Length -gt 4)
        }
        
        if ($encryptedFiles.Count -gt 10) {
            $detections += @{
                Type = "Rapid File Encryption"
                EncryptedFiles = $encryptedFiles.Count
                Risk = "Critical"
            }
        }
        
        # Check for ransom notes
        $ransomNoteNames = @("readme.txt", "decrypt.txt", "how_to_decrypt.txt", "recover.txt", "restore.txt", "!!!readme!!!.txt")
        foreach ($file in $recentFiles) {
            if ($file.Name -in $ransomNoteNames) {
                $detections += @{
                    File = $file.FullName
                    Type = "Ransom Note Detected"
                    Risk = "Critical"
                }
            }
        }
        
        # Check for processes with high file I/O
        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 processes with unusual file activity
                    $ioStats = Get-Counter "\Process($($proc.Name))\IO Data Operations/sec" -ErrorAction SilentlyContinue
                    if ($ioStats -and $ioStats.CounterSamples[0].CookedValue -gt 1000) {
                        # High I/O activity
                        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
                                    IOOperations = $ioStats.CounterSamples[0].CookedValue
                                    Type = "High File I/O - Unsigned Process"
                                    Risk = "High"
                                }
                            }
                        }
                    }
                } catch {
                    continue
                }
            }
        } catch { }
        
        # Check for shadow copy deletion
        try {
            $shadowCopies = Get-CimInstance Win32_ShadowCopy -ErrorAction SilentlyContinue
            if ($shadowCopies.Count -eq 0 -and (Test-Path "C:\Windows\System32\vssadmin.exe")) {
                $detections += @{
                    Type = "Shadow Copies Deleted"
                    Risk = "Critical"
                }
            }
        } catch { }
        
        # Check for crypto API usage
        try {
            $processes = Get-Process -ErrorAction SilentlyContinue
            foreach ($proc in $processes) {
                $modules = $proc.Modules | Where-Object {
                    $_.ModuleName -match "crypt32|cryptsp|cryptnet|bcrypt"
                }
                
                if ($modules.Count -gt 0) {
                    # Check if process is accessing many files
                    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" }
                        
                        if ($fileHandles.Count -gt 50) {
                            $detections += @{
                                ProcessId = $proc.Id
                                ProcessName = $proc.ProcessName
                                FileHandles = $fileHandles.Count
                                Type = "Cryptographic API with High File Access"
                                Risk = "High"
                            }
                        }
                    } catch { }
                }
            }
        } catch { }
        
        if ($detections.Count -gt 0) {
            foreach ($detection in $detections) {
                Write-EventLog -LogName Application -Source "GEDR" -EntryType Error -EventId 2014 `
                    -Message "RANSOMWARE DETECTED: $($detection.Type) - $($detection.ProcessName -or $detection.File -or $detection.EncryptedFiles)"
            }
            
            $logPath = "C:\ProgramData\GEDR\Logs\Ransomware_$(Get-Date -Format 'yyyy-MM-dd').log"
            $detections | ForEach-Object {
                "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|$($_.Type)|$($_.Risk)|$($_.ProcessName -or $_.File -or $_.EncryptedFiles)" |
                    Add-Content -Path $logPath
            }
            
            Write-Output "DETECTION:$ModuleName`:Found $($detections.Count) ransomware 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-RansomwareScan
                $LastTick = $now
                Write-Output "STATS:$ModuleName`:Detections=$count"
            }
            Start-Sleep -Seconds 5
        } catch {
            Write-Output "ERROR:$ModuleName`:$_"
            Start-Sleep -Seconds 10
        }
    }
}
}
# endregion

# region RealTimeFileMonitor
# Real-Time File Monitor
# FileSystemWatcher for exe/dll/sys/winmd on fixed and removable drives


$ModuleName = "RealTimeFileMonitor"
$Watchers = @()

function Start-RealtimeMonitor {
    $extensions = @("*.exe", "*.dll", "*.sys", "*.winmd")
    $drives = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Root -match '^[A-Z]:\\$' }
    
    foreach ($drive in $drives) {
        $root = $drive.Root
        if (-not (Test-Path $root)) { continue }
        
        try {
            $watcher = New-Object System.IO.FileSystemWatcher
            $watcher.Path = $root
            $watcher.IncludeSubdirectories = $true
            $watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor [System.IO.NotifyFilters]::LastWrite
            
            $action = {
                $path = $Event.SourceEventArgs.FullPath
                $ext = [System.IO.Path]::GetExtension($path).ToLower()
                if ($ext -in @(".exe", ".dll", ".sys", ".winmd")) {
                    Start-Sleep -Seconds 1
                    if (Test-Path $path) {
                        try {
                            $hash = (Get-FileHash -Path $path -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
                            $logPath = "C:\ProgramData\GEDR\Logs\realtime_monitor_$(Get-Date -Format 'yyyy-MM-dd').log"
                            "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')|Created/Changed|$path|$hash" | Add-Content -Path $logPath -ErrorAction SilentlyContinue
                            Write-EventLog -LogName Application -Source "GEDR" -EntryType Warning -EventId 2090 -Message "REAL-TIME: $path" -ErrorAction SilentlyContinue
                        } catch { }
                    }
                }
            }
            
            Register-ObjectEvent $watcher Created -Action $action | Out-Null
            Register-ObjectEvent $watcher Changed -Action $action | Out-Null
            $watcher.EnableRaisingEvents = $true
            $script:Watchers += $watcher
            Write-Output "STATS:$ModuleName`:Watching $root"
        } catch {
            Write-Output "ERROR:$ModuleName`:Failed to watch $root - $_"
        }
    }
    
    Write-Output "STATS:$ModuleName`:Started with $($script:Watchers.Count) watchers"
}
# endregion

# region 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 "GEDR" -EntryType Error -EventId 2036 `
                    -Message "REFLECTIVE DLL INJECTION: $($detection.Type) - $($detection.ProcessName) (PID: $($detection.ProcessId))"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 {
    
    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 "GEDR" -EntryType Warning -EventId 2008 `
                    -Message "REGISTRY PERSISTENCE: $($detection.RegistryPath)\$($detection.ValueName) - $($detection.Value)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2100 `
                        -Message $alertMsg
                    $results += "Alert sent: $alertMsg"
                }
                
                "Log" {
                    # Already logged, but add to response log
                    $logPath = "C:\ProgramData\GEDR\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 = "C:\ProgramData\GEDR\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 "GEDR_$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 "GEDR" -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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Error -EventId 2017 `
                    -Message "ROOTKIT DETECTED: $($detection.Type) - $($detection.ProcessName -or $detection.DriverName -or $detection.Directory)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2007 `
                    -Message "SUSPICIOUS TASK: $($detection.TaskName) - $($detection.Reasons -join ', ')"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2025 `
                    -Message "SERVICE MONITORING: $($detection.Type) - $($detection.ServiceName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2021 `
                    -Message "SHADOW COPY MONITORING: $($detection.Type) - $($detection.ProcessName -or $detection.Volume -or $detection.Message)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2010 `
                    -Message "TOKEN MANIPULATION: $($detection.ProcessName -or $detection.Type) - $($detection.Tool -or $detection.TargetUser)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Information -EventId 2022 `
                    -Message "USB MONITORING: $($detection.Type) - $($detection.DeviceName -or $detection.ProcessName -or $detection.DriverName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2031 `
                    -Message "WEBCAM GUARDIAN: $($detection.Type) - $($detection.ProcessName -or $detection.AppName)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 "GEDR" -EntryType Warning -EventId 2006 `
                    -Message "WMI PERSISTENCE DETECTED: $($detection.ConsumerName -or $detection.FilterName -or $detection.Namespace) - $($detection.Type)"
            }
            
            $logPath = "C:\ProgramData\GEDR\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
        }
    }
}
}
# endregion

# region 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 = @("C:\ProgramData\GEDR\Yara", "C:\ProgramData\GEDR\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 "GEDR" -EntryType Warning -EventId 2096 -Message "YARA: $($d.File) - $($d.Match)" -ErrorAction SilentlyContinue
        }
        $logPath = "C:\ProgramData\GEDR\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
        }
    }
}

if (-not $ModuleConfig) { Start-Module -Config @{ TickInterval = 120 } }
# endregion

# region 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

#Requires -RunAsAdministrator

param(
    [Parameter(Mandatory=$false)]
    [string[]]$AllowedDomains = @(),
    [Parameter(Mandatory=$false)]
    [switch]$AutoStart = $false,
    [Parameter(Mandatory=$false)]
    [switch]$RemoveRules = $false
)

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"
    }
}

if ($RemoveRules) {
    Remove-BlockedRules
    exit 0
}

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

# 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 }

try {
    Write-ColorOutput "============================================================" "Cyan"
    Write-ColorOutput "     GFocus - Network Traffic Monitor                      " "Cyan"
    Write-ColorOutput "============================================================" "Cyan"
    Write-ColorOutput ""
    foreach ($Domain in $AllowedDomains) { Add-AllowedDomain -Domain $Domain }
    Start-ConnectionMonitoring
} catch {
    Write-ColorOutput "Error: $($_.Exception.Message)" "Red"
} finally {
    Stop-Monitoring
}


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:GFocusSeen.ContainsKey($Key)) { continue }
        $script:GFocusSeen[$Key] = $true
        try {
            $Process = Get-Process -Id $Conn.OwningProcess -ErrorAction Stop
            $ProcessName = $Process.ProcessName
            $ProcessPath = $Process.Path
        } catch { $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) }
}
# endregion


# --- Scheduler: run all modules by interval ---
$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) {
    Remove-BlockedRules
    exit 0
}

# Run Initializer once
Invoke-Initialization | Out-Null

# Optional: start RealTimeFileMonitor watchers (event-based)
if (Get-Command Start-RealtimeMonitor -ErrorAction SilentlyContinue) {
    Start-RealtimeMonitor | 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