Skip to content

Instantly share code, notes, and snippets.

@ahmedosama007
Created June 14, 2022 23:46
Show Gist options
  • Save ahmedosama007/bfdb8198fe6690d17e7c3db398f6d725 to your computer and use it in GitHub Desktop.
Save ahmedosama007/bfdb8198fe6690d17e7c3db398f6d725 to your computer and use it in GitHub Desktop.
PE header reader
#Region "References"
Imports System.IO
Imports System.ComponentModel
Imports System.Runtime.InteropServices
#End Region
Namespace OsUtils
''' <summary>
''' Reads the PE header of a Portable Executable file
''' </summary>
Public NotInheritable Class PEHeaderReader
#Region "File Header Structures"
<CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification:="<Pending>")>
Public Structure IMAGE_DOS_HEADER ' DOS .EXE header
' ReSharper disable UnusedMember.Global
Public E_magic As UShort ' Magic number
Public E_cblp As UShort ' Bytes on last page of file
Public E_cp As UShort ' Pages in file
Public E_crlc As UShort ' Relocations
Public E_cparhdr As UShort ' Size of header in paragraphs
Public E_minalloc As UShort ' Minimum extra paragraphs needed
Public E_maxalloc As UShort ' Maximum extra paragraphs needed
Public E_ss As UShort ' Initial (relative) SS value
Public E_sp As UShort ' Initial SP value
Public E_csum As UShort ' Checksum
Public E_ip As UShort ' Initial IP value
Public E_cs As UShort ' Initial (relative) CS value
Public E_lfarlc As UShort ' File address of relocation table
Public E_ovno As UShort ' Overlay number
Public E_res_0 As UShort ' Reserved words
Public E_res_1 As UShort ' Reserved words
Public E_res_2 As UShort ' Reserved words
Public E_res_3 As UShort ' Reserved words
Public E_oemid As UShort ' OEM identifier (for e_oeminfo)
Public E_oeminfo As UShort ' OEM information; e_oemid specific
Public E_res2_0 As UShort ' Reserved words
Public E_res2_1 As UShort ' Reserved words
Public E_res2_2 As UShort ' Reserved words
Public E_res2_3 As UShort ' Reserved words
Public E_res2_4 As UShort ' Reserved words
Public E_res2_5 As UShort ' Reserved words
Public E_res2_6 As UShort ' Reserved words
Public E_res2_7 As UShort ' Reserved words
Public E_res2_8 As UShort ' Reserved words
Public E_res2_9 As UShort ' Reserved words
Public E_lfanew As UInteger ' File address of new exe header
' ReSharper restore UnusedMember.Global
End Structure
<CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification:="<Pending>")>
<StructLayout(LayoutKind.Sequential)>
Public Structure IMAGE_DATA_DIRECTORY
Public VirtualAddress As UInteger
Public Size As UInteger
End Structure
<CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification:="<Pending>")>
<StructLayout(LayoutKind.Sequential, Pack:=1)>
Public Structure IMAGE_OPTIONAL_HEADER32
Public Magic As UShort
Public MajorLinkerVersion As Byte
Public MinorLinkerVersion As Byte
''' <summary>
''' The size of the code(text) section, or the sum of all code sections if there are multiple sections.
''' </summary>
Public SizeOfCode As UInteger
Public SizeOfInitializedData As UInteger
Public SizeOfUninitializedData As UInteger
''' <summary>
''' The address of the entry point relative to the image base when the executable file is loaded into memory.<br/>
''' For program images, this is the starting address. For device drivers, this is the address of the initialization function.<br/>
''' An entry point is optional for DLLs. When no entry point is present, this field must be zero.
''' </summary>
Public AddressOfEntryPoint As UInteger
''' <summary>
''' The address that is relative to the image base of the beginning-of-code section when it is loaded into memory.
''' </summary>
Public BaseOfCode As UInteger
''' <summary>
''' The address that is relative to the image base of the beginning-of-data section when it is loaded into memory.
''' </summary>
Public BaseOfData As UInteger
Public ImageBase As UInteger
Public SectionAlignment As UInteger
Public FileAlignment As UInteger
Public MajorOperatingSystemVersion As UShort
Public MinorOperatingSystemVersion As UShort
Public MajorImageVersion As UShort
Public MinorImageVersion As UShort
Public MajorSubsystemVersion As UShort
Public MinorSubsystemVersion As UShort
Public Win32VersionValue As UInteger
''' <summary>
''' The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of SectionAlignment.
''' </summary>
Public SizeOfImage As UInteger
''' <summary>
''' The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment.
''' </summary>
Public SizeOfHeaders As UInteger
''' <summary>
''' The image file checksum.The algorithm for computing the checksum is incorporated into IMAGHELP.DLL.<br/>
''' The following are checked for validation at load time: all drivers, any DLL loaded at boot time,<br/>
''' and any DLL that is loaded into a critical Windows process.
''' </summary>
Public CheckSum As UInteger
''' <summary>
''' determine which Windows subsystem (if any) is required to run the image.
''' </summary>
Public Subsystem As ImageSubSystem
Public DllCharacteristics As UShort
Public SizeOfStackReserve As UInteger
Public SizeOfStackCommit As UInteger
Public SizeOfHeapReserve As UInteger
Public SizeOfHeapCommit As UInteger
Public LoaderFlags As UInteger
Public NumberOfRvaAndSizes As UInteger
Public ExportTable As IMAGE_DATA_DIRECTORY
Public ImportTable As IMAGE_DATA_DIRECTORY
Public ResourceTable As IMAGE_DATA_DIRECTORY
Public ExceptionTable As IMAGE_DATA_DIRECTORY
Public CertificateTable As IMAGE_DATA_DIRECTORY
Public BaseRelocationTable As IMAGE_DATA_DIRECTORY
Public Debug As IMAGE_DATA_DIRECTORY
Public Architecture As IMAGE_DATA_DIRECTORY
Public GlobalPtr As IMAGE_DATA_DIRECTORY
Public TLSTable As IMAGE_DATA_DIRECTORY
Public LoadConfigTable As IMAGE_DATA_DIRECTORY
Public BoundImport As IMAGE_DATA_DIRECTORY
Public IAT As IMAGE_DATA_DIRECTORY
Public DelayImportDescriptor As IMAGE_DATA_DIRECTORY
Public CLRRuntimeHeader As IMAGE_DATA_DIRECTORY
Public Reserved As IMAGE_DATA_DIRECTORY
End Structure
<CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification:="<Pending>")>
<StructLayout(LayoutKind.Sequential, Pack:=1)>
Public Structure IMAGE_OPTIONAL_HEADER64
Public Magic As UShort
Public MajorLinkerVersion As Byte
Public MinorLinkerVersion As Byte
Public SizeOfCode As UInteger
Public SizeOfInitializedData As UInteger
Public SizeOfUninitializedData As UInteger
Public AddressOfEntryPoint As UInteger
Public BaseOfCode As UInteger
Public ImageBase As ULong
Public SectionAlignment As UInteger
Public FileAlignment As UInteger
Public MajorOperatingSystemVersion As UShort
Public MinorOperatingSystemVersion As UShort
Public MajorImageVersion As UShort
Public MinorImageVersion As UShort
Public MajorSubsystemVersion As UShort
Public MinorSubsystemVersion As UShort
Public Win32VersionValue As UInteger
Public SizeOfImage As UInteger
Public SizeOfHeaders As UInteger
Public CheckSum As UInteger
Public Subsystem As UShort
Public DllCharacteristics As UShort
Public SizeOfStackReserve As ULong
Public SizeOfStackCommit As ULong
Public SizeOfHeapReserve As ULong
Public SizeOfHeapCommit As ULong
Public LoaderFlags As UInteger
Public NumberOfRvaAndSizes As UInteger
Public ExportTable As IMAGE_DATA_DIRECTORY
Public ImportTable As IMAGE_DATA_DIRECTORY
Public ResourceTable As IMAGE_DATA_DIRECTORY
Public ExceptionTable As IMAGE_DATA_DIRECTORY
Public CertificateTable As IMAGE_DATA_DIRECTORY
Public BaseRelocationTable As IMAGE_DATA_DIRECTORY
Public Debug As IMAGE_DATA_DIRECTORY
Public Architecture As IMAGE_DATA_DIRECTORY
Public GlobalPtr As IMAGE_DATA_DIRECTORY
Public TLSTable As IMAGE_DATA_DIRECTORY
Public LoadConfigTable As IMAGE_DATA_DIRECTORY
Public BoundImport As IMAGE_DATA_DIRECTORY
Public IAT As IMAGE_DATA_DIRECTORY
Public DelayImportDescriptor As IMAGE_DATA_DIRECTORY
Public CLRRuntimeHeader As IMAGE_DATA_DIRECTORY
Public Reserved As IMAGE_DATA_DIRECTORY
End Structure
<CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification:="<Pending>")>
<StructLayout(LayoutKind.Sequential, Pack:=1)>
Public Structure IMAGE_FILE_HEADER
Public Machine As MachineType
Public NumberOfSections As UShort
Public TimeDateStamp As UInteger
Public PointerToSymbolTable As UInteger
Public NumberOfSymbols As UInteger
Public SizeOfOptionalHeader As UShort
Public Characteristics As ImageCharacteristics
End Structure
<CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification:="<Pending>")>
<StructLayout(LayoutKind.Explicit)>
Public Structure IMAGE_SECTION_HEADER
<FieldOffset(0)>
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>
Public Name As Char()
<FieldOffset(8)>
Public VirtualSize As UInteger
<FieldOffset(12)>
Public VirtualAddress As UInteger
<FieldOffset(16)>
Public SizeOfRawData As UInteger
<FieldOffset(20)>
Public PointerToRawData As UInteger
<FieldOffset(24)>
Public PointerToRelocations As UInteger
<FieldOffset(28)>
Public PointerToLinenumbers As UInteger
<FieldOffset(32)>
Public NumberOfRelocations As UShort
<FieldOffset(34)>
Public NumberOfLinenumbers As UShort
<FieldOffset(36)>
Public Characteristics As DataSection
Public ReadOnly Property Section As String
Get
Return New String(Name)
End Get
End Property
End Structure
#End Region
#Region "Private Fields"
''' <summary>
''' The DOS header
''' </summary>
Private ReadOnly _dosHeader As IMAGE_DOS_HEADER
''' <summary>
''' The file header
''' </summary>
Private _fileHeaderField As IMAGE_FILE_HEADER
#End Region
#Region "Public Methods"
''' <summary>
''' Initialize a new instance of the <see cref="PEHeaderReader"/> class
''' </summary>
''' <param name="filePath">Portable executable file path</param>
Public Sub New(filePath As String)
' Read in the DLL or EXE and get the time-stamp
Using fStream = New FileStream(filePath, FileMode.Open, FileAccess.Read)
Using bReader = New BinaryReader(fStream)
_dosHeader = FromBinaryReader(Of IMAGE_DOS_HEADER)(bReader)
'Add 4 bytes to the offset
fStream.Seek(_dosHeader.E_lfanew, SeekOrigin.Begin)
bReader.ReadUInt32()
_fileHeaderField = FromBinaryReader(Of IMAGE_FILE_HEADER)(bReader)
If Is32BitHeader Then
OptionalHeader32 = FromBinaryReader(Of IMAGE_OPTIONAL_HEADER32)(bReader)
Else
OptionalHeader64 = FromBinaryReader(Of IMAGE_OPTIONAL_HEADER64)(bReader)
End If
ImageSectionHeaders = New IMAGE_SECTION_HEADER(_fileHeaderField.NumberOfSections - 1) {}
Dim headerNo As Integer
While headerNo < ImageSectionHeaders.Length
ImageSectionHeaders(headerNo) = FromBinaryReader(Of IMAGE_SECTION_HEADER)(bReader)
Threading.Interlocked.Increment(headerNo)
End While
End Using
End Using
End Sub
Public Shared Function FromBinaryReader(Of T)(reader As BinaryReader) As T
If reader Is Nothing Then Return Nothing
Dim bytes = reader.ReadBytes(Marshal.SizeOf(GetType(T)))
Dim handle = GCHandle.Alloc(bytes, GCHandleType.Pinned)
Dim struct = CType(Marshal.PtrToStructure(handle.AddrOfPinnedObject(), GetType(T)), T)
handle.Free()
Return struct
End Function
#End Region
#Region "Public Properties"
Public ReadOnly Property Is32BitHeader As Boolean
Get
Return FileHeader.Characteristics.HasFlag(ImageCharacteristics.IMAGE_FILE_32BIT_MACHINE)
End Get
End Property
''' <summary>
''' Gets the image file header
''' </summary>
Public ReadOnly Property FileHeader As IMAGE_FILE_HEADER
Get
Return _fileHeaderField
End Get
End Property
''' <summary>
''' Gets the optional 32-bit header
''' </summary>
Public ReadOnly Property OptionalHeader32 As IMAGE_OPTIONAL_HEADER32
''' <summary>
''' Gets the optional 64-bit header
''' </summary>
Public ReadOnly Property OptionalHeader64 As IMAGE_OPTIONAL_HEADER64
#Disable Warning CA1819 ' Properties should not return arrays
Public ReadOnly Property ImageSectionHeaders As IMAGE_SECTION_HEADER()
#Enable Warning CA1819 ' Properties should not return arrays
''' <summary>
''' Gets the time-stamp from the file header
''' </summary>
Public ReadOnly Property TimeStamp As Date
Get
'Time-stamp is a date offset from 1970
Dim returnValue As New DateTime(1970, 1, 1, 0, 0, 0)
' Add in the number of seconds since 1970/1/1
returnValue = returnValue.AddSeconds(_fileHeaderField.TimeDateStamp)
' Adjust to local timezone
returnValue += TimeZone.CurrentTimeZone.GetUtcOffset(returnValue)
Return returnValue
End Get
End Property
#End Region
#Region "Enumerations"
<Flags> <CodeAnalysis.SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification:="<Pending>")>
Public Enum DataSection As UInteger
''' <summary>
''' Reserved for future use.
''' </summary>
None = &H0
''' <summary>
''' Reserved for future use.
''' </summary>
' ReSharper disable UnusedMember.Global
TypeDsect = &H1
''' <summary>
''' Reserved for future use.
''' </summary>
TypeNoLoad = &H2
''' <summary>
''' Reserved for future use.
''' </summary>
TypeGroup = &H4
''' <summary>
''' The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
''' </summary>
TypeNoPadded = &H8
''' <summary>
''' Reserved for future use.
''' </summary>
TypeCopy = &H10
''' <summary>
''' The section contains executable code.
''' </summary>
ContentCode = &H20
''' <summary>
''' The section contains initialized data.
''' </summary>
ContentInitializedData = &H40
''' <summary>
''' The section contains uninitialized data.
''' </summary>
ContentUninitializedData = &H80
''' <summary>
''' Reserved for future use.
''' </summary>
LinkOther = &H100
''' <summary>
''' The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
''' </summary>
LinkInfo = &H200
''' <summary>
''' Reserved for future use.
''' </summary>
TypeOver = &H400
''' <summary>
''' The section will not become part of the image. This is valid only for object files.
''' </summary>
LinkRemove = &H800
''' <summary>
''' The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
''' </summary>
LinkComDat = &H1000
''' <summary>
''' Reset speculative exceptions handling bits in the TLB entries for this section.
''' </summary>
NoDeferSpecExceptions = &H4000
''' <summary>
''' The section contains data referenced through the global pointer (GP).
''' </summary>
RelativeGP = &H8000
''' <summary>
''' Reserved for future use.
''' </summary>
MemPurgeable = &H20000
''' <summary>
''' Reserved for future use.
''' </summary>
Memory16Bit = &H20000
''' <summary>
''' Reserved for future use.
''' </summary>
MemoryLocked = &H40000
''' <summary>
''' Reserved for future use.
''' </summary>
MemoryPreload = &H80000
''' <summary>
''' Align data on a 1-byte boundary. Valid only for object files.
''' </summary>
Align1Bytes = &H100000
''' <summary>
''' Align data on a 2-byte boundary. Valid only for object files.
''' </summary>
Align2Bytes = &H200000
''' <summary>
''' Align data on a 4-byte boundary. Valid only for object files.
''' </summary>
Align4Bytes = &H300000
''' <summary>
''' Align data on an 8-byte boundary. Valid only for object files.
''' </summary>
Align8Bytes = &H400000
''' <summary>
''' Align data on a 16-byte boundary. Valid only for object files.
''' </summary>
Align16Bytes = &H500000
''' <summary>
''' Align data on a 32-byte boundary. Valid only for object files.
''' </summary>
Align32Bytes = &H600000
''' <summary>
''' Align data on a 64-byte boundary. Valid only for object files.
''' </summary>
Align64Bytes = &H700000
''' <summary>
''' Align data on a 128-byte boundary. Valid only for object files.
''' </summary>
Align128Bytes = &H800000
''' <summary>
''' Align data on a 256-byte boundary. Valid only for object files.
''' </summary>
Align256Bytes = &H900000
''' <summary>
''' Align data on a 512-byte boundary. Valid only for object files.
''' </summary>
Align512Bytes = &HA00000
''' <summary>
''' Align data on a 1024-byte boundary. Valid only for object files.
''' </summary>
Align1024Bytes = &HB00000
''' <summary>
''' Align data on a 2048-byte boundary. Valid only for object files.
''' </summary>
Align2048Bytes = &HC00000
''' <summary>
''' Align data on a 4096-byte boundary. Valid only for object files.
''' </summary>
Align4096Bytes = &HD00000
''' <summary>
''' Align data on an 8192-byte boundary. Valid only for object files.
''' </summary>
Align8192Bytes = &HE00000
''' <summary>
''' The section contains extended relocations.
''' </summary>
LinkExtendedRelocationOverflow = &H1000000
''' <summary>
''' The section can be discarded as needed.
''' </summary>
MemoryDiscardable = &H2000000
''' <summary>
''' The section cannot be cached.
''' </summary>
MemoryNotCached = &H4000000
''' <summary>
''' The section is not pageable.
''' </summary>
MemoryNotPaged = &H8000000
''' <summary>
''' The section can be shared in memory.
''' </summary>
MemoryShared = &H10000000
''' <summary>
''' The section can be executed as code.
''' </summary>
MemoryExecute = &H20000000
''' <summary>
''' The section can be read.
''' </summary>
MemoryRead = &H40000000
''' <summary>
''' The section can be written to.
''' </summary>
'MemoryWrite = &H80000000
' ReSharper restore UnusedMember.Global
End Enum
<CodeAnalysis.SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
Public Enum ImageSubSystem As UShort
<Description("Unknown image subsystem")> IMAGE_SUBSYSTEM_UNKNOWN = 0
<Description("Native")> IMAGE_SUBSYSTEM_NATIVE = 1
<Description("Windows GUI")> IMAGE_SUBSYSTEM_WINDOWS_GUI = 2
<Description("Windows CUI")> IMAGE_SUBSYSTEM_WINDOWS_CUI = 3
<Description("OS/2 CUI")> IMAGE_SUBSYSTEM_OS2_CUI = 5
<Description("POSIX CUI")> IMAGE_SUBSYSTEM_POSIX_CUI = 7
<Description("Native Windows image subsystem")> IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8
<Description("Windows CE")> IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9
<Description("EFI")> IMAGE_SUBSYSTEM_EFI_APPLICATION = 10
<Description("EFI driver with boot services")> IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11
<Description("EFI driver with run-time services")> IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12
<Description("EFI ROM")> IMAGE_SUBSYSTEM_EFI_ROM = 13
<Description("Xbox")> IMAGE_SUBSYSTEM_XBOX = 14
<Description("Windows Boot")> IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16
End Enum
<CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification:="<Pending>")>
Public Enum MachineType As UShort
<Description("Unknown")> IMAGE_FILE_MACHINE_UNKNOWN = &H0
''' <summary>
''' Matsushita AM33
''' </summary>
<Description("AM33")> IMAGE_FILE_MACHINE_AM33 = &H1D3
''' <summary>
''' x64
''' </summary>
<Description("AMD64")> IMAGE_FILE_MACHINE_AMD64 = &H8664
''' <summary>
''' ARM
''' </summary>
<Description("ARM")> IMAGE_FILE_MACHINE_ARM = &H1C0
''' <summary>
''' ARM64
''' </summary>
<Description("ARM64")> IMAGE_FILE_MACHINE_ARM64 = &HAA64
''' <summary>
''' ARM Thumb-2 little endian
''' </summary>
<Description("ARM Thumb-2")> IMAGE_FILE_MACHINE_ARMNT = &H1C4
''' <summary>
''' EFI byte code
''' </summary>
<Description("EFI Byte Code")> IMAGE_FILE_MACHINE_EBC = &HEBC
''' <summary>
''' Intel 386 or later and compatible processors
''' </summary>
<Description("Intel I386")> IMAGE_FILE_MACHINE_I386 = &H14C
''' <summary>
''' Intel Itanium
''' </summary>
<Description("IA-64")> IMAGE_FILE_MACHINE_IA64 = &H200
''' <summary>
''' Mitsubishi M32R little endian
''' </summary>
<Description("M32R")> IMAGE_FILE_MACHINE_M32R = &H9041
''' <summary>
''' MIPS16
''' </summary>
<Description("MIPS16")> IMAGE_FILE_MACHINE_MIPS16 = &H266
''' <summary>
''' MIPS with FPU
''' </summary>
<Description("MIPS")> IMAGE_FILE_MACHINE_MIPSFPU = &H366
''' <summary>
''' MIPS16 with FPU
''' </summary>
<Description("MIPS16")> IMAGE_FILE_MACHINE_MIPSFPU16 = &H466
''' <summary>
''' Power PC little endian
''' </summary>
<Description("IBM PowerPC")> IMAGE_FILE_MACHINE_POWERPC = &H1F0
''' <summary>
''' Power PC with floating point support
''' </summary>
<Description("PowerPCFP")> IMAGE_FILE_MACHINE_POWERPCFP = &H1F1
''' <summary>
''' MIPS little endian
''' </summary>
<Description("MIPS")> IMAGE_FILE_MACHINE_R4000 = &H166
''' <summary>
''' RISC-V 32-bit address space
''' </summary>
<Description("RISC-V 32-bit")> IMAGE_FILE_MACHINE_RISCV32 = &H5032
''' <summary>
''' RISC-V 64-bit address space
''' </summary>
<Description("RISC-V 64-bit")> IMAGE_FILE_MACHINE_RISCV64 = &H5064
''' <summary>
''' RISC-V 128-bit address space
''' </summary>
<Description("RISC-V 128-bit")> IMAGE_FILE_MACHINE_RISCV128 = &H5128
''' <summary>
''' Hitachi SH3
''' </summary>
<Description("Hitachi SH3")> IMAGE_FILE_MACHINE_SH3 = &H1A2
''' <summary>
''' Hitachi SH3 DSP
''' </summary>
<Description("Hitachi SH3 DSP")> IMAGE_FILE_MACHINE_SH3DSP = &H1A3
''' <summary>
''' Hitachi SH4
''' </summary>
<Description("Hitachi SH4")> IMAGE_FILE_MACHINE_SH4 = &H1A6
''' <summary>
''' Hitachi SH5
''' </summary>
<Description("Hitachi SH5")> IMAGE_FILE_MACHINE_SH5 = &H1A8
''' <summary>
''' Thumb
''' </summary>
<Description("Thumb")> IMAGE_FILE_MACHINE_THUMB = &H1C2
''' <summary>
''' MIPS little-endian WCE v2
''' </summary>
<Description("MIPS WCE v2")> IMAGE_FILE_MACHINE_WCEMIPSV2 = &H169
End Enum
<Flags> <CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification:="<Pending>")>
<CodeAnalysis.SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification:="<Pending>")>
Public Enum ImageCharacteristics As UShort
''' <summary>
''' Image only, Windows CE, and Microsoft Windows NT and later. This indicates that the file does not contain base relocations and must therefore be loaded at its preferred base address. If the base address is not available, the loader reports an error. The default behavior of the linker is to strip base relocations from executable (EXE) files.
''' </summary>
<Description("Stripped Relocations")> IMAGE_FILE_RELOCS_STRIPPED = &H1
''' <summary>
''' Image only. This indicates that the image file is valid and can be run.If this flag is not set, it indicates a linker error.
''' </summary>
<Description("Executable File")> IMAGE_FILE_EXECUTABLE_IMAGE = &H2
''' <summary>
''' COFF line numbers have been removed. This flag is deprecated and should be zero.
''' </summary>
<Description("Stripped Line Numbers")> IMAGE_FILE_LINE_NUMS_STRIPPED = &H4
''' <summary>
''' COFF symbol table entries for local symbols have been removed.This flag is deprecated and should be zero.
''' </summary>
<Description("Stripped Local Symbols")> IMAGE_FILE_LOCAL_SYMS_STRIPPED = &H8
''' <summary>
''' Obsolete.Aggressively trim working set. This flag is deprecated for Windows 2000 and later and must be zero.
''' </summary>
<Description("Trimmed Working Set")> IMAGE_FILE_AGGRESSIVE_WS_TRIM = &H10
''' <summary>
''' Application can handle > 2-GB addresses.
''' </summary>
<Description("Handle Large Address")> IMAGE_FILE_LARGE_ADDRESS_AWARE = &H20
#Disable Warning CA1700 ' Do not name enum values 'Reserved'
''' <summary>
''' This flag is reserved for future use.
''' </summary>
<Description("RESERVED")> RESERVED = &H40
#Enable Warning CA1700 ' Do not name enum values 'Reserved'
''' <summary>
''' Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory.This flag is deprecated and should be zero.
''' </summary>
<Description("IMAGE_FILE_BYTES_REVERSED_LO")> IMAGE_FILE_BYTES_REVERSED_LO = &H80
''' <summary>
''' Machine is based on a 32-bit-word architecture.
''' </summary>
<Description("32-bit")> IMAGE_FILE_32BIT_MACHINE = &H100
''' <summary>
''' Debugging information is removed from the image file.
''' </summary>
<Description("No Debug Info")> IMAGE_FILE_DEBUG_STRIPPED = &H200
''' <summary>
''' If the image is on removable media, fully load it and copy it to the swap file.
''' </summary>
<Description("Located on Removable Media/Run from Swap")> IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = &H400
''' <summary>
''' If the image is on network media, fully load it and copy it to the swap file.
''' </summary>
<Description("Located on Network Media/Run from Swap")> IMAGE_FILE_NET_RUN_FROM_SWAP = &H800
''' <summary>
''' The image file is a system file, not a user program.
''' </summary>
<Description("System File")> IMAGE_FILE_SYSTEM = &H1000
''' <summary>
''' The image file is a dynamic-link library (DLL). Such files are considered executable files for almost all purposes, although they cannot be directly run.
''' </summary>
<Description("DLL File")> IMAGE_FILE_DLL = &H2000
''' <summary>
''' The file should be run only on a uniprocessor machine.
''' </summary>
<Description("Uniprocessor Computer")> IMAGE_FILE_UP_SYSTEM_ONLY = &H4000
''' <summary>
''' Big endian: the MSB precedes the LSB in memory.This flag is deprecated and should be zero.
''' </summary>
<Description("IMAGE_FILE_BYTES_REVERSED_HI")> IMAGE_FILE_BYTES_REVERSED_HI = &H8000
End Enum
#End Region
End Class
End Namespace
@livlif2dfullest
Copy link

I converted this to C# for my usage if you want to add it for someone else:

using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;

namespace LaunchApps
{
	/// <summary>
	/// Reads the PE header of a Portable Executable file
	/// </summary>
	public class PEHeaderReader
	{
		#region "File Header Structures"
		[SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
		public struct IMAGE_DOS_HEADER      // DOS .EXE header
		{
			// ReSharper disable UnusedMember.Global
			public ushort E_magic;              // Magic number
			public ushort E_cblp;               // Bytes on last page of file
			public ushort E_cp;                 // Pages in file
			public ushort E_crlc;               // Relocations
			public ushort E_cparhdr;            // Size of header in paragraphs
			public ushort E_minalloc;           // Minimum extra paragraphs needed
			public ushort E_maxalloc;           // Maximum extra paragraphs needed
			public ushort E_ss;                 // Initial (relative) SS value
			public ushort E_sp;                 // Initial SP value
			public ushort E_csum;               // Checksum
			public ushort E_ip;                 // Initial IP value
			public ushort E_cs;                 // Initial (relative) CS value
			public ushort E_lfarlc;             // File address of relocation table
			public ushort E_ovno;               // Overlay number
			public ushort E_res_0;              // Reserved words
			public ushort E_res_1;              // Reserved words
			public ushort E_res_2;              // Reserved words
			public ushort E_res_3;              // Reserved words
			public ushort E_oemid;              // OEM identifier (for e_oeminfo)
			public ushort E_oeminfo;            // OEM information; e_oemid specific
			public ushort E_res2_0;             // Reserved words
			public ushort E_res2_1;             // Reserved words
			public ushort E_res2_2;             // Reserved words
			public ushort E_res2_3;             // Reserved words
			public ushort E_res2_4;             // Reserved words
			public ushort E_res2_5;             // Reserved words
			public ushort E_res2_6;             // Reserved words
			public ushort E_res2_7;             // Reserved words
			public ushort E_res2_8;             // Reserved words
			public ushort E_res2_9;             // Reserved words
			public uint E_lfanew;           // File address of new exe header
											// ReSharper restore UnusedMember.Global
		}

		[SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
		[StructLayout(LayoutKind.Sequential)]
		public struct IMAGE_DATA_DIRECTORY
		{
			public uint VirtualAddress;
			public uint Size;
		}

		[SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct IMAGE_OPTIONAL_HEADER32
		{
			public ushort Magic;
			public byte MajorLinkerVersion;
			public byte MinorLinkerVersion;
			/// <summary>
			/// The size of the code(text) section, or the sum of all code sections if there are multiple sections.
			/// </summary>
			public uint SizeOfCode;

			public uint SizeOfInitializedData;

			public uint SizeOfUninitializedData;
			/// <summary>
			/// The address of the entry point relative to the image base when the executable file is loaded into memory.<br/>
			/// For program images, this is the starting address. For device drivers, this is the address of the initialization function.<br/>
			/// An entry point is optional for DLLs. When no entry point is present, this field must be zero. 
			/// </summary>
			public uint AddressOfEntryPoint;

			/// <summary>
			/// The address that is relative to the image base of the beginning-of-code section when it is loaded into memory. 
			/// </summary>
			public uint BaseOfCode;
			/// <summary>
			/// The address that is relative to the image base of the beginning-of-data section when it is loaded into memory. 
			/// </summary>
			public uint BaseOfData;

			public uint ImageBase;

			public uint SectionAlignment;

			public uint FileAlignment;

			public ushort MajorOperatingSystemVersion;

			public ushort MinorOperatingSystemVersion;

			public ushort MajorImageVersion;

			public ushort MinorImageVersion;

			public ushort MajorSubsystemVersion;

			public ushort MinorSubsystemVersion;

			public uint Win32VersionValue;
			/// <summary>
			/// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of SectionAlignment. 
			/// </summary>
			public uint SizeOfImage;
			/// <summary>
			/// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. 
			/// </summary>
			public uint SizeOfHeaders;
			/// <summary>
			/// The image file checksum.The algorithm for computing the checksum is incorporated into IMAGHELP.DLL.<br/>
			/// The following are checked for validation at load time: all drivers, any DLL loaded at boot time,<br/>
			/// and any DLL that is loaded into a critical Windows process. 
			/// </summary>
			public uint CheckSum;

			/// <summary>
			/// determine which Windows subsystem (if any) is required to run the image.
			/// </summary>
			public ImageSubSystem Subsystem;

			public ushort DllCharacteristics;

			public uint SizeOfStackReserve;

			public uint SizeOfStackCommit;

			public uint SizeOfHeapReserve;

			public uint SizeOfHeapCommit;

			public uint LoaderFlags;

			public uint NumberOfRvaAndSizes;

			public IMAGE_DATA_DIRECTORY ExportTable;

			public IMAGE_DATA_DIRECTORY ImportTable;

			public IMAGE_DATA_DIRECTORY ResourceTable;

			public IMAGE_DATA_DIRECTORY ExceptionTable;

			public IMAGE_DATA_DIRECTORY CertificateTable;

			public IMAGE_DATA_DIRECTORY BaseRelocationTable;

			public IMAGE_DATA_DIRECTORY Debug;

			public IMAGE_DATA_DIRECTORY Architecture;

			public IMAGE_DATA_DIRECTORY GlobalPtr;

			public IMAGE_DATA_DIRECTORY TLSTable;

			public IMAGE_DATA_DIRECTORY LoadConfigTable;

			public IMAGE_DATA_DIRECTORY BoundImport;

			public IMAGE_DATA_DIRECTORY IAT;

			public IMAGE_DATA_DIRECTORY DelayImportDescriptor;

			public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;

			public IMAGE_DATA_DIRECTORY Reserved;

		}

		[SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct IMAGE_OPTIONAL_HEADER64
		{
			public ushort Magic;
			public byte MajorLinkerVersion;
			public byte MinorLinkerVersion;
			public uint SizeOfCode;
			public uint SizeOfInitializedData;
			public uint SizeOfUninitializedData;
			public uint AddressOfEntryPoint;
			public uint BaseOfCode;
			public ulong ImageBase;
			public uint SectionAlignment;
			public uint FileAlignment;
			public ushort MajorOperatingSystemVersion;
			public ushort MinorOperatingSystemVersion;
			public ushort MajorImageVersion;
			public ushort MinorImageVersion;
			public ushort MajorSubsystemVersion;
			public ushort MinorSubsystemVersion;
			public uint Win32VersionValue;
			public uint SizeOfImage;
			public uint SizeOfHeaders;
			public uint CheckSum;
			public ImageSubSystem Subsystem;
			public ushort DllCharacteristics;
			public ulong SizeOfStackReserve;
			public ulong SizeOfStackCommit;
			public ulong SizeOfHeapReserve;
			public ulong SizeOfHeapCommit;
			public uint LoaderFlags;
			public uint NumberOfRvaAndSizes;
			public IMAGE_DATA_DIRECTORY ExportTable;
			public IMAGE_DATA_DIRECTORY ImportTable;
			public IMAGE_DATA_DIRECTORY ResourceTable;
			public IMAGE_DATA_DIRECTORY ExceptionTable;
			public IMAGE_DATA_DIRECTORY CertificateTable;
			public IMAGE_DATA_DIRECTORY BaseRelocationTable;
			public IMAGE_DATA_DIRECTORY Debug;
			public IMAGE_DATA_DIRECTORY Architecture;
			public IMAGE_DATA_DIRECTORY GlobalPtr;
			public IMAGE_DATA_DIRECTORY TLSTable;
			public IMAGE_DATA_DIRECTORY LoadConfigTable;
			public IMAGE_DATA_DIRECTORY BoundImport;
			public IMAGE_DATA_DIRECTORY IAT;
			public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
			public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
			public IMAGE_DATA_DIRECTORY Reserved;
		}

		[SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct IMAGE_FILE_HEADER
		{
			public MachineType Machine;
			public ushort NumberOfSections;
			public uint TimeDateStamp;
			public uint PointerToSymbolTable;
			public uint NumberOfSymbols;
			public ushort SizeOfOptionalHeader;
			public ImageCharacteristics Characteristics;
		}

		[SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "<Pending>")]
		[StructLayout(LayoutKind.Explicit)]
		public struct IMAGE_SECTION_HEADER
		{
			[FieldOffset(0)]
			[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
			public char[] Name;
			[FieldOffset(8)]
			public uint VirtualSize;
			[FieldOffset(12)]
			public uint VirtualAddress;
			[FieldOffset(16)]
			public uint SizeOfRawData;
			[FieldOffset(20)]
			public uint PointerToRawData;
			[FieldOffset(24)]
			public uint PointerToRelocations;
			[FieldOffset(28)]
			public uint PointerToLinenumbers;
			[FieldOffset(32)]
			public ushort NumberOfRelocations;
			[FieldOffset(34)]
			public ushort NumberOfLinenumbers;
			[FieldOffset(36)]
			public DataSection Characteristics;

			public string Section
			{
				get { return new string(Name); }
			}
		}
		#endregion

		#region "Private Fields"
		/// <summary>
		/// The DOS header
		/// </summary>
		private readonly IMAGE_DOS_HEADER _dosHeader;

		/// <summary>
		/// The file header
		/// </summary>
		private readonly IMAGE_FILE_HEADER _fileHeaderField;
		#endregion

		#region "public Methods"
		/// <summary>
		/// Initialize a new instance of the <see cref="PEHeaderReader"/> class
		/// </summary>
		/// <param name="filePath">Portable executable file path</param>
		public PEHeaderReader(String filePath)
		{
			// Read in the DLL or EXE and get the time-stamp
			using (FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
			{
				int headerNo = 0;

				using (BinaryReader bReader = new BinaryReader(fStream))
				{
					_dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(bReader);

					//Add 4 bytes to the offset
					fStream.Seek(_dosHeader.E_lfanew, SeekOrigin.Begin);
					bReader.ReadUInt32();

					_fileHeaderField = FromBinaryReader<IMAGE_FILE_HEADER>(bReader);

					if (Is32BitHeader)
						OptionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(bReader);
					else
						OptionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(bReader);

					ImageSectionHeaders = new IMAGE_SECTION_HEADER[_fileHeaderField.NumberOfSections - 1];

					while (headerNo < ImageSectionHeaders.Length)
					{
						ImageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(bReader);
						Interlocked.Increment(ref headerNo);
					}
				}
			}
		}

		public T FromBinaryReader<T>(BinaryReader reader)
		{
			T result = default(T);

			if (!(reader is null))
			{
				byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
				GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);

				result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
				handle.Free();
			}

			return result;
		}
		#endregion

		#region "public Properties"
		public bool Is32BitHeader
		{
			get { return FileHeader.Characteristics.HasFlag(ImageCharacteristics.IMAGE_FILE_32BIT_MACHINE); }
		}

		/// <summary>
		/// Gets the image file header
		/// </summary>
		public IMAGE_FILE_HEADER FileHeader
		{
			get { return _fileHeaderField; }
		}

		/// <summary>
		/// Gets the optional 32-bit header
		/// </summary>
		public IMAGE_OPTIONAL_HEADER32 OptionalHeader32;

		/// <summary>
		/// Gets the optional 64-bit header
		/// </summary>
		public IMAGE_OPTIONAL_HEADER64 OptionalHeader64;

#pragma warning disable CA1819 // Properties should not return arrays
		public IMAGE_SECTION_HEADER[] ImageSectionHeaders;
#pragma warning restore CA1819 // Properties should not return arrays

		/// <summary>
		/// Gets the time-stamp from the file header
		/// </summary>
		public DateTime TimeStamp
		{
			get
			{
				//Time-stamp is a date offset from 1970

				DateTime returnValue = new DateTime(1970, 1, 1, 0, 0, 0);

				// Add in the number of seconds since 1970/1/1
				returnValue = returnValue.AddSeconds(_fileHeaderField.TimeDateStamp);
				// Adjust to local timezone
				returnValue += TimeZone.CurrentTimeZone.GetUtcOffset(returnValue);
				return returnValue;
			}
		}

		[Flags]
		[SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification = "<Pending>")]
		public enum DataSection : uint
		{
			/// <summary>
			/// Reserved for future use.
			/// </summary>
			None = 0x0,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			// ReSharper disable UnusedMember.Global
			TypeDsect = 0x1,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			TypeNoLoad = 0x2,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			TypeGroup = 0x4,

			/// <summary>
			/// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
			/// </summary>
			TypeNoPadded = 0x8,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			TypeCopy = 0x10,

			/// <summary>
			/// The section contains executable code.
			/// </summary>
			ContentCode = 0x20,

			/// <summary>
			/// The section contains initialized data.
			/// </summary>
			ContentInitializedData = 0x40,

			/// <summary>
			/// The section contains uninitialized data.
			/// </summary>
			ContentUninitializedData = 0x80,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			LinkOther = 0x100,

			/// <summary>
			/// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
			/// </summary>
			LinkInfo = 0x200,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			TypeOver = 0x400,

			/// <summary>
			/// The section will not become part of the image. This is valid only for object files.
			/// </summary>
			LinkRemove = 0x800,

			/// <summary>
			/// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
			/// </summary>
			LinkComDat = 0x1000,

			/// <summary>
			/// Reset speculative exceptions handling bits in the TLB entries for this section.
			/// </summary>
			NoDeferSpecExceptions = 0x4000,

			/// <summary>
			/// The section contains data referenced through the global pointer (GP).
			/// </summary>
			RelativeGP = 0x8000,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			MemPurgeable = 0x20000,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			Memory16Bit = 0x20000,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			MemoryLocked = 0x40000,

			/// <summary>
			/// Reserved for future use.
			/// </summary>
			MemoryPreload = 0x80000,

			/// <summary>
			/// Align data on a 1-byte boundary. Valid only for object files.
			/// </summary>
			Align1Bytes = 0x100000,

			/// <summary>
			/// Align data on a 2-byte boundary. Valid only for object files.
			/// </summary>
			Align2Bytes = 0x200000,

			/// <summary>
			/// Align data on a 4-byte boundary. Valid only for object files.
			/// </summary>
			Align4Bytes = 0x300000,

			/// <summary>
			/// Align data on an 8-byte boundary. Valid only for object files.
			/// </summary>
			Align8Bytes = 0x400000,

			/// <summary>
			/// Align data on a 16-byte boundary. Valid only for object files.
			/// </summary>
			Align16Bytes = 0x500000,

			/// <summary>
			/// Align data on a 32-byte boundary. Valid only for object files.
			/// </summary>
			Align32Bytes = 0x600000,

			/// <summary>
			/// Align data on a 64-byte boundary. Valid only for object files.
			/// </summary>
			Align64Bytes = 0x700000,

			/// <summary>
			/// Align data on a 128-byte boundary. Valid only for object files.
			/// </summary>
			Align128Bytes = 0x800000,

			/// <summary>
			/// Align data on a 256-byte boundary. Valid only for object files.
			/// </summary>
			Align256Bytes = 0x900000,

			/// <summary>
			/// Align data on a 512-byte boundary. Valid only for object files.
			/// </summary>
			Align512Bytes = 0xA00000,

			/// <summary>
			/// Align data on a 1024-byte boundary. Valid only for object files.
			/// </summary>
			Align1024Bytes = 0xB00000,

			/// <summary>
			/// Align data on a 2048-byte boundary. Valid only for object files.
			/// </summary>
			Align2048Bytes = 0xC00000,

			/// <summary>
			/// Align data on a 4096-byte boundary. Valid only for object files.
			/// </summary>
			Align4096Bytes = 0xD00000,

			/// <summary>
			/// Align data on an 8192-byte boundary. Valid only for object files.
			/// </summary>
			Align8192Bytes = 0xE00000,

			/// <summary>
			/// The section contains extended relocations.
			/// </summary>
			LinkExtendedRelocationOverflow = 0x1000000,

			/// <summary>
			/// The section can be discarded as needed.
			/// </summary>
			MemoryDiscardable = 0x2000000,

			/// <summary>
			/// The section cannot be cached.
			/// </summary>
			MemoryNotCached = 0x4000000,

			/// <summary>
			/// The section is not pageable.
			/// </summary>
			MemoryNotPaged = 0x8000000,

			/// <summary>
			/// The section can be shared in memory.
			/// </summary>
			MemoryShared = 0x10000000,

			/// <summary>
			/// The section can be executed as code.
			/// </summary>
			MemoryExecute = 0x20000000,

			/// <summary>
			/// The section can be read.
			/// </summary>
			MemoryRead = 0x40000000

			/// <summary>
			/// The section can be written to.
			/// </summary>
			// MemoryWrite = 0x80000000

			// ReSharper restore UnusedMember.Global

		}

		[SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification = "<Pending>")]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		public enum ImageSubSystem : ushort
		{
			[Description("Unknown image subsystem")] IMAGE_SUBSYSTEM_UNKNOWN = 0,
			[Description("Native")] IMAGE_SUBSYSTEM_NATIVE = 1,
			[Description("Windows GUI")] IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
			[Description("Windows CUI")] IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
			[Description("OS/2 CUI")] IMAGE_SUBSYSTEM_OS2_CUI = 5,
			[Description("POSIX CUI")] IMAGE_SUBSYSTEM_POSIX_CUI = 7,
			[Description("Native Windows image subsystem")] IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8,
			[Description("Windows CE")] IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
			[Description("EFI")] IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
			[Description("EFI driver with boot services")] IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
			[Description("EFI driver with run-time services")] IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
			[Description("EFI ROM")] IMAGE_SUBSYSTEM_EFI_ROM = 13,
			[Description("Xbox")] IMAGE_SUBSYSTEM_XBOX = 14,
			[Description("Windows Boot")] IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16
		}

		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification = "<Pending>")]
		public enum MachineType : ushort
		{
			[Description("Unknown")] IMAGE_FILE_MACHINE_UNKNOWN = 0x0,

			/// <summary>
			/// Matsushita AM33 
			/// </summary>
			[Description("AM33")] IMAGE_FILE_MACHINE_AM33 = 0x1D3,

			/// <summary>
			/// x64
			/// </summary>
			[Description("AMD64")] IMAGE_FILE_MACHINE_AMD64 = 0x8664,

			/// <summary>
			/// ARM 
			/// </summary>
			[Description("ARM")] IMAGE_FILE_MACHINE_ARM = 0x1C0,

			/// <summary>
			/// ARM64
			/// </summary>
			[Description("ARM64")] IMAGE_FILE_MACHINE_ARM64 = 0xAA64,

			/// <summary>
			/// ARM Thumb-2 little endian 
			/// </summary>
			[Description("ARM Thumb-2")] IMAGE_FILE_MACHINE_ARMNT = 0x1C4,

			/// <summary>
			/// EFI byte code
			/// </summary>
			[Description("EFI byte Code")] IMAGE_FILE_MACHINE_EBC = 0xEBC,

			/// <summary>
			/// Intel 386 or later and compatible processors 
			/// </summary>
			[Description("Intel I386")] IMAGE_FILE_MACHINE_I386 = 0x14C,

			/// <summary>
			/// Intel Itanium
			/// </summary>
			[Description("IA-64")] IMAGE_FILE_MACHINE_IA64 = 0x200,

			/// <summary>
			/// Mitsubishi M32R little endian 
			/// </summary>
			[Description("M32R")] IMAGE_FILE_MACHINE_M32R = 0x9041,

			/// <summary>
			/// MIPS16
			/// </summary>
			[Description("MIPS16")] IMAGE_FILE_MACHINE_MIPS16 = 0x266,

			/// <summary>
			/// MIPS with FPU
			/// </summary>
			[Description("MIPS")] IMAGE_FILE_MACHINE_MIPSFPU = 0x366,

			/// <summary>
			/// MIPS16 with FPU
			/// </summary>
			[Description("MIPS16")] IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,

			/// <summary>
			/// Power PC little endian
			/// </summary>
			[Description("IBM PowerPC")] IMAGE_FILE_MACHINE_POWERPC = 0x1F0,

			/// <summary>
			/// Power PC with floating point support
			/// </summary>
			[Description("PowerPCFP")] IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,

			/// <summary>
			/// MIPS little endian
			/// </summary>
			[Description("MIPS")] IMAGE_FILE_MACHINE_R4000 = 0x166,

			/// <summary>
			/// RISC-V 32-bit address space
			/// </summary>
			[Description("RISC-V 32-bit")] IMAGE_FILE_MACHINE_RISCV32 = 0x5032,

			/// <summary>
			/// RISC-V 64-bit address space
			/// </summary>
			[Description("RISC-V 64-bit")] IMAGE_FILE_MACHINE_RISCV64 = 0x5064,

			/// <summary>
			/// RISC-V 128-bit address space
			/// </summary>
			[Description("RISC-V 128-bit")] IMAGE_FILE_MACHINE_RISCV128 = 0x5128,

			/// <summary>
			/// Hitachi SH3
			/// </summary>
			[Description("Hitachi SH3")] IMAGE_FILE_MACHINE_SH3 = 0x1A2,

			/// <summary>
			/// Hitachi SH3 DSP
			/// </summary>
			[Description("Hitachi SH3 DSP")] IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,

			/// <summary>
			/// Hitachi SH4
			/// </summary>
			[Description("Hitachi SH4")] IMAGE_FILE_MACHINE_SH4 = 0x1A6,

			/// <summary>
			/// Hitachi SH5
			/// </summary>
			[Description("Hitachi SH5")] IMAGE_FILE_MACHINE_SH5 = 0x1A8,

			/// <summary>
			/// Thumb
			/// </summary>
			[Description("Thumb")] IMAGE_FILE_MACHINE_THUMB = 0x1C2,

			/// <summary>
			/// MIPS little-endian WCE v2
			/// </summary>
			[Description("MIPS WCE v2")] IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
		}

		[Flags]
		[SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "<Pending>")]
		[SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification = "<Pending>")]
		public enum ImageCharacteristics : ushort
		{
			/// <summary>
			/// Image only, Windows CE, and Microsoft Windows NT and later. This indicates that the file does not contain base relocations and must therefore be loaded at its preferred base address. If the base address is not available, the loader reports an error. The default behavior of the linker is to strip base relocations from executable (EXE) files.
			/// </summary>
			[Description("Stripped Relocations")] IMAGE_FILE_RELOCS_STRIPPED = 0x1,

			/// <summary>
			/// Image only. This indicates that the image file is valid and can be run.If this flag is not set, it indicates a linker error.
			/// </summary>
			[Description("Executable File")] IMAGE_FILE_EXECUTABLE_IMAGE = 0x2,

			/// <summary>
			/// COFF line numbers have been removed. This flag is deprecated and should be zero.
			/// </summary>
			[Description("Stripped Line Numbers")] IMAGE_FILE_LINE_NUMS_STRIPPED = 0x4,

			/// <summary>
			/// COFF symbol table entries for local symbols have been removed.This flag is deprecated and should be zero.
			/// </summary>
			[Description("Stripped Local Symbols")] IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x8,

			/// <summary>
			/// Obsolete.Aggressively trim working set. This flag is deprecated for Windows 2000 and later and must be zero.
			/// </summary>
			[Description("Trimmed Working Set")] IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x10,

			/// <summary>
			/// Application can handle > 2-GB addresses.
			/// </summary>
			[Description("Handle Large Address")] IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x20,

#pragma warning disable CA1700 // Do not name enum values 'Reserved'
			/// <summary>
			/// This flag is reserved for future use.
			/// </summary>
			[Description("RESERVED")] RESERVED = 0x40,
#pragma warning restore CA1700 // Do not name enum values 'Reserved'

			/// <summary>
			/// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory.This flag is deprecated and should be zero.
			/// </summary>
			[Description("IMAGE_FILE_BYTES_REVERSED_LO")] IMAGE_FILE_BYTES_REVERSED_LO = 0x80,

			/// <summary>
			/// Machine is based on a 32-bit-word architecture.
			/// </summary>
			[Description("32-bit")] IMAGE_FILE_32BIT_MACHINE = 0x100,

			/// <summary>
			/// Debugging information is removed from the image file.
			/// </summary>
			[Description("No Debug Info")] IMAGE_FILE_DEBUG_STRIPPED = 0x200,

			/// <summary>
			/// If the image is on removable media, fully load it and copy it to the swap file.
			/// </summary>
			[Description("Located on Removable Media/Run from Swap")] IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x400,

			/// <summary>
			/// If the image is on network media, fully load it and copy it to the swap file.
			/// </summary>
			[Description("Located on Network Media/Run from Swap")] IMAGE_FILE_NET_RUN_FROM_SWAP = 0x800,

			/// <summary>
			/// The image file is a system file, not a user program.
			/// </summary>
			[Description("System File")] IMAGE_FILE_SYSTEM = 0x1000,

			/// <summary>
			/// The image file is a dynamic-link library (DLL). Such files are considered executable files for almost all purposes, although they cannot be directly run.
			/// </summary>
			[Description("DLL File")] IMAGE_FILE_DLL = 0x2000,

			/// <summary>
			/// The file should be run only on a uniprocessor machine.
			/// </summary>
			[Description("Uniprocessor Computer")] IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,

			/// <summary>
			/// Big endian: the MSB precedes the LSB in memory.This flag is deprecated and should be zero.
			/// </summary>
			[Description("IMAGE_FILE_BYTES_REVERSED_HI")] IMAGE_FILE_BYTES_REVERSED_HI = 0x8000,

		}
		#endregion
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment