24/7/365 Support

Parse and Manage Binary Files in Windows PowerShell

Problem

You want to work with binary data in a file.

Solution

Two main techniques are used when working with binary data in a file. The first is to read the file using the Byte encoding, so that PowerShell does not treat the content as text. The second is to use the BitConverter class to translate these bytes back and forth into numbers that you more commonly care about.

Example 73 displays the “characteristics” of a Windows executable. The beginning section of any executable (a .DLL, .EXE, and several others) starts with a binary section known as the PE (portable executable) header. Part of this header includes characteristics about that file—such as whether the file is a DLL.

For more information about the PE header format, see http://www.microsoft.com/ whdc/system/platform/firmware/PECOFF.mspx.

Example 73. GetCharacteristics.ps1

############################################################################## ## ## GetCharacteristics.ps1 ## ## Get the file characteristics of a file in the PE Executable File Format. ## ## ie: ## ## PS >GetCharacteristics $env:WINDIR\notepad.exe ## IMAGE_FILE_LOCAL_SYMS_STRIPPED ## IMAGE_FILE_RELOCS_STRIPPED ## IMAGE_FILE_EXECUTABLE_IMAGE

Example 73. GetCharacteristics.ps1 (continued)

## IMAGE_FILE_32BIT_MACHINE ## IMAGE_FILE_LINE_NUMS_STRIPPED ## ##############################################################################

param([string] $filename = $(throw "Please specify a filename."))

## Define the characteristics used in the PE file file header. ## Taken from http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx $characteristics = @{} $characteristics["IMAGE_FILE_RELOCS_STRIPPED"] = 0x0001 $characteristics["IMAGE_FILE_EXECUTABLE_IMAGE"] = 0x0002 $characteristics["IMAGE_FILE_LINE_NUMS_STRIPPED"] = 0x0004 $characteristics["IMAGE_FILE_LOCAL_SYMS_STRIPPED"] = 0x0008 $characteristics["IMAGE_FILE_AGGRESSIVE_WS_TRIM"] = 0x0010 $characteristics["IMAGE_FILE_LARGE_ADDRESS_AWARE"] = 0x0020 $characteristics["RESERVED"] = 0x0040 $characteristics["IMAGE_FILE_BYTES_REVERSED_LO"] = 0x0080 $characteristics["IMAGE_FILE_32BIT_MACHINE"] = 0x0100 $characteristics["IMAGE_FILE_DEBUG_STRIPPED"] = 0x0200 $characteristics["IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP"] = 0x0400 $characteristics["IMAGE_FILE_NET_RUN_FROM_SWAP"] = 0x0800 $characteristics["IMAGE_FILE_SYSTEM"] = 0x1000 $characteristics["IMAGE_FILE_DLL"] = 0x2000 $characteristics["IMAGE_FILE_UP_SYSTEM_ONLY"] = 0x4000 $characteristics["IMAGE_FILE_BYTES_REVERSED_HI"] = 0x8000

## Get the content of the file, as an array of bytes $fileBytes = GetContent $filename ReadCount 0 Encoding byte

## The offset of the signature in the file is stored at location 0x3c. $signatureOffset = $fileBytes[0x3c]

## Ensure it is a PE file $signature = [char[]] $fileBytes[$signatureOffset..($signatureOffset + 3)] if([String]::Join('', $signature) ne "PE`0`0") {

throw "This file does not conform to the PE specification." }

## The location of the COFF header is 4 bytes into the signature $coffHeader = $signatureOffset + 4

## The characteristics data are 18 bytes into the COFF header. The BitConverter ## class manages the conversion of the 4 bytes into an integer. $characteristicsData = [BitConverter]::ToInt32($fileBytes, $coffHeader + 18)

## Go through each of the characteristics. If the data from the file has that ## flag set, then output that characteristic. foreach($key in $characteristics.Keys)

Example 73. GetCharacteristics.ps1 (continued)

{ $flag = $characteristics[$key] if(($characteristicsData band $flag) eq $flag) {

$key } }

Discussion

For most files, this technique is the easiest way to work with binary data. If you actually modify the binary data, then you will also want to use the Byte encoding when you send it back to disk:

$fileBytes | SetContent modified.exe Encoding Byte

For extremely large files, though, it may be unacceptably slow to load the entire file into memory when you work with it. If you begin to run against this limit, the solution is to use file management classes from the .NET Framework. These classes include BinaryReader, StreamReader, and others.

Help Category:

Get Windows Dedicated Server

Only reading will not help you, you have to practice it! So get it now.

Processor RAM Storage Server Detail
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 1 TB (HDD SATA) Configure Server
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 128 GB (SSD SATA) Configure Server
Intel Atom C2750 2.4 GHz 8c/8t 8 GB DDR3 1× 1 TB (HDD SATA) Configure Server
Intel Xeon E3-1230 v2 3.3 GHz 4c/8t 16 GB DDR3 1× 256 GB (SSD SATA) Configure Server
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 250 GB (SSD SATA) Configure Server

What Our Clients Say