using System.IO; namespace BurnOutSharp.Wrappers { public class PortableExecutable { #region Pass-Through Properties #region MS-DOS Stub #region Standard Fields /// public byte[] Stub_Magic => _executable.Stub.Header.Magic; /// public ushort Stub_LastPageBytes => _executable.Stub.Header.LastPageBytes; /// public ushort Stub_Pages => _executable.Stub.Header.Pages; /// public ushort Stub_RelocationItems => _executable.Stub.Header.RelocationItems; /// public ushort Stub_HeaderParagraphSize => _executable.Stub.Header.HeaderParagraphSize; /// public ushort Stub_MinimumExtraParagraphs => _executable.Stub.Header.MinimumExtraParagraphs; /// public ushort Stub_MaximumExtraParagraphs => _executable.Stub.Header.MaximumExtraParagraphs; /// public ushort Stub_InitialSSValue => _executable.Stub.Header.InitialSSValue; /// public ushort Stub_Stub_InitialSPValue => _executable.Stub.Header.InitialSPValue; /// public ushort Stub_Checksum => _executable.Stub.Header.Checksum; /// public ushort Stub_InitialIPValue => _executable.Stub.Header.InitialIPValue; /// public ushort Stub_InitialCSValue => _executable.Stub.Header.InitialCSValue; /// public ushort Stub_RelocationTableAddr => _executable.Stub.Header.RelocationTableAddr; /// public ushort Stub_OverlayNumber => _executable.Stub.Header.OverlayNumber; #endregion #region PE Extensions /// public ushort[] Stub_Reserved1 => _executable.Stub.Header.Reserved1; /// public ushort Stub_OEMIdentifier => _executable.Stub.Header.OEMIdentifier; /// public ushort Stub_OEMInformation => _executable.Stub.Header.OEMInformation; /// public ushort[] Stub_Reserved2 => _executable.Stub.Header.Reserved2; /// public uint Stub_NewExeHeaderAddr => _executable.Stub.Header.NewExeHeaderAddr; #endregion #endregion /// public byte[] Signature => _executable.Signature; #region COFF File Header /// public Models.PortableExecutable.MachineType Machine => _executable.COFFFileHeader.Machine; /// public ushort NumberOfSections => _executable.COFFFileHeader.NumberOfSections; /// public uint TimeDateStamp => _executable.COFFFileHeader.TimeDateStamp; /// public uint PointerToSymbolTable => _executable.COFFFileHeader.PointerToSymbolTable; /// public uint NumberOfSymbols => _executable.COFFFileHeader.NumberOfSymbols; /// public uint SizeOfOptionalHeader => _executable.COFFFileHeader.SizeOfOptionalHeader; /// public Models.PortableExecutable.Characteristics Characteristics => _executable.COFFFileHeader.Characteristics; #endregion #region Optional Header #region Standard Fields /// public Models.PortableExecutable.OptionalHeaderMagicNumber OH_Magic => _executable.OptionalHeader.Magic; /// public byte OH_MajorLinkerVersion => _executable.OptionalHeader.MajorLinkerVersion; /// public byte OH_MinorLinkerVersion => _executable.OptionalHeader.MinorLinkerVersion; /// public uint OH_SizeOfCode => _executable.OptionalHeader.SizeOfCode; /// public uint OH_SizeOfInitializedData => _executable.OptionalHeader.SizeOfInitializedData; /// public uint OH_SizeOfUninitializedData => _executable.OptionalHeader.SizeOfUninitializedData; /// public uint OH_AddressOfEntryPoint => _executable.OptionalHeader.AddressOfEntryPoint; /// public uint OH_BaseOfCode => _executable.OptionalHeader.BaseOfCode; /// public uint? OH_BaseOfData => _executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? (uint?)_executable.OptionalHeader.BaseOfData : null; #endregion #region Windows-Specific Fields /// public ulong OH_ImageBase => _executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _executable.OptionalHeader.ImageBase_PE32 : _executable.OptionalHeader.ImageBase_PE32Plus; /// public uint OH_SectionAlignment => _executable.OptionalHeader.SectionAlignment; /// public uint OH_FileAlignment => _executable.OptionalHeader.FileAlignment; /// public ushort OH_MajorOperatingSystemVersion => _executable.OptionalHeader.MajorOperatingSystemVersion; /// public ushort OH_MinorOperatingSystemVersion => _executable.OptionalHeader.MinorOperatingSystemVersion; /// public ushort OH_MajorImageVersion => _executable.OptionalHeader.MajorImageVersion; /// public ushort OH_MinorImageVersion => _executable.OptionalHeader.MinorImageVersion; /// public ushort OH_MajorSubsystemVersion => _executable.OptionalHeader.MajorSubsystemVersion; /// public ushort OH_MinorSubsystemVersion => _executable.OptionalHeader.MinorSubsystemVersion; /// public uint OH_Win32VersionValue => _executable.OptionalHeader.Win32VersionValue; /// public uint OH_SizeOfImage => _executable.OptionalHeader.SizeOfImage; /// public uint OH_SizeOfHeaders => _executable.OptionalHeader.SizeOfHeaders; /// public uint OH_CheckSum => _executable.OptionalHeader.CheckSum; /// public Models.PortableExecutable.WindowsSubsystem OH_Subsystem => _executable.OptionalHeader.Subsystem; /// public Models.PortableExecutable.DllCharacteristics OH_DllCharacteristics => _executable.OptionalHeader.DllCharacteristics; /// public ulong OH_SizeOfStackReserve => _executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _executable.OptionalHeader.SizeOfStackReserve_PE32 : _executable.OptionalHeader.SizeOfStackReserve_PE32Plus; /// public ulong OH_SizeOfStackCommit => _executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _executable.OptionalHeader.SizeOfStackCommit_PE32 : _executable.OptionalHeader.SizeOfStackCommit_PE32Plus; /// public ulong OH_SizeOfHeapReserve => _executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _executable.OptionalHeader.SizeOfHeapReserve_PE32 : _executable.OptionalHeader.SizeOfHeapReserve_PE32Plus; /// public ulong OH_SizeOfHeapCommit => _executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _executable.OptionalHeader.SizeOfHeapCommit_PE32 : _executable.OptionalHeader.SizeOfHeapCommit_PE32Plus; /// public uint OH_LoaderFlags => _executable.OptionalHeader.LoaderFlags; /// public uint OH_NumberOfRvaAndSizes => _executable.OptionalHeader.NumberOfRvaAndSizes; #endregion #region Data Directories /// public Models.PortableExecutable.DataDirectory OH_ExportTable => _executable.OptionalHeader.ExportTable; /// public Models.PortableExecutable.DataDirectory OH_ImportTable => _executable.OptionalHeader.ImportTable; /// public Models.PortableExecutable.DataDirectory OH_ResourceTable => _executable.OptionalHeader.ResourceTable; /// public Models.PortableExecutable.DataDirectory OH_ExceptionTable => _executable.OptionalHeader.ExceptionTable; /// public Models.PortableExecutable.DataDirectory OH_CertificateTable => _executable.OptionalHeader.CertificateTable; /// public Models.PortableExecutable.DataDirectory OH_BaseRelocationTable => _executable.OptionalHeader.BaseRelocationTable; /// public Models.PortableExecutable.DataDirectory OH_Debug => _executable.OptionalHeader.Debug; /// public ulong OH_Architecture => _executable.OptionalHeader.Architecture; /// public Models.PortableExecutable.DataDirectory OH_GlobalPtr => _executable.OptionalHeader.GlobalPtr; /// public Models.PortableExecutable.DataDirectory OH_ThreadLocalStorageTable => _executable.OptionalHeader.ThreadLocalStorageTable; /// public Models.PortableExecutable.DataDirectory OH_LoadConfigTable => _executable.OptionalHeader.LoadConfigTable; /// public Models.PortableExecutable.DataDirectory OH_BoundImport => _executable.OptionalHeader.BoundImport; /// public Models.PortableExecutable.DataDirectory OH_ImportAddressTable => _executable.OptionalHeader.ImportAddressTable; /// public Models.PortableExecutable.DataDirectory OH_DelayImportDescriptor => _executable.OptionalHeader.DelayImportDescriptor; /// public Models.PortableExecutable.DataDirectory OH_CLRRuntimeHeader => _executable.OptionalHeader.CLRRuntimeHeader; /// public ulong OH_Reserved => _executable.OptionalHeader.Reserved; #endregion #endregion #region Tables /// public Models.PortableExecutable.SectionHeader[] SectionTable => _executable.SectionTable; /// public Models.PortableExecutable.COFFSymbolTableEntry[] COFFSymbolTable => _executable.COFFSymbolTable; /// public Models.PortableExecutable.COFFStringTable COFFStringTable => _executable.COFFStringTable; /// public Models.PortableExecutable.AttributeCertificateTableEntry[] AttributeCertificateTable => _executable.AttributeCertificateTable; /// public Models.PortableExecutable.DelayLoadDirectoryTable DelayLoadDirectoryTable => _executable.DelayLoadDirectoryTable; #endregion #region Sections /// public Models.PortableExecutable.DebugTable DebugTable => _executable.DebugTable; /// public Models.PortableExecutable.ExportTable ExportTable => _executable.ExportTable; /// public Models.PortableExecutable.ImportTable ImportTable => _executable.ImportTable; /// public Models.PortableExecutable.ResourceDirectoryTable ResourceDirectoryTable => _executable.ResourceDirectoryTable; #endregion // TODO: Determine what properties can be passed through #endregion #region Extension Properties // TODO: Determine what extension properties are needed #endregion #region Instance Variables /// /// Internal representation of the executable /// private Models.PortableExecutable.Executable _executable; #endregion /// /// Private constructor /// private PortableExecutable() { } /// /// Create a PE executable from a byte array and offset /// /// Byte array representing the executable /// Offset within the array to parse /// A PE executable wrapper on success, null on failure public static PortableExecutable Create(byte[] data, int offset) { var executable = Builder.PortableExecutable.ParseExecutable(data, offset); if (executable == null) return null; var wrapper = new PortableExecutable { _executable = executable }; return wrapper; } /// /// Create a PE executable from a Stream /// /// Stream representing the executable /// A PE executable wrapper on success, null on failure public static PortableExecutable Create(Stream data) { var executable = Builder.PortableExecutable.ParseExecutable(data); if (executable == null) return null; var wrapper = new PortableExecutable { _executable = executable }; return wrapper; } } }