# encoding: utf-8 # api: powershell # title: # description: My old bytes module with some extra functions from SANS all wrapped up into a single module. # version: 0.1 # type: class # license: CC0 # function: Shift-Left # x-poshcode-id: 1729 # x-archived: 2016-03-10T10:09:48 # # #requires -version 2.0 Add-Type @" public class Shift { public static int Right(int x, int count) { return x >> count; } public static uint Right(uint x, int count) { return x >> count; } public static long Right(long x, int count) { return x >> count; } public static ulong Right(ulong x, int count) { return x >> count; } public static int Left(int x, int count) { return x << count; } public static uint Left(uint x, int count) { return x << count; } public static long Left(long x, int count) { return x << count; } public static ulong Left(ulong x, int count) { return x << count; } } "@ #.Example # Shift-Left 16 1 ## returns 32 #.Example # 8,16 |Shift-Left ## returns 16,32 function Shift-Left { PARAM( $x=1, $y ) BEGIN { if($y) { [Shift]::Left( $x, $y ) } } PROCESS { if($_){ [Shift]::Left($_, $x) } } } #.Example # Shift-Right 8 1 ## returns 4 #.Example # 2,4,8 |Shift-Right 2 ## returns 0,1,2 function Shift-Right { PARAM( $x=1, $y ) BEGIN { if($y) { [Shift]::Right( $x, $y ) } } PROCESS { if($_){ [Shift]::Right($_, $x) } } }function Write-FileByte { ################################################################ #.Synopsis #  Overwrites or creates a file with an array of raw bytes. #.Parameter ByteArray #  System.Byte[] array of bytes to put into the file.  If you #  pipe this array in, you must pipe the [Ref] to the array. #.Parameter Path #  Path to the file as a string or as System.IO.FileInfo object. #  Path as a string can be relative, absolute, or a simple file #  name if the file is in the present working directory. #.Example #  write-filebyte -bytearray $bytes -path outfile.bin #.Example #  [Ref] $bytes | write-filebyte -path c:\temp\outfile.bin ################################################################ [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [System.Byte[]] $ByteArray, [Parameter(Mandatory = $True)] $Path ) if ($Path -is [System.IO.FileInfo]) { $Path = $Path.FullName } elseif ($Path -notlike "*\*") #Simple file name. { $Path = "$pwd" + "\" + "$Path" } elseif ($Path -like ".\*")  #pwd of script { $Path = $Path -replace "^\.",$pwd.Path } elseif ($Path -like "..\*") #parent directory of pwd of script { $Path = $Path -replace "^\.\.",$(get-item $pwd).Parent.FullName } else { throw "Cannot resolve path!" } [System.IO.File]::WriteAllBytes($Path, $ByteArray) } function Convert-HexStringToByteArray { ################################################################ #.Synopsis #  Convert a string of hex data into a System.Byte[] array. An #  array is always returned, even if it contains only one byte. #.Parameter String #  A string containing hex data in any of a variety of formats, #  including strings like the following, with or without extra #  tabs, spaces, quotes or other non-hex characters: #     0x41,0x42,0x43,0x44 #     \x41\x42\x43\x44 #     41-42-43-44 #     41424344 #  The string can be piped into the function too. ################################################################ [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [String] $String ) #Clean out whitespaces and any other non-hex crud. $String = $String.ToLower() -replace '[^a-f0-9\\\,x\-\:]','' #Try to put into canonical colon-delimited format. $String = $String -replace '0x|\\x|\-|,',':' #Remove beginning and ending colons, and other detritus. $String = $String -replace '^:+|:+$|x|\\','' #Maybe there's nothing left over to convert... if ($String.Length -eq 0) { ,@() ; return } #Split string with or without colon delimiters. if ($String.Length -eq 1) { ,@([System.Convert]::ToByte($String,16)) } elseif (($String.Length % 2 -eq 0) -and ($String.IndexOf(":") -eq -1)) { ,@($String -split '([a-f0-9]{2})' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}}) } elseif ($String.IndexOf(":") -ne -1) { ,@($String -split ':+' | foreach-object {[System.Convert]::ToByte($_,16)}) } else { ,@() } #The strange ",@(...)" syntax is needed to force the output into an #array even if there is only one element in the output (or none). } function Convert-ByteArrayToHexString { ################################################################ #.Synopsis #  Returns a hex representation of a System.Byte[] array as #  one or more strings.  Hex format can be changed. #.Parameter ByteArray #  System.Byte[] array of bytes to put into the file.  If you #  pipe this array in, you must pipe the [Ref] to the array. #  Also accepts a single Byte object instead of Byte[]. #.Parameter Width #  Number of hex characters per line of output. #.Parameter Delimiter #  How each pair of hex characters (each byte of input) will be #  delimited from the next pair in the output.  The default #  looks like "0x41,0xFF,0xB9" but you could specify "\x" if #  you want the output like "\x41\xFF\xB9" instead.  You do #  not have to worry about an extra comma, semicolon, colon #  or tab appearing before each line of output.  The default #  value is ",0x". #.Parameter Prepend #  An optional string you can prepend to each line of hex #  output, perhaps like '$x += ' to paste into another #  script, hence the single quotes. #.Parameter AddQuotes #  An switch which will enclose each line in double-quotes. #.Example #  [Byte[]] $x = 0x41,0x42,0x43,0x44 #  Convert-ByteArrayToHexString $x # #  0x41,0x42,0x43,0x44 #.Example #  [Byte[]] $x = 0x41,0x42,0x43,0x44 #  Convert-ByteArrayToHexString $x -width 2 -delimiter "\x" -addquotes # #  "\x41\x42" #  "\x43\x44" ################################################################ [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [System.Byte[]] $ByteArray, [Parameter()] [Int] $Width = 10, [Parameter()] [String] $Delimiter = ",0x", [Parameter()] [String] $Prepend = "", [Parameter()] [Switch] $AddQuotes ) if ($Width -lt 1) { $Width = 1 } if ($ByteArray.Length -eq 0) { Return } $FirstDelimiter = $Delimiter -Replace "^[\,\;\:\t]","" $From = 0 $To = $Width - 1 Do { $String = [System.BitConverter]::ToString($ByteArray[$From..$To]) $String = $FirstDelimiter + ($String -replace "\-",$Delimiter) if ($AddQuotes) { $String = '"' + $String + '"' } if ($Prepend -ne "") { $String = $Prepend + $String } $String $From += $Width $To += $Width } While ($From -lt $ByteArray.Length) } function Convert-ByteArrayToString { ################################################################ #.Synopsis #  Returns the string representation of a System.Byte[] array. #  ASCII string is the default, but Unicode, UTF7, UTF8 and #  UTF32 are available too. #.Parameter ByteArray #  System.Byte[] array of bytes to put into the file.  If you #  pipe this array in, you must pipe the [Ref] to the array. #  Also accepts a single Byte object instead of Byte[]. #.Parameter Encoding #  Encoding of the string: ASCII, Unicode, UTF7, UTF8 or UTF32. #  ASCII is the default. ################################################################ [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [System.Byte[]] $ByteArray, [Parameter()] [String] $Encoding = "ASCII" ) switch ( $Encoding.ToUpper() ) { "ASCII"   { $EncodingType = "System.Text.ASCIIEncoding" } "UNICODE" { $EncodingType = "System.Text.UnicodeEncoding" } "UTF7"    { $EncodingType = "System.Text.UTF7Encoding" } "UTF8"    { $EncodingType = "System.Text.UTF8Encoding" } "UTF32"   { $EncodingType = "System.Text.UTF32Encoding" } Default   { $EncodingType = "System.Text.ASCIIEncoding" } } $Encode = new-object $EncodingType $Encode.GetString($ByteArray) } function Get-FileHex { ################################################################ #.Synopsis #  Display the hex dump of a file. #.Parameter Path #  Path to file as a string or as a System.IO.FileInfo object; #  object can be piped into the function, string cannot. #.Parameter Width #  Number of hex bytes shown per line (default = 16). #.Parameter Count #  Number of bytes in the file to process (default = all). #.Parameter NoOffset #  Switch to suppress offset line numbers in output. #.Parameter NoText #  Switch to suppress ASCII translation of bytes in output. ################################################################ [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [Alias("FullName","FilePath")] $Path, [Parameter()] [Int] $Width = 16, [Parameter()] [Int] $Count = -1, [Parameter()] [Switch] $NoOffset, [Parameter()] [Switch] $NoText ) $linecounter = 0        # Offset from beginning of file in hex. $placeholder = "."      # What to print when byte is not a letter or digit. get-content $path -encoding byte -readcount $width -totalcount $count | foreach-object { $paddedhex = $asciitext = $null $bytes = $_        # Array of [Byte] objects that is $width items in length. foreach ($byte in $bytes) { $byteinhex = [String]::Format("{0:X}", $byte)     # Convert byte to hex, e.g., "F". $paddedhex += $byteinhex.PadLeft(2,"0") + " "     # Pad with zero to force 2-digit length, e.g., "0F ". } # Total bytes in file unlikely to be evenly divisible by $width, so fix last line. # Hex output width is '$width * 3' because of the extra spaces added around hex characters. if ($paddedhex.length -lt $width * 3) { $paddedhex = $paddedhex.PadRight($width * 3," ") } foreach ($byte in $bytes) { if ( [Char]::IsLetterOrDigit($byte) -or [Char]::IsPunctuation($byte) -or [Char]::IsSymbol($byte) ) { $asciitext += [Char] $byte } else { $asciitext += $placeholder } } $offsettext = [String]::Format("{0:X}", $linecounter) # Linecounter in hex too. $offsettext = $offsettext.PadLeft(8,"0") + "h:"       # Pad linecounter with left zeros. $linecounter += $width                                # Increment linecounter, each line representing $width bytes. if (-not $NoOffset) { $paddedhex = "$offsettext $paddedhex" } if (-not $NoText) { $paddedhex = $paddedhex + $asciitext } $paddedhex } } function Toggle-Endian { ################################################################ #.Synopsis #  Swaps the ordering of bytes in an array where each swappable #  unit can be one or more bytes, and, if more than one, the #  ordering of the bytes within that unit is NOT swapped. Can #  be used to toggle between little- and big-endian formats. #  Cannot be used to swap nibbles or bits within a single byte. #.Parameter ByteArray #  System.Byte[] array of bytes to be rearranged.  If you #  pipe this array in, you must pipe the [Ref] to the array, but #  a new array will be returned (originally array untouched). #.Parameter SubWidthInBytes #  Defaults to 1 byte.  Defines the number of bytes in each unit #  (or atomic element) which is swapped, but no swapping occurs #  within that unit.  The number of bytes in the ByteArray must #  be evenly divisible by SubWidthInBytes. #.Example #  $bytearray = toggle-endian $bytearray #.Example #  [Ref] $bytearray | toggle-endian -SubWidthInBytes 2 ################################################################ [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [System.Byte[]] $ByteArray, [Parameter()] [Int] $SubWidthInBytes = 1 ) if ($ByteArray.count -eq 1 -or $ByteArray.count -eq 0) { $ByteArray ; return } if ($SubWidthInBytes -eq 1) { [System.Array]::Reverse($ByteArray); $ByteArray ; return } if ($ByteArray.count % $SubWidthInBytes -ne 0) { throw "ByteArray size must be an even multiple of SubWidthInBytes!" ; return }   $newarray = new-object System.Byte[] $ByteArray.count # $i tracks ByteArray from head, $j tracks NewArray from end. for ($($i = 0; $j = $newarray.count - 1) ; $i -lt $ByteArray.count ; $($i += $SubWidthInBytes; $j -= $SubWidthInBytes)) { for ($k = 0 ; $k -lt $SubWidthInBytes ; $k++) { $newarray[$j - ($SubWidthInBytes - 1) + $k] = $ByteArray[$i + $k] } } $newarray } function PushToTcpPort { param ([Byte[]] $bytearray, [String] $ipaddress, [Int32] $port) $tcpclient = new-object System.Net.Sockets.TcpClient($ipaddress, $port) -ErrorAction "SilentlyContinue" trap { "Failed to connect to $ipaddress`:$port" ; return } $networkstream = $tcpclient.getstream() #write(payload,starting offset,number of bytes to send) $networkstream.write($bytearray,0,$bytearray.length) $networkstream.close(1) #Wait 1 second before closing TCP session. $tcpclient.close() }