# Obfuscate-PSScript.ps1 # A Multi-Layer PowerShell Script Obfuscator for Windows 11 # Author: Andreas Nilsen # Email: adde88@gmail.com # GitHub: https://github.com/adde88 # Twitter/X: @adde88 # Date: 06. September 2025 # License: Creative Commons Attribution-NonCommercial (CC BY-NC) # You are free to share and adapt, but must: # - Attribute the original author # - Not use it for commercial purposes # This script is provided "as-is" without warranty. param( [Parameter(Mandatory = $true)] [string]$InputScriptPath, [Parameter(Mandatory = $false)] [string]$OutputPath = "obfuscated.ps1" ) function Get-ScriptContent { param([string]$Path) if (-not (Test-Path -Path $Path -PathType Leaf)) { throw "Input script file not found: $Path" } return [System.IO.File]::ReadAllText($Path) } function Set-ScriptContent { param([string]$Path, [string]$Content) [System.IO.File]::WriteAllText($Path, $Content) } # --- Token Obfuscation --- function Obfuscate-Tokens { param([string]$Script) $tokenMap = @{ "if" = "when" "else" = "otherwise" "for" = "loop" "foreach" = "each" "while" = "until" "switch" = "choose" "break" = "exit" "continue" = "skip" "function" = "make" "param" = "input" "return" = "give" "throw" = "fail" "try" = "attempt" "catch" = "handle" "finally" = "end" } $Script = $Script -replace '\b(if|else|for|foreach|while|switch|break|continue|function|param|return|throw|try|catch|finally)\b', { $match = $_.ToString() if ($tokenMap.ContainsKey($match)) { return $tokenMap[$match] } return $match } $Script = $Script -replace '\b\+\+|\-\-|\*\*|\|\||&|&&|\|\|','{op}' return $Script } # --- String Obfuscation --- function Obfuscate-Strings { param([string]$Script) $substitution = @{ 'A' = 'P'; 'B' = 'Q'; 'C' = 'R'; 'D' = 'S' 'E' = 'T'; 'F' = 'U'; 'G' = 'V'; 'H' = 'W' 'I' = 'X'; 'J' = 'Y'; 'K' = 'Z'; 'L' = 'A' 'M' = 'B'; 'N' = 'C'; 'O' = 'D'; 'P' = 'E' 'Q' = 'F'; 'R' = 'G'; 'S' = 'H'; 'T' = 'I' } $Script = $Script -replace '\b([a-zA-Z]+)\b', { $match = $_.ToString() if ($match -match '^[a-zA-Z]+$') { $result = "" for ($i = 0; $i -lt $match.Length; $i++) { $c = $match[$i] $result += $substitution[$c] -or $c } return $result } return $match } $Script = $Script -replace 'Write-Host', 'Show-Text' $Script = $Script -replace 'Get-Process', 'Fetch-Task' return $Script } # --- Encoding with XOR + UTF16 --- function Encode-WithXORKey { param([string]$Script, [string]$Key) $bytes = [System.Text.Encoding]::UTF16LE.GetBytes($Script) $keyBytes = [System.Text.Encoding]::UTF8.GetBytes($Key) $xoredBytes = for ($i = 0; $i -lt $bytes.Length; $i++) { $bytes[$i] ^ $keyBytes[$i % $keyBytes.Length] } return [System.Convert]::ToBase64String($xoredBytes) } # --- Compression --- function Compress-Script { param([string]$Script) $bytes = [System.Text.Encoding]::UTF16LE.GetBytes($Script) $compressed = [System.IO.Compression.GZipStream]::Compress($bytes) return [System.Convert]::ToBase64String($compressed) } # --- Custom XOR Layer --- function Apply-XORLayer { param([string]$Script, [string]$FileName) $key = "$FileName" + (Get-Date).ToString("HHmmss") $encoded = Encode-WithXORKey -Script $Script -Key $key return $encoded } # --- Dynamic Contextual Token Substitution --- function Obfuscate-ContextualTokens { param([string]$Script) $user = [Security.Principal.WindowsIdentity]::GetCurrent().Name $osVersion = [Environment]::OSVersion.Version.ToString() $machineName = [System.Environment]::MachineName $timeOfDay = if ((Get-Date).Hour -ge 6 -and (Get-Date).Hour -lt 18) { "day" } else { "night" } $Script = $Script -replace 'user', "[$(if ($user -match 'DOMAIN') { 'domain' } else { 'local' })]" $Script = $Script -replace 'os', "v$(($osVersion -split '\.')[0])" $Script = $Script -replace 'machine', "$machineName" $Script = $Script -replace 'time', "[$timeOfDay]" return $Script } # --- Self-Decoding Function --- function Decode-ObfuscatedScript { param([string]$EncodedScript, [string]$Key) $bytes = [System.Convert]::FromBase64String($EncodedScript) $keyBytes = [System.Text.Encoding]::UTF8.GetBytes($Key) $decoded = for ($i = 0; $i -lt $bytes.Length; $i++) { $bytes[$i] ^ $keyBytes[$i % $keyBytes.Length] } return [System.Text.Encoding]::UTF16LE.GetString($decoded) } # --- Final Output Script --- function Generate-ExecutableObfuscatedScript { param([string]$OriginalScript) # Apply layers $script = Obfuscate-Tokens -Script $OriginalScript $script = Obfuscate-Strings -Script $script $key = "ObfuscateKey" + (Get-Date).ToString("yyyyMMddHHmmss") $encoded = Apply-XORLayer -Script $script -FileName "MyScript" $compressed = Compress-Script -Script $script # Final script with decoder $finalScript = @" # =================================================== # GENERATED BY: Obfuscate-PSScript.ps1 # DATE: $(Get-Date) # ENVIRONMENT: $($env:COMPUTERNAME) | USER: $($env:USERNAME) # LAYERS: Token, String, Encoding (UTF-16), Compression, XOR, Contextual # =================================================== # DECODER FUNCTION $encoded = 'XOR+Compressed+Encoded+Contextual' $decodedScript = Decode-ObfuscatedScript -EncodedScript $encoded -Key '$key' # Reconstruct original script $original = $decodedScript # Execute the script Invoke-Expression $original # =================================================== "@ return $finalScript } # --- Main Execution --- try { $originalScript = Get-ScriptContent -Path $InputScriptPath # Generate final obfuscated and executable script $finalScript = Generate-ExecutableObfuscatedScript -OriginalScript $originalScript Set-ScriptContent -Path $OutputPath -Content $finalScript Write-Host "✅ Obfuscation completed successfully!" -ForegroundColor Green Write-Host "📄 Output saved to: $OutputPath" -ForegroundColor Yellow Write-Host "💡 To run: PowerShell -File $OutputPath" -ForegroundColor Cyan } catch { Write-Error "❌ Error during obfuscation: $_" exit 1 }