-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathGet-BinaryType.ps1
124 lines (114 loc) · 5.01 KB
/
Get-BinaryType.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
function Get-BinaryType {
<#
.SYNOPSIS
Gets the binary executable type for a given set of files
.DESCRIPTION
PowerShell wrapper around the GetBinaryType Windows API that inspects file headers
and reports the binary file type (e.g., 32-bit Windows app, 64-bit Windows app,
16-bit DOS/Windows app, etc.)
.PARAMETER Path
File path(s) to inspect
.EXAMPLE
#Reports the file type of C:\Windows\Explorer.exe:
Get-BinaryType C:\Windows\Explorer.exe
.EXAMPLE
#Attempts to get the binary type of all files in the current directory
Get-ChildItem | where { !$_.PsIsContainer } | Get-BinaryType
.EXAMPLE
#Attempts to get the binary type of all exe files in the windows directory,
#ignoring any non-terminating errors
Get-ChildItem $env:windir -filter *.exe | Get-BinaryType -ErrorAction SilentlyContinue
.EXAMPLE
#From a 32bit process on a 64 bit Windows install, attempts to get the binary type of all exe files
#in the windows system32 directory by bypassing filesystem redirection using "sysnative",
#ignoring any non-terminating errors, and finally showing the file name and binary type
Get-ChildItem $env:windir\sysnative -filter *.exe | Get-BinaryType -ErrorAction SilentlyContinue -passthrough | select Name,BinaryType
.NOTES
Author: Battleship, Aaron Margosis
Inspiration: http://pinvoke.net/default.aspx/kernel32/GetBinaryType.html
.LINK
http://wonkysoftware.appspot.com
#>
[CmdletBinding(ConfirmImpact = 'none')]
param
(
[Parameter(HelpMessage = 'Enter binary file(s) to examine',Position = 0,
Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )]
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path -Path ((get-item -path $_).FullName)})]
[string[]] $Path,
[Alias('PassThru')]
[switch] $PassThrough
)
begin {
Write-Verbose -Message "Starting [$($MyInvocation.Mycommand)]"
$paths = Resolve-Path -Path $path | Select-Object -ExpandProperty Path
try
{
#add the enum for the binary types
#Using more user friendly names since they won't likely be used outside this context
$enumString = @'
public enum BinaryType
{
BIT32 = 0, // A 32-bit Windows-based application, SCS_32BIT_BINARY
DOS = 1, // An MS-DOS - based application, SCS_DOS_BINARY
WOW = 2, // A 16-bit Windows-based application, SCS_WOW_BINARY
PIF = 3, // A PIF file that executes an MS-DOS based application, SCS_PIF_BINARY
POSIX = 4, // A POSIX based application, SCS_POSIX_BINARY
OS216 = 5, // A 16-bit OS/2-based application, SCS_OS216_BINARY
BIT64 = 6 // A 64-bit Windows-based application, SCS_64BIT_BINARY
}
'@
Add-Type -TypeDefinition $enumString
}
catch {
Write-Verbose -message 'Info'
} #type already been loaded, do nothing
try
{
# create the win32 signature
$Signature = @'
[DllImport("kernel32.dll")]
public static extern bool GetBinaryType(
string lpApplicationName,
ref int lpBinaryType
);
'@
# Create a new type that lets us access the Windows API function
Add-Type -MemberDefinition $Signature -Name BinaryType -Namespace PFWin32Utils
} catch {
Write-Verbose -Message 'Info'
} #type already been loaded, do nothing
}
process {
foreach ($Item in $Paths)
{
$ReturnedType = -1
Write-Verbose -Message "Attempting to get type for file: $($Item.FullName)"
$Result = [PFWin32Utils.BinaryType]::GetBinaryType($Item, [ref] $ReturnedType)
#if the function returned $false, indicating an error, or the binary type wasn't returned
if (!$Result -or ($ReturnedType -eq -1))
{
Write-Error -Message "Failed to get binary type for file $($Item.FullName)"
}
else
{
$ToReturn = [BinaryType] $ReturnedType
if ($PassThrough)
{
#get the file object, attach a property indicating the type, and passthru to pipeline
Get-Item -Path $Item.FullName -Force |
Add-Member -MemberType noteproperty -Name BinaryType -Value $ToReturn -Force -PassThru
}
else
{
#Put enum object directly into pipeline
$ToReturn
}
}
}
}
end {
Write-Verbose -Message "Ending [$($MyInvocation.Mycommand)]"
}
}