Get-XorRegularExpression.ps1
<#PSScriptInfo
.VERSION 1.0 .GUID a05e7971-f270-48c5-b32c-6695e5f18863 .AUTHOR Lee Holmes .DESCRIPTION Get a regular expression that can be used to search for content that has been XOR encoded #> param( ## The value that we would like to search for in XOR encoded content [Parameter(Mandatory)] $Value, ## True if we should look for Unicode encodings of the string. Otherwise, ## assumed to be OEM / Default encoding [Parameter()] [Switch] $Unicode, ## True if we should emit the raw bytes for each XOR encoding [Parameter()] [Switch] $Raw ) ## Holds the various byte representations of what we're searching for $byteRepresentations = @() ## If we got a string, look for the representation of the string if($Value -is [String]) { if($Unicode.IsPresent) { $byteRepresentations += ,[Byte[]] [System.Text.Encoding]::Unicode.GetBytes($Value) } else { $byteRepresentations += ,[Byte[]] [System.Text.Encoding]::Default.GetBytes($Value) } } ## If it was a byte array directly, look for the byte representations if($Value -is [byte[]]) { $byteRepresentations += ,$Value } ## Find the safe searchable sequences for each XOR representation of input bytes $xorByteSequences = foreach($bytes in $byteRepresentations) { ## XOR encode what we're looking for with every possible key foreach($xorKey in 1..255) { $outputBytes = [byte[]] $(foreach($byte in $bytes) { $byte -bxor $xorKey }) ,$outputBytes } } if($Raw.IsPresent) { $xorByteSequences } else { $xorSequences = foreach($xorByteSequence in @($xorByteSequences)) { ## Basic EOM encoding $string = -join ([char[]]$xorByteSequence) $string = [Regex]::Escape($string) $string = [Regex]::Replace($string, '\p{C}', { "\x{0}" -f [Convert]::ToString([int][char]$args[0].Value, 16).PadLeft(2, '0') }) ## Ignore the original string (i.e.: if the XOR key was 0x20) if($string -ne $Value) { $string } } ## Output a regular expression for these sequences "(" + (($xorSequences | Sort-Object -Unique) -join "|") + ")" } |