Created
February 28, 2019 23:48
-
-
Save Trucido/2aa287d29f9d65f047549a3833e8f22d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Get-PECharacteristics.ps1 | |
<# | |
.SYNOPSIS | |
Get the file characteristics of a PE Executable. | |
.EXAMPLE | |
PS > Get-PECharacteristics $env:WINDIR\notepad.exe | |
IMAGE_FILE_LOCAL_SYMS_STRIPPED | |
IMAGE_FILE_RELOCS_STRIPPED | |
IMAGE_FILE_EXECUTABLE_IMAGE | |
IMAGE_FILE_32BIT_MACHINE | |
IMAGE_FILE_LINE_NUMS_STRIPPED | |
#> | |
function Get-PECharacteristics | |
{ | |
param( | |
[Parameter(Mandatory = $true, ValueFromPipeline = $true)] | |
[string] $Path | |
) | |
Set-StrictMode -Version 'Latest' | |
# Define characteristics used in PE file headers. | |
# TODO: Many more characteristics; easier to parse as CSharp class. | |
$characteristics = @{ | |
"IMAGE_FILE_RELOCS_STRIPPED" = 0x0001 | |
"IMAGE_FILE_EXECUTABLE_IMAGE" = 0x0002 | |
"IMAGE_FILE_LINE_NUMS_STRIPPED" = 0x0004 | |
"IMAGE_FILE_LOCAL_SYMS_STRIPPED" = 0x0008 | |
"IMAGE_FILE_AGGRESSIVE_WS_TRIM" = 0x0010 | |
"IMAGE_FILE_LARGE_ADDRESS_AWARE" = 0x0020 | |
"RESERVED" = 0x0040 | |
"IMAGE_FILE_BYTES_REVERSED_LO" = 0x0080 | |
"IMAGE_FILE_32BIT_MACHINE" = 0x0100 | |
"IMAGE_FILE_DEBUG_STRIPPED" = 0x0200 | |
"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP" = 0x0400 | |
"IMAGE_FILE_NET_RUN_FROM_SWAP" = 0x0800 | |
"IMAGE_FILE_SYSTEM" = 0x1000 | |
"IMAGE_FILE_DLL" = 0x2000 | |
"IMAGE_FILE_UP_SYSTEM_ONLY" = 0x4000 | |
"IMAGE_FILE_BYTES_REVERSED_HI" = 0x8000 | |
} | |
# Get content of file as byte array | |
# TODO: Wildcarded [string[]]$Path | |
# [!NOTE] > In PowerShell 6.0, The `-Encoding` parameter type | |
# > was changed from `FileSystemCmdletProviderEncoding` | |
# > to `System.Text.Encoding` and Byte is no longer a valid option. | |
# > The `-AsByteStream` parameter should be used to indicate that | |
# > the content should be read and output as a byte stream. | |
if($PSVersionTable.PSVersion.Major -ge 6) | |
{ | |
$fileBytes = Get-Content $path -ReadCount 0 -AsByteStream | |
} | |
else | |
{ | |
$fileBytes = Get-Content $path -ReadCount 0 -Encoding byte | |
} | |
# Signature offset location is 0x3c. | |
$signatureOffset = $fileBytes[0x3c] | |
# Ensure file is PE | |
$signature = [char[]] $fileBytes[$signatureOffset..($signatureOffset + 3)] | |
if(($signature -join '') -ne "PE`0`0") | |
{ | |
throw "This file does not conform to the PE specification." | |
} | |
# COFF header location is 4 bytes into signature | |
$coffHeader = $signatureOffset + 4 | |
# Characteristics data are 18 bytes into COFF header. | |
# BitConverter class manages conversion of the 4 bytes into int. | |
$characteristicsData = [BitConverter]::ToInt32($fileBytes, $coffHeader + 18) | |
# Loop through each characteristic and output it if file contains the flag. | |
# TODO: Add characteristics as properties for object parsing/formatting. | |
foreach($key in $characteristics.Keys) | |
{ | |
$flag = $characteristics[$key] | |
if(($characteristicsData -band $flag) -eq $flag) | |
{ | |
$key | |
} | |
} | |
} | |
# If this script is invoked directly - as opposed to being dot-sourced in order | |
# to define the embedded function for later use - invoke the embedded function, | |
# relaying any arguments passed - but first detect ValueFromPipeLine $input | |
if ($MyInvocation.ExpectingInput) | |
{ | |
$input | Get-PECharacteristics @args | |
} | |
elseif (-not ($MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq '')) | |
{ | |
Get-PECharacteristics @args | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment