Public/Get-MSIXAppMachineType.ps1
|
function Get-MSIXAppMachineType { <# .SYNOPSIS Retrieves the architecture type for a given executable file or dll. .DESCRIPTION This function reads the PE (Portable Executable) header of an executable file and determines the machine type for which the file is compiled. .PARAMETER FilePathName Specifies the path to the executable or DLL file. .OUTPUTS System.String The machine type for the executable file. Possible values are: - "Native": The file is a native executable. - "I386": The file is compiled for the x86 architecture. - "Itanium": The file is compiled for the Itanium architecture. - "x64": The file is compiled for the x64 architecture. - "ARM": The file is compiled for the ARM architecture. - "ARM64": The file is compiled for the ARM64 architecture. - "Unknown": The machine type is unknown or unsupported. .EXAMPLE Get-MSIXAppMachineType -FilePathName "C:\Path\To\MyApp.exe" Retrieves the machine type for the specified executable file. .NOTES c# Source https://stackoverflow.com/questions/197951/how-can-i-determine-for-which-platform-an-executable-is-compiled https://www.nick-it.de Andreas Nick, 2024 #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [System.IO.FileInfo] $FilePathName ) process { $PE_POINTER_OFFSET = 60 $MACHINE_OFFSET = 4 $BUFFER_SIZE = 4096 $data = New-Object byte[] $BUFFER_SIZE $stream = [System.IO.File]::Open($FilePathName.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) try { $null = $stream.Read($data, 0, $BUFFER_SIZE) # Validate that the DOS header magic bytes 'MZ' are present if ($data[0] -ne 0x4D -or $data[1] -ne 0x5A) { Write-Warning "$($FilePathName.Name) is not a valid PE file (missing MZ header)." "Unknown" return } $PE_HEADER_ADDR = [System.BitConverter]::ToInt32($data, $PE_POINTER_OFFSET) # Ensure the PE header and machine type field fit within the buffer $requiredBytes = $PE_HEADER_ADDR + $MACHINE_OFFSET + 2 if ($PE_HEADER_ADDR -lt 0 -or $requiredBytes -gt $BUFFER_SIZE) { Write-Warning "$($FilePathName.Name) has a PE header offset outside the readable buffer." "Unknown" return } $machineUint = [System.BitConverter]::ToUInt16($data, $PE_HEADER_ADDR + $MACHINE_OFFSET) $architecture = switch ($machineUint) { 0 { "Native" } 0x014c { "I386" } 0x0200 { "Itanium" } 0x8664 { "x64" } 0x01c0 { "ARM" } 0xaa64 { "ARM64" } default { "Unknown" } } Write-Verbose "$($FilePathName.Name) architecture type: $architecture" $architecture } finally { $stream.Close() } } } |