diff --git a/exeinfo/Program.cs b/exeinfo/Program.cs index ecbb0a9..9d5b538 100644 --- a/exeinfo/Program.cs +++ b/exeinfo/Program.cs @@ -33,7 +33,7 @@ using libexeinfo; namespace exeinfo { - class MainClass + static class MainClass { public static void Main(string[] args) { @@ -48,25 +48,25 @@ namespace exeinfo bool recognized = false; - MZ mzExe = new MZ(exeFs); - NE neExe = new NE(exeFs); - AtariST stExe = new AtariST(exeFs); - LX lxExe = new LX(exeFs); - COFF coffExe = new COFF(exeFs); - PE peExe = new PE(exeFs); + IExecutable mzExe = new MZ(exeFs); + IExecutable neExe = new NE(exeFs); + IExecutable stExe = new AtariST(exeFs); + IExecutable lxExe = new LX(exeFs); + IExecutable coffExe = new COFF(exeFs); + IExecutable peExe = new PE(exeFs); - if(mzExe.IsMZ) + if(mzExe.Recognized) { recognized = true; - Console.Write(mzExe.GetInfo()); + Console.Write(mzExe.Information); } - if(neExe.IsNE) + if(neExe.Recognized) { recognized = true; - Console.Write(neExe.GetInfo()); - if(neExe.Versions != null) - foreach(NE.Version vers in neExe.Versions) + Console.Write(neExe.Information); + if(((NE)neExe).Versions != null) + foreach(NE.Version vers in ((NE)neExe).Versions) { Console.WriteLine("\tVersion resource {0}:", vers.Name); Console.WriteLine("\t\tFile version: {0}", vers.FileVersion); @@ -117,28 +117,28 @@ namespace exeinfo } } - if(stExe.IsAtariST) + if(stExe.Recognized) { recognized = true; - Console.Write(stExe.GetInfo()); + Console.Write(stExe.Information); } - if(lxExe.IsLX) + if(lxExe.Recognized) { recognized = true; - Console.Write(lxExe.GetInfo()); + Console.Write(lxExe.Information); } - if(coffExe.IsCOFF) + if(coffExe.Recognized) { recognized = true; - Console.Write(coffExe.GetInfo()); + Console.Write(coffExe.Information); } - if(peExe.IsPE) + if(peExe.Recognized) { recognized = true; - Console.Write(peExe.GetInfo()); + Console.Write(peExe.Information); } if(!recognized) Console.WriteLine("Executable format not recognized"); diff --git a/exeinfogui/MainForm.xeto.cs b/exeinfogui/MainForm.xeto.cs index 2cdb708..35ea6c6 100644 --- a/exeinfogui/MainForm.xeto.cs +++ b/exeinfogui/MainForm.xeto.cs @@ -57,48 +57,48 @@ namespace exeinfogui FileStream exeFs = File.Open(dlgOpen.FileName, FileMode.Open, FileAccess.Read); - MZ mzExe = new MZ(exeFs); - NE neExe = new NE(exeFs); - AtariST stExe = new AtariST(exeFs); - LX lxExe = new LX(exeFs); - COFF coffExe = new COFF(exeFs); - PE peExe = new PE(exeFs); + IExecutable mzExe = new MZ(exeFs); + IExecutable neExe = new NE(exeFs); + IExecutable stExe = new AtariST(exeFs); + IExecutable lxExe = new LX(exeFs); + IExecutable coffExe = new COFF(exeFs); + IExecutable peExe = new PE(exeFs); - if(mzExe.IsMZ) + if(mzExe.Recognized) { - if(neExe.IsNE) + if(neExe.Recognized) { - txtType.Text = "New Executable (NE)"; - txtInformation.Text = neExe.GetInfo(); + txtType.Text = neExe.Type; + txtInformation.Text = neExe.Information; } - else if(lxExe.IsLX) + else if(lxExe.Recognized) { - txtType.Text = "Linear eXecutable (LX)"; - txtInformation.Text = lxExe.GetInfo(); + txtType.Text = lxExe.Type; + txtInformation.Text = lxExe.Information; } - else if(peExe.IsPE) + else if(peExe.Recognized) { - txtType.Text = "Portable Executable (PE)"; - txtInformation.Text = peExe.GetInfo(); + txtType.Text = peExe.Type; + txtInformation.Text = peExe.Information; } else - txtType.Text = "DOS Executable (MZ)"; + txtType.Text = mzExe.Type; - txtInformation.Text += mzExe.GetInfo(); + txtInformation.Text += mzExe.Information; } - else if(stExe.IsAtariST) + else if(stExe.Recognized) { - txtType.Text = "Atari ST executable"; - txtInformation.Text = stExe.GetInfo(); + txtType.Text = stExe.Type; + txtInformation.Text = stExe.Information; } - else if(coffExe.IsCOFF) + else if(coffExe.Recognized) { - txtType.Text = "Common Object File Format (COFF)"; - txtInformation.Text = coffExe.GetInfo(); + txtType.Text = coffExe.Type; + txtInformation.Text = coffExe.Information; } else txtType.Text = "Format not recognized"; - + exeFs.Close(); } diff --git a/libexeinfo/AtariST/AtariST.cs b/libexeinfo/AtariST/AtariST.cs index 596b5d5..9ead046 100644 --- a/libexeinfo/AtariST/AtariST.cs +++ b/libexeinfo/AtariST/AtariST.cs @@ -29,71 +29,82 @@ using System.Runtime.InteropServices; namespace libexeinfo { - /// - /// Represents an Atari ST executable - /// - public partial class AtariST + /// + /// Represents an Atari ST executable + /// + public partial class AtariST : IExecutable { - /// - /// The that contains the executable represented by this instance - /// - public readonly FileStream BaseStream; - /// - /// Header for this executable - /// - public readonly AtariHeader Header; - /// - /// If true this instance correctly represents an Atari ST executable - /// - public readonly bool IsAtariST; - - /// - /// Initializes a new instance of the class. - /// - /// Executable path. - public AtariST(string path) + /// + /// Initializes a new instance of the class. + /// + /// Executable path. + public AtariST(string path) { - byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; - - BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); - BaseStream.Position = 0; - BaseStream.Read(buffer, 0, buffer.Length); - Header = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); - IsAtariST = Header.signature == SIGNATURE; + BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); + Initialize(); } - /// - /// Initializes a new instance of the class. - /// - /// Stream containing the executable. - public AtariST(FileStream stream) + /// + /// Initializes a new instance of the class. + /// + /// Stream containing the executable. + public AtariST(Stream stream) { - byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; - - BaseStream = stream; - BaseStream.Position = 0; - BaseStream.Read(buffer, 0, buffer.Length); - Header = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); - IsAtariST = Header.signature == SIGNATURE; + BaseStream = stream; + Initialize(); } - /// - /// Identifies if the specified executable is a Atari ST executable - /// - /// true if the specified executable is a Atari ST executable, false otherwise. - /// Executable path. - public static bool Identify(string path) + /// + /// Initializes a new instance of the class. + /// + /// Byte array containing the executable. + public AtariST(byte[] data) + { + BaseStream = new MemoryStream(data); + Initialize(); + } + + /// + /// Header for this executable + /// + public AtariHeader Header { get; private set; } + public Stream BaseStream { get; } + public bool IsBigEndian => true; + public bool Recognized { get; private set; } + public string Type { get; private set; } + + void Initialize() + { + Recognized = false; + + if(BaseStream == null) return; + + byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; + BaseStream.Position = 0; + BaseStream.Read(buffer, 0, buffer.Length); + Header = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); + Recognized = Header.signature == SIGNATURE; + + if(Recognized) Type = "Atari ST executable"; + } + + /// + /// Identifies if the specified executable is a Atari ST executable + /// + /// true if the specified executable is a Atari ST executable, false otherwise. + /// Executable path. + public static bool Identify(string path) { FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read); return Identify(exeFs); } - /// - /// Identifies if the specified executable is a Atari ST executable - /// - /// true if the specified executable is a Atari ST executable, false otherwise. - /// Stream containing the executable. - public static bool Identify(FileStream stream) + /// + /// Identifies if the specified executable is a Atari ST executable + /// + /// true if the specified executable is a Atari ST executable, false otherwise. + /// Stream containing the executable. + public static bool Identify(Stream stream) { byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; diff --git a/libexeinfo/AtariST/Info.cs b/libexeinfo/AtariST/Info.cs index cd46913..7889b92 100644 --- a/libexeinfo/AtariST/Info.cs +++ b/libexeinfo/AtariST/Info.cs @@ -30,12 +30,18 @@ namespace libexeinfo { public partial class AtariST { - /// - /// Gets a string with human readable information for a given Atari ST header - /// - /// Human readable information for given Atari ST header. - /// Atari ST executable header. - public static string GetInfo(AtariHeader header) + /// + /// Gets a string with human readable information for the Atari ST executable represented by this instance + /// + /// Human readable information for this instance. + public string Information => GetInfo(Header); + + /// + /// Gets a string with human readable information for a given Atari ST header + /// + /// Human readable information for given Atari ST header. + /// Atari ST executable header. + static string GetInfo(AtariHeader header) { StringBuilder sb = new StringBuilder(); sb.AppendLine("Atari ST executable:"); @@ -45,14 +51,5 @@ namespace libexeinfo sb.AppendFormat("\t{0} bytes in symbol table", header.symb_len).AppendLine(); return sb.ToString(); } - - /// - /// Gets a string with human readable information for the Atari ST executable represented by this instance - /// - /// Human readable information for this instance. - public string GetInfo() - { - return GetInfo(Header); - } } } \ No newline at end of file diff --git a/libexeinfo/COFF/COFF.cs b/libexeinfo/COFF/COFF.cs index 232d912..c7855a7 100644 --- a/libexeinfo/COFF/COFF.cs +++ b/libexeinfo/COFF/COFF.cs @@ -30,102 +30,105 @@ using System.Runtime.InteropServices; namespace libexeinfo { - /// - /// Represents a Common Object File Format - /// - public partial class COFF + /// + /// Represents a Common Object File Format + /// + public partial class COFF : IExecutable { - /// - /// The that contains the executable represented by this instance - /// - public readonly FileStream BaseStream; - /// - /// Header for this executable - /// - public readonly COFFHeader Header; - public readonly bool IsBigEndian; - /// - /// If true this instance correctly represents a Common Object File Format - /// - public readonly bool IsCOFF; - - /// - /// Initializes a new instance of the class. - /// - /// Executable path. - public COFF(string path) + /// + /// Initializes a new instance of the class. + /// + /// Executable path. + public COFF(string path) { + BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); + Initialize(); + } + + /// + /// Initializes a new instance of the class. + /// + /// Stream containing the executable. + public COFF(Stream stream) + { + BaseStream = stream; + Initialize(); + } + + /// + /// Initializes a new instance of the class. + /// + /// Byte array containing the executable. + public COFF(byte[] data) + { + BaseStream = new MemoryStream(data); + Initialize(); + } + + /// + /// Header for this executable + /// + public COFFHeader Header { get; private set; } + /// + /// The that contains the executable represented by this instance + /// + public Stream BaseStream { get; } + public bool IsBigEndian { get; private set; } + /// + /// If true this instance correctly represents a Common Object File Format + /// + public bool Recognized { get; private set; } + public string Type { get; private set; } + + void Initialize() + { + Recognized = false; + if(BaseStream == null) return; + byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))]; - BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream.Position = 0; BaseStream.Read(buffer, 0, buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Header = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader)); Marshal.FreeHGlobal(hdrPtr); - IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || - Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC || - Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; - IsBigEndian = false; - - if(!IsCOFF) - { - Header = SwapHeader(Header); - IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || + Recognized = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC || Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; - IsBigEndian = !IsCOFF; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// Stream containing the executable. - public COFF(FileStream stream) - { - byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))]; - - BaseStream = stream; - BaseStream.Position = 0; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader)); - Marshal.FreeHGlobal(hdrPtr); - IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || - Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC || - Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; IsBigEndian = false; - if(!IsCOFF) + if(!Recognized) { - Header = SwapHeader(Header); - IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || - Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC || - Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; - IsBigEndian = !IsCOFF; + Header = SwapHeader(Header); + Recognized = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || + Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC || + Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; + IsBigEndian = !Recognized; } + + if(!Recognized) return; + + Type = "Common Object File Format (COFF)"; } - /// - /// Identifies if the specified executable is a Common Object File Format - /// - /// true if the specified executable is a Common Object File Format, false otherwise. - /// Executable path. - public static bool Identify(string path) + /// + /// Identifies if the specified executable is a Common Object File Format + /// + /// true if the specified executable is a Common Object File Format, false otherwise. + /// Executable path. + public static bool Identify(string path) { FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read); return Identify(exeFs); } - /// - /// Identifies if the specified executable is a Common Object File Format - /// - /// true if the specified executable is a Common Object File Format, false otherwise. - /// Stream containing the executable. - public static bool Identify(FileStream stream) + /// + /// Identifies if the specified executable is a Common Object File Format + /// + /// true if the specified executable is a Common Object File Format, false otherwise. + /// Stream containing the executable. + public static bool Identify(FileStream stream) { byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))]; @@ -133,17 +136,17 @@ namespace libexeinfo stream.Read(buffer, 0, buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - COFFHeader COFFHdr = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader)); + COFFHeader coffHdr = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader)); Marshal.FreeHGlobal(hdrPtr); - if(COFFHdr.optionalHeader.magic == STMAGIC || COFFHdr.optionalHeader.magic == OMAGIC || - COFFHdr.optionalHeader.magic == JMAGIC || COFFHdr.optionalHeader.magic == DMAGIC || - COFFHdr.optionalHeader.magic == ZMAGIC || COFFHdr.optionalHeader.magic == SHMAGIC) return true; + if(coffHdr.optionalHeader.magic == STMAGIC || coffHdr.optionalHeader.magic == OMAGIC || + coffHdr.optionalHeader.magic == JMAGIC || coffHdr.optionalHeader.magic == DMAGIC || + coffHdr.optionalHeader.magic == ZMAGIC || coffHdr.optionalHeader.magic == SHMAGIC) return true; - COFFHdr = SwapHeader(COFFHdr); - return COFFHdr.optionalHeader.magic == STMAGIC || COFFHdr.optionalHeader.magic == OMAGIC || - COFFHdr.optionalHeader.magic == JMAGIC || COFFHdr.optionalHeader.magic == DMAGIC || - COFFHdr.optionalHeader.magic == ZMAGIC || COFFHdr.optionalHeader.magic == SHMAGIC; + coffHdr = SwapHeader(coffHdr); + return coffHdr.optionalHeader.magic == STMAGIC || coffHdr.optionalHeader.magic == OMAGIC || + coffHdr.optionalHeader.magic == JMAGIC || coffHdr.optionalHeader.magic == DMAGIC || + coffHdr.optionalHeader.magic == ZMAGIC || coffHdr.optionalHeader.magic == SHMAGIC; } static COFFHeader SwapHeader(COFFHeader header) diff --git a/libexeinfo/COFF/Consts.cs b/libexeinfo/COFF/Consts.cs index 5faa0e8..0e6a3d4 100644 --- a/libexeinfo/COFF/Consts.cs +++ b/libexeinfo/COFF/Consts.cs @@ -28,86 +28,86 @@ namespace libexeinfo { public partial class COFF { - public const ushort STMAGIC = 0x101; - public const ushort OMAGIC = 0x104; - /// - /// dirty text and data image, can't share - /// - public const ushort JMAGIC = 0x107; - /// - /// dirty text segment, data aligned - /// - public const ushort DMAGIC = 0x108; - /// - /// The proper magic number for executables - /// - public const ushort ZMAGIC = 0x10b; - /// - /// shared library header - /// - public const ushort SHMAGIC = 0x123; + const ushort STMAGIC = 0x101; + const ushort OMAGIC = 0x104; + /// + /// dirty text and data image, can't share + /// + const ushort JMAGIC = 0x107; + /// + /// dirty text segment, data aligned + /// + const ushort DMAGIC = 0x108; + /// + /// The proper magic number for executables + /// + internal const ushort ZMAGIC = 0x10b; + /// + /// shared library header + /// + const ushort SHMAGIC = 0x123; - /// - /// Alpha architecture information - /// - public readonly string SectionAlpha = ".arch"; - /// - /// Uninitialized data - /// - public readonly string SectionBss = ".bss"; - /// - /// Initialized data - /// - public readonly string SectionData = ".data"; - /// - /// Debug information - /// - public readonly string SectionDebug = ".debug"; - /// - /// A .drectve section consists of a string of ASCII text. This string is - /// a series of linker options (each option containing hyphen, option - /// name, and any appropriate attribute) separated by spaces.The - /// .drectve section must not have relocations or line numbers. - /// - public readonly string SectionDirectives = ".drectve"; - /// - /// Exception information - /// - public readonly string SectioneXception = ".xdata"; - /// - /// Exception information - /// - public readonly string SectionException = ".pdata"; - /// - /// Executable code - /// - public readonly string SectionExecutable = ".text"; - /// - /// The export data section, named .edata, contains information about - /// symbols that other images can access through dynamic linking. - /// Exports are generally found in DLLs, but DLLs can import symbols as - /// well. - /// - public readonly string SectionExport = ".edata"; - /// - /// Import tables - /// - public readonly string SectionImport = ".idata"; - /// - /// Read-only initialized data - /// - public readonly string SectionReadOnly = ".rdata"; - /// - /// Image relocations - /// - public readonly string SectionRelocations = ".reloc"; - /// - /// Resource directory - /// - public readonly string SectionResource = ".rsrc"; - /// - /// Thread-local storage - /// - public readonly string SectionTls = ".tls"; + /// + /// Alpha architecture information + /// + public readonly string SectionAlpha = ".arch"; + /// + /// Uninitialized data + /// + public readonly string SectionBss = ".bss"; + /// + /// Initialized data + /// + public readonly string SectionData = ".data"; + /// + /// Debug information + /// + public readonly string SectionDebug = ".debug"; + /// + /// A .drectve section consists of a string of ASCII text. This string is + /// a series of linker options (each option containing hyphen, option + /// name, and any appropriate attribute) separated by spaces.The + /// .drectve section must not have relocations or line numbers. + /// + public readonly string SectionDirectives = ".drectve"; + /// + /// Exception information + /// + public readonly string SectioneXception = ".xdata"; + /// + /// Exception information + /// + public readonly string SectionException = ".pdata"; + /// + /// Executable code + /// + public readonly string SectionExecutable = ".text"; + /// + /// The export data section, named .edata, contains information about + /// symbols that other images can access through dynamic linking. + /// Exports are generally found in DLLs, but DLLs can import symbols as + /// well. + /// + public readonly string SectionExport = ".edata"; + /// + /// Import tables + /// + public readonly string SectionImport = ".idata"; + /// + /// Read-only initialized data + /// + public readonly string SectionReadOnly = ".rdata"; + /// + /// Image relocations + /// + public readonly string SectionRelocations = ".reloc"; + /// + /// Resource directory + /// + public readonly string SectionResource = ".rsrc"; + /// + /// Thread-local storage + /// + public readonly string SectionTls = ".tls"; } } \ No newline at end of file diff --git a/libexeinfo/COFF/Enums.cs b/libexeinfo/COFF/Enums.cs index 6d4b8ee..a1bedf0 100644 --- a/libexeinfo/COFF/Enums.cs +++ b/libexeinfo/COFF/Enums.cs @@ -26,398 +26,400 @@ using System; +// ReSharper disable InconsistentNaming + namespace libexeinfo { public partial class COFF { - /// - /// The Characteristics field contains flags that indicate attributes of the object or image file. - /// - [Flags] + /// + /// The Characteristics field contains flags that indicate attributes of the object or image file. + /// + [Flags] public enum Characteristics : ushort { - /// - /// 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. - /// - IMAGE_FILE_RELOCS_STRIPPED = 0x0001, - /// - /// 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. - /// - IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002, - /// - /// COFF line numbers have been removed. This flag is deprecated and should be zero. - /// - IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004, - /// - /// COFF symbol table entries for local symbols have been removed. This flag is deprecated and should be zero. - /// - IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008, - /// - /// Obsolete. Aggressively trim working set. This flag is deprecated for Windows 2000 and later and must be zero. - /// - IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010, - /// - /// Application can handle > 2-GB addresses. - /// - IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020, - /// - /// Machine is based on a 16-bit-word architecture. - /// - IMAGE_FILE_16BIT_MACHINE = 0x0040, - /// - /// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory. This flag is - /// deprecated and should be zero. - /// - IMAGE_FILE_BYTES_REVERSED_LO = 0x0080, - /// - /// Machine is based on a 32-bit-word architecture. - /// - IMAGE_FILE_32BIT_MACHINE = 0x0100, - /// - /// Debugging information is removed from the image file. - /// - IMAGE_FILE_DEBUG_STRIPPED = 0x0200, - /// - /// If the image is on removable media, fully load it and copy it to the swap file. - /// - IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400, - /// - /// If the image is on network media, fully load it and copy it to the swap file. - /// - IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800, - /// - /// The image file is a system file, not a user program. - /// - IMAGE_FILE_SYSTEM = 0x1000, - /// - /// 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. - /// - IMAGE_FILE_DLL = 0x2000, - /// - /// The file should be run only on a uniprocessor machine. - /// - IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000, - /// - /// Big endian: the MSB precedes the LSB in memory. This flag is deprecated and should be zero. - /// - IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 + /// + /// 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. + /// + IMAGE_FILE_RELOCS_STRIPPED = 0x0001, + /// + /// 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. + /// + IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002, + /// + /// COFF line numbers have been removed. This flag is deprecated and should be zero. + /// + IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004, + /// + /// COFF symbol table entries for local symbols have been removed. This flag is deprecated and should be zero. + /// + IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008, + /// + /// Obsolete. Aggressively trim working set. This flag is deprecated for Windows 2000 and later and must be zero. + /// + IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010, + /// + /// Application can handle > 2-GB addresses. + /// + IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020, + /// + /// Machine is based on a 16-bit-word architecture. + /// + IMAGE_FILE_16BIT_MACHINE = 0x0040, + /// + /// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory. This flag is + /// deprecated and should be zero. + /// + IMAGE_FILE_BYTES_REVERSED_LO = 0x0080, + /// + /// Machine is based on a 32-bit-word architecture. + /// + IMAGE_FILE_32BIT_MACHINE = 0x0100, + /// + /// Debugging information is removed from the image file. + /// + IMAGE_FILE_DEBUG_STRIPPED = 0x0200, + /// + /// If the image is on removable media, fully load it and copy it to the swap file. + /// + IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400, + /// + /// If the image is on network media, fully load it and copy it to the swap file. + /// + IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800, + /// + /// The image file is a system file, not a user program. + /// + IMAGE_FILE_SYSTEM = 0x1000, + /// + /// 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. + /// + IMAGE_FILE_DLL = 0x2000, + /// + /// The file should be run only on a uniprocessor machine. + /// + IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000, + /// + /// Big endian: the MSB precedes the LSB in memory. This flag is deprecated and should be zero. + /// + IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 } - /// - /// The Machine field has one of the following values that specifies its CPU type. An image file can be run only on the - /// specified machine or on a system that emulates the specified machine. - /// - public enum MachineTypes : ushort + /// + /// The Machine field has one of the following values that specifies its CPU type. An image file can be run only on the + /// specified machine or on a system that emulates the specified machine. + /// + public enum MachineTypes : ushort { - /// - /// The contents of this field are assumed to be applicable to any machine type - /// - IMAGE_FILE_MACHINE_UNKNOWN = 0x0, - /// - /// Alpha AXP - /// - IMAGE_FILE_MACHINE_ALPHA = 0x184, - /// - /// Alpha AXP 64-bit. - /// - IMAGE_FILE_MACHINE_ALPHA64 = 0x284, - /// - /// Matsushita AM33 - /// - IMAGE_FILE_MACHINE_AM33 = 0x1d3, - /// - /// x64 - /// - IMAGE_FILE_MACHINE_AMD64 = 0x8664, - /// - /// ARM little endian - /// - IMAGE_FILE_MACHINE_ARM = 0x1c0, - /// - /// ARM64 little endian - /// - IMAGE_FILE_MACHINE_ARM64 = 0xaa64, - /// - /// ARM Thumb-2 little endian - /// - IMAGE_FILE_MACHINE_ARMNT = 0x1c4, - /// - /// Clipper - /// - IMAGE_FILE_MACHINE_CLIPPER = 0x17f, - /// - /// EFI byte code - /// - IMAGE_FILE_MACHINE_EBC = 0xebc, - /// - /// Intel 386 or later processors and compatible processors - /// - IMAGE_FILE_MACHINE_I386 = 0x14c, - /// - /// Intel 386 or later processors and compatible processors, used by AIX - /// - IMAGE_FILE_MACHINE_I386_AIX = 0x175, - /// - /// Intel Itanium processor family - /// - IMAGE_FILE_MACHINE_IA64 = 0x200, - /// - /// Mitsubishi M32R little endian - /// - IMAGE_FILE_MACHINE_M32R = 0x9041, - /// - /// Motorola 68000 series - /// - IMAGE_FILE_MACHINE_M68K = 0x268, - /// - /// Motorola 68000 series - /// - IMAGE_FILE_MACHINE_M68K_OTHER = 0x150, - /// - /// MIPS16 - /// - IMAGE_FILE_MACHINE_MIPS16 = 0x266, - /// - /// MIPS with FPU - /// - IMAGE_FILE_MACHINE_MIPSFPU = 0x366, - /// - /// MIPS16 with FPU - /// - IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466, - /// - /// PowerPC little endian - /// - IMAGE_FILE_MACHINE_POWERPC = 0x1f0, - /// - /// Power PC with floating point support - /// - IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1, - /// - /// MIPS big endian - /// - IMAGE_FILE_MACHINE_MIPSEB = 0x160, - /// - /// MIPS little endian - /// - IMAGE_FILE_MACHINE_R3000 = 0x162, - /// - /// MIPS little endian - /// - IMAGE_FILE_MACHINE_R4000 = 0x166, - /// - /// MIPS little endian - /// - IMAGE_FILE_MACHINE_R10000 = 0x168, - /// - /// RISC-V 32-bit address space - /// - IMAGE_FILE_MACHINE_RISCV32 = 0x5032, - /// - /// RISC-V 64-bit address space - /// - IMAGE_FILE_MACHINE_RISCV64 = 0x5064, - /// - /// RISC-V 128-bit address space - /// - IMAGE_FILE_MACHINE_RISCV128 = 0x5128, - /// - /// Hitachi SH3 - /// - IMAGE_FILE_MACHINE_SH3 = 0x1a2, - /// - /// Hitachi SH3 DSP - /// - IMAGE_FILE_MACHINE_SH3DSP = 0x1a3, - /// - /// Hitachi SH4 - /// - IMAGE_FILE_MACHINE_SH4 = 0x1a6, - /// - /// Hitachi SH5 - /// - IMAGE_FILE_MACHINE_SH5 = 0x1a8, - /// - /// Thumb - /// - IMAGE_FILE_MACHINE_THUMB = 0x1c2, - /// - /// MIPS little-endian WCE v2 - /// - IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169, - /// - /// WE32000 - /// - IMAGE_FILE_MACHINE_WE32000 = 0x170 + /// + /// The contents of this field are assumed to be applicable to any machine type + /// + IMAGE_FILE_MACHINE_UNKNOWN = 0x0, + /// + /// Alpha AXP + /// + IMAGE_FILE_MACHINE_ALPHA = 0x184, + /// + /// Alpha AXP 64-bit. + /// + IMAGE_FILE_MACHINE_ALPHA64 = 0x284, + /// + /// Matsushita AM33 + /// + IMAGE_FILE_MACHINE_AM33 = 0x1d3, + /// + /// x64 + /// + IMAGE_FILE_MACHINE_AMD64 = 0x8664, + /// + /// ARM little endian + /// + IMAGE_FILE_MACHINE_ARM = 0x1c0, + /// + /// ARM64 little endian + /// + IMAGE_FILE_MACHINE_ARM64 = 0xaa64, + /// + /// ARM Thumb-2 little endian + /// + IMAGE_FILE_MACHINE_ARMNT = 0x1c4, + /// + /// Clipper + /// + IMAGE_FILE_MACHINE_CLIPPER = 0x17f, + /// + /// EFI byte code + /// + IMAGE_FILE_MACHINE_EBC = 0xebc, + /// + /// Intel 386 or later processors and compatible processors + /// + IMAGE_FILE_MACHINE_I386 = 0x14c, + /// + /// Intel 386 or later processors and compatible processors, used by AIX + /// + IMAGE_FILE_MACHINE_I386_AIX = 0x175, + /// + /// Intel Itanium processor family + /// + IMAGE_FILE_MACHINE_IA64 = 0x200, + /// + /// Mitsubishi M32R little endian + /// + IMAGE_FILE_MACHINE_M32R = 0x9041, + /// + /// Motorola 68000 series + /// + IMAGE_FILE_MACHINE_M68K = 0x268, + /// + /// Motorola 68000 series + /// + IMAGE_FILE_MACHINE_M68K_OTHER = 0x150, + /// + /// MIPS16 + /// + IMAGE_FILE_MACHINE_MIPS16 = 0x266, + /// + /// MIPS with FPU + /// + IMAGE_FILE_MACHINE_MIPSFPU = 0x366, + /// + /// MIPS16 with FPU + /// + IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466, + /// + /// PowerPC little endian + /// + IMAGE_FILE_MACHINE_POWERPC = 0x1f0, + /// + /// Power PC with floating point support + /// + IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1, + /// + /// MIPS big endian + /// + IMAGE_FILE_MACHINE_MIPSEB = 0x160, + /// + /// MIPS little endian + /// + IMAGE_FILE_MACHINE_R3000 = 0x162, + /// + /// MIPS little endian + /// + IMAGE_FILE_MACHINE_R4000 = 0x166, + /// + /// MIPS little endian + /// + IMAGE_FILE_MACHINE_R10000 = 0x168, + /// + /// RISC-V 32-bit address space + /// + IMAGE_FILE_MACHINE_RISCV32 = 0x5032, + /// + /// RISC-V 64-bit address space + /// + IMAGE_FILE_MACHINE_RISCV64 = 0x5064, + /// + /// RISC-V 128-bit address space + /// + IMAGE_FILE_MACHINE_RISCV128 = 0x5128, + /// + /// Hitachi SH3 + /// + IMAGE_FILE_MACHINE_SH3 = 0x1a2, + /// + /// Hitachi SH3 DSP + /// + IMAGE_FILE_MACHINE_SH3DSP = 0x1a3, + /// + /// Hitachi SH4 + /// + IMAGE_FILE_MACHINE_SH4 = 0x1a6, + /// + /// Hitachi SH5 + /// + IMAGE_FILE_MACHINE_SH5 = 0x1a8, + /// + /// Thumb + /// + IMAGE_FILE_MACHINE_THUMB = 0x1c2, + /// + /// MIPS little-endian WCE v2 + /// + IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169, + /// + /// WE32000 + /// + IMAGE_FILE_MACHINE_WE32000 = 0x170 } [Flags] public enum SectionFlags : uint { - /// - /// Reserved for future use. - /// - IMAGE_SCN_TYPE_DSECT = 0x00000001, - /// - /// Reserved for future use. - /// - IMAGE_SCN_TYPE_NOLOAD = 0x00000002, - /// - /// Reserved for future use. - /// - IMAGE_SCN_TYPE_GROUP = 0x00000004, - /// - /// Section should not be padded to next boundary. - /// This is obsolete and replaced by . - /// This is valid for object files only. - /// - IMAGE_SCN_TYPE_NO_PAD = 0x00000008, - /// - /// Reserved for future use. - /// - IMAGE_SCN_TYPE_COPY = 0x00000010, - /// - /// Section contains executable code. - /// - IMAGE_SCN_CNT_CODE = 0x00000020, - /// - /// Section contains initialized data. - /// - IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, - /// - /// Section contains uninitialized data. - /// - IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080, - /// - /// Reserved for future use. - /// - IMAGE_SCN_LNK_OTHER = 0x00000100, - /// - /// Section contains comments or other information. The .drectve section has this type. This is valid for object files - /// only. - /// - IMAGE_SCN_LNK_INFO = 0x00000200, - /// - /// Reserved for future use. - /// - IMAGE_SCN_TYPE_OVER = 0x00000400, - /// - /// Section will not become part of the image. This is valid for object files only. - /// - IMAGE_SCN_LNK_REMOVE = 0x00000800, - /// - /// Section contains COMDAT data. This is valid for object files only. - /// - IMAGE_SCN_LNK_COMDAT = 0x00001000, - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_FARDATA = 0x00008000, - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_16BIT = 0x00020000, - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_LOCKED = 0x00040000, - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_PRELOAD = 0x00080000, - /// - /// Align data on a 1-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_1BYTES = 0x00100000, - /// - /// Align data on a 2-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_2BYTES = 0x00200000, - /// - /// Align data on a 4-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_4BYTES = 0x00300000, - /// - /// Align data on a 8-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_8BYTES = 0x00400000, - /// - /// Align data on a 16-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_16BYTES = 0x00500000, - /// - /// Align data on a 32-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_32BYTES = 0x00600000, - /// - /// Align data on a 64-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_64BYTES = 0x00700000, - /// - /// Align data on a 128-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_128BYTES = 0x00800000, - /// - /// Align data on a 256-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_256BYTES = 0x00900000, - /// - /// Align data on a 512-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_512BYTES = 0x00A00000, - /// - /// Align data on a 1024-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000, - /// - /// Align data on a 2048-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000, - /// - /// Align data on a 4096-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000, - /// - /// Align data on a 8192-byte boundary. This is valid for object files only. - /// - IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000, - /// - /// Section contains extended relocations. - /// - IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000, - /// - /// Section can be discarded as needed. - /// - IMAGE_SCN_MEM_DISCARDABLE = 0x02000000, - /// - /// Section cannot be cached. - /// - IMAGE_SCN_MEM_NOT_CACHED = 0x04000000, - /// - /// Section is not pageable. - /// - IMAGE_SCN_MEM_NOT_PAGED = 0x08000000, - /// - /// Section can be shared in memory. - /// - IMAGE_SCN_MEM_SHARED = 0x10000000, - /// - /// Section can be executed as code. - /// - IMAGE_SCN_MEM_EXECUTE = 0x20000000, - /// - /// Section can be read. - /// - IMAGE_SCN_MEM_READ = 0x40000000, - /// - /// Section can be written to. - /// - IMAGE_SCN_MEM_WRITE = 0x80000000 + /// + /// Reserved for future use. + /// + IMAGE_SCN_TYPE_DSECT = 0x00000001, + /// + /// Reserved for future use. + /// + IMAGE_SCN_TYPE_NOLOAD = 0x00000002, + /// + /// Reserved for future use. + /// + IMAGE_SCN_TYPE_GROUP = 0x00000004, + /// + /// Section should not be padded to next boundary. + /// This is obsolete and replaced by . + /// This is valid for object files only. + /// + IMAGE_SCN_TYPE_NO_PAD = 0x00000008, + /// + /// Reserved for future use. + /// + IMAGE_SCN_TYPE_COPY = 0x00000010, + /// + /// Section contains executable code. + /// + IMAGE_SCN_CNT_CODE = 0x00000020, + /// + /// Section contains initialized data. + /// + IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, + /// + /// Section contains uninitialized data. + /// + IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080, + /// + /// Reserved for future use. + /// + IMAGE_SCN_LNK_OTHER = 0x00000100, + /// + /// Section contains comments or other information. The .drectve section has this type. This is valid for object files + /// only. + /// + IMAGE_SCN_LNK_INFO = 0x00000200, + /// + /// Reserved for future use. + /// + IMAGE_SCN_TYPE_OVER = 0x00000400, + /// + /// Section will not become part of the image. This is valid for object files only. + /// + IMAGE_SCN_LNK_REMOVE = 0x00000800, + /// + /// Section contains COMDAT data. This is valid for object files only. + /// + IMAGE_SCN_LNK_COMDAT = 0x00001000, + /// + /// Reserved for future use. + /// + IMAGE_SCN_MEM_FARDATA = 0x00008000, + /// + /// Reserved for future use. + /// + IMAGE_SCN_MEM_16BIT = 0x00020000, + /// + /// Reserved for future use. + /// + IMAGE_SCN_MEM_LOCKED = 0x00040000, + /// + /// Reserved for future use. + /// + IMAGE_SCN_MEM_PRELOAD = 0x00080000, + /// + /// Align data on a 1-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_1BYTES = 0x00100000, + /// + /// Align data on a 2-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_2BYTES = 0x00200000, + /// + /// Align data on a 4-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_4BYTES = 0x00300000, + /// + /// Align data on a 8-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_8BYTES = 0x00400000, + /// + /// Align data on a 16-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_16BYTES = 0x00500000, + /// + /// Align data on a 32-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_32BYTES = 0x00600000, + /// + /// Align data on a 64-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_64BYTES = 0x00700000, + /// + /// Align data on a 128-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_128BYTES = 0x00800000, + /// + /// Align data on a 256-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_256BYTES = 0x00900000, + /// + /// Align data on a 512-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_512BYTES = 0x00A00000, + /// + /// Align data on a 1024-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000, + /// + /// Align data on a 2048-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000, + /// + /// Align data on a 4096-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000, + /// + /// Align data on a 8192-byte boundary. This is valid for object files only. + /// + IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000, + /// + /// Section contains extended relocations. + /// + IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000, + /// + /// Section can be discarded as needed. + /// + IMAGE_SCN_MEM_DISCARDABLE = 0x02000000, + /// + /// Section cannot be cached. + /// + IMAGE_SCN_MEM_NOT_CACHED = 0x04000000, + /// + /// Section is not pageable. + /// + IMAGE_SCN_MEM_NOT_PAGED = 0x08000000, + /// + /// Section can be shared in memory. + /// + IMAGE_SCN_MEM_SHARED = 0x10000000, + /// + /// Section can be executed as code. + /// + IMAGE_SCN_MEM_EXECUTE = 0x20000000, + /// + /// Section can be read. + /// + IMAGE_SCN_MEM_READ = 0x40000000, + /// + /// Section can be written to. + /// + IMAGE_SCN_MEM_WRITE = 0x80000000 } public const uint IMAGE_SCN_ALIGN_MASK = 0x00F00000; diff --git a/libexeinfo/COFF/Info.cs b/libexeinfo/COFF/Info.cs index 00e01ab..63551d1 100644 --- a/libexeinfo/COFF/Info.cs +++ b/libexeinfo/COFF/Info.cs @@ -31,7 +31,9 @@ namespace libexeinfo { public partial class COFF { - public static string GetInfo(COFFHeader header) + public string Information => GetInfo(Header); + + internal static string GetInfo(COFFHeader header) { DateTime epoch = new DateTime(1970, 1, 1); StringBuilder sb = new StringBuilder(); @@ -63,9 +65,9 @@ namespace libexeinfo if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_RELOCS_STRIPPED)) sb.AppendLine("\tExecutable contains no relocations."); - if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_EXECUTABLE_IMAGE)) - sb.AppendLine("\tExecutable is valid."); - else sb.AppendLine("\tExecutable is invalid, contains errors or has not been linked correctly."); + sb.AppendLine(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_EXECUTABLE_IMAGE) + ? "\tExecutable is valid." + : "\tExecutable is invalid, contains errors or has not been linked correctly."); if(!header.characteristics.HasFlag(Characteristics.IMAGE_FILE_LINE_NUMS_STRIPPED)) sb.AppendLine("\tExecutable contains line numbers."); if(!header.characteristics.HasFlag(Characteristics.IMAGE_FILE_LOCAL_SYMS_STRIPPED)) @@ -114,10 +116,5 @@ namespace libexeinfo sb.AppendFormat("\tData starts at {0}", header.optionalHeader.baseOfData).AppendLine(); return sb.ToString(); } - - public string GetInfo() - { - return GetInfo(Header); - } } } \ No newline at end of file diff --git a/libexeinfo/COFF/MachineTypes.cs b/libexeinfo/COFF/MachineTypes.cs index 3af9a29..0113eff 100644 --- a/libexeinfo/COFF/MachineTypes.cs +++ b/libexeinfo/COFF/MachineTypes.cs @@ -28,7 +28,7 @@ namespace libexeinfo { public partial class COFF { - public static string MachineTypeToString(MachineTypes machine) + static string MachineTypeToString(MachineTypes machine) { switch(machine) { @@ -69,7 +69,7 @@ namespace libexeinfo case MachineTypes.IMAGE_FILE_MACHINE_CLIPPER: return "Clipper"; case MachineTypes.IMAGE_FILE_MACHINE_WE32000: return "WE32000 series"; default: - return string.Format("Unknown machine type with code {0}", (ushort)machine); + return $"Unknown machine type with code {(ushort)machine}"; } } } diff --git a/libexeinfo/IExecutable.cs b/libexeinfo/IExecutable.cs new file mode 100644 index 0000000..7ccbc97 --- /dev/null +++ b/libexeinfo/IExecutable.cs @@ -0,0 +1,28 @@ +using System.IO; + +namespace libexeinfo +{ + public interface IExecutable + { + /// + /// If true the executable is recognized by this instance + /// + bool Recognized { get; } + /// + /// Name of executable format + /// + string Type { get; } + /// + /// The that contains the executable represented by this instance + /// + Stream BaseStream { get; } + /// + /// If true the executable is for a big-endian architecture + /// + bool IsBigEndian { get; } + /// + /// General description of executable contents + /// + string Information { get; } + } +} \ No newline at end of file diff --git a/libexeinfo/LX/Consts.cs b/libexeinfo/LX/Consts.cs index 597f544..6b9b288 100644 --- a/libexeinfo/LX/Consts.cs +++ b/libexeinfo/LX/Consts.cs @@ -28,13 +28,13 @@ namespace libexeinfo { public partial class LX { - /// - /// Linear Executable signature, "LE" - /// - public const ushort Signature16 = 0x454C; - /// - /// Linear eXecutable signature, "LX" - /// - public const ushort Signature = 0x584C; + /// + /// Linear Executable signature, "LE" + /// + public const ushort Signature16 = 0x454C; + /// + /// Linear eXecutable signature, "LX" + /// + public const ushort Signature = 0x584C; } } \ No newline at end of file diff --git a/libexeinfo/LX/Enums.cs b/libexeinfo/LX/Enums.cs index ae2a051..b094210 100644 --- a/libexeinfo/LX/Enums.cs +++ b/libexeinfo/LX/Enums.cs @@ -30,60 +30,60 @@ namespace libexeinfo { public partial class LX { - /// - /// Executable module flags. - /// - [Flags] + /// + /// Executable module flags. + /// + [Flags] public enum ModuleFlags : uint { - /// - /// Per-Process Library Initialization - /// - PerProcessLibrary = 0x04, - /// - /// Internal fixups for the module have been applied - /// - InternalFixups = 0x10, - /// - /// External fixups for the module have been applied - /// - ExternalFixups = 0x20, - /// - /// Incompatible with Presentation Manager - /// - PMIncompatible = 0x100, - /// - /// Compatible with Presentation Manager - /// - PMCompatible = 0x200, - /// - /// Uses Presentation Manager - /// - UsesPM = 0x300, - /// - /// Module is not loadable. Contains errors or is being linked - /// - NotLoadable = 0x2000, - /// - /// Library module - /// - Library = 0x8000, - /// - /// Protected Memory Library module - /// - ProtectedMemoryLibrary = 0x18000, - /// - /// Physical Device Driver module - /// - PhysicalDeviceDriver = 0x20000, - /// - /// Virtual Device Driver module - /// - VirtualDeviceDriver = 0x28000, - /// - /// Per-process Library Termination - /// - PerProcessTermination = 0x40000000 + /// + /// Per-Process Library Initialization + /// + PerProcessLibrary = 0x04, + /// + /// Internal fixups for the module have been applied + /// + InternalFixups = 0x10, + /// + /// External fixups for the module have been applied + /// + ExternalFixups = 0x20, + /// + /// Incompatible with Presentation Manager + /// + PMIncompatible = 0x100, + /// + /// Compatible with Presentation Manager + /// + PMCompatible = 0x200, + /// + /// Uses Presentation Manager + /// + UsesPM = 0x300, + /// + /// Module is not loadable. Contains errors or is being linked + /// + NotLoadable = 0x2000, + /// + /// Library module + /// + Library = 0x8000, + /// + /// Protected Memory Library module + /// + ProtectedMemoryLibrary = 0x18000, + /// + /// Physical Device Driver module + /// + PhysicalDeviceDriver = 0x20000, + /// + /// Virtual Device Driver module + /// + VirtualDeviceDriver = 0x28000, + /// + /// Per-process Library Termination + /// + PerProcessTermination = 0x40000000 } public enum TargetCpu : ushort @@ -100,10 +100,10 @@ namespace libexeinfo MIPS3 = 0x42 } - /// - /// Target operating system. - /// - public enum TargetOS : ushort + /// + /// Target operating system. + /// + public enum TargetOS : ushort { Unknown = 0, OS2 = 1, diff --git a/libexeinfo/LX/Info.cs b/libexeinfo/LX/Info.cs index 40dadc3..cc416e3 100644 --- a/libexeinfo/LX/Info.cs +++ b/libexeinfo/LX/Info.cs @@ -30,6 +30,8 @@ namespace libexeinfo { public partial class LX { + public string Information => GetInfo(Header); + public static string GetInfo(LXHeader header) { StringBuilder sb = new StringBuilder(); @@ -187,10 +189,5 @@ namespace libexeinfo sb.AppendFormat("\tHeap size added to the auto ds object: {0}", header.heap_size).AppendLine(); return sb.ToString(); } - - public string GetInfo() - { - return GetInfo(Header); - } } } \ No newline at end of file diff --git a/libexeinfo/LX/LX.cs b/libexeinfo/LX/LX.cs index 18134b7..3df895d 100644 --- a/libexeinfo/LX/LX.cs +++ b/libexeinfo/LX/LX.cs @@ -34,21 +34,23 @@ namespace libexeinfo /// Represents a Microsoft/IBM Linear EXecutable /// // TODO: Big-endian (really needed?) - public partial class LX + public partial class LX : IExecutable { - public readonly MZ BaseExecutable; + MZ BaseExecutable; /// /// The that contains the executable represented by this instance /// - public readonly FileStream BaseStream; + public Stream BaseStream { get; } + public bool IsBigEndian => false; /// /// Header for this executable /// - public readonly LXHeader Header; + LXHeader Header; /// /// If true this instance correctly represents a Microsoft/IBM Linear EXecutable /// - public readonly bool IsLX; + public bool Recognized { get; private set;} + public string Type { get; private set;} /// /// Initializes a new instance of the class. @@ -56,46 +58,53 @@ namespace libexeinfo /// Executable path. public LX(string path) { - IsLX = false; BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); - BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); - Marshal.FreeHGlobal(hdrPtr); - IsLX = Header.signature == Signature || Header.signature == Signature16; - } + Initialize(); } /// /// Initializes a new instance of the class. /// /// Stream containing the executable. - public LX(FileStream stream) + public LX(Stream stream) { - IsLX = false; BaseStream = stream; - BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); - Marshal.FreeHGlobal(hdrPtr); - IsLX = Header.signature == Signature || Header.signature == Signature16; - } + Initialize(); } + /// + /// Initializes a new instance of the class. + /// + /// Byte array containing the executable. + public LX(byte[] data) + { + BaseStream = new MemoryStream(data); + Initialize(); + } + + void Initialize() + { + Recognized = false; + if(BaseStream == null) return; + BaseExecutable = new MZ(BaseStream); + if(!BaseExecutable.Recognized) return; + + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); + Marshal.FreeHGlobal(hdrPtr); + Recognized = Header.signature == Signature || Header.signature == Signature16; + + if(!Recognized) return; + + Type = Header.signature == Signature16 ? "Linear Executable (LE)" : "Linear eXecutable (LX)"; + } + /// /// Identifies if the specified executable is a Microsoft/IBM Linear EXecutable /// @@ -105,20 +114,19 @@ namespace libexeinfo { FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); MZ BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); - Marshal.FreeHGlobal(hdrPtr); - return Header.signature == Signature || Header.signature == Signature16; - } + if(!BaseExecutable.Recognized) return false; + + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); + Marshal.FreeHGlobal(hdrPtr); + return Header.signature == Signature || Header.signature == Signature16; - return false; } /// @@ -130,20 +138,19 @@ namespace libexeinfo { FileStream BaseStream = stream; MZ BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); - Marshal.FreeHGlobal(hdrPtr); - return Header.signature == Signature || Header.signature == Signature16; - } + if(!BaseExecutable.Recognized) return false; + + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); + Marshal.FreeHGlobal(hdrPtr); + return Header.signature == Signature || Header.signature == Signature16; - return false; } } } \ No newline at end of file diff --git a/libexeinfo/MZ/Consts.cs b/libexeinfo/MZ/Consts.cs index 9943be4..257956f 100644 --- a/libexeinfo/MZ/Consts.cs +++ b/libexeinfo/MZ/Consts.cs @@ -28,9 +28,9 @@ namespace libexeinfo { public partial class MZ { - /// - /// MZ executable signature, "MZ" - /// - public const ushort Signature = 0x5A4D; + /// + /// MZ executable signature, "MZ" + /// + public const ushort Signature = 0x5A4D; } } \ No newline at end of file diff --git a/libexeinfo/MZ/Info.cs b/libexeinfo/MZ/Info.cs index 8ec5b02..15baeed 100644 --- a/libexeinfo/MZ/Info.cs +++ b/libexeinfo/MZ/Info.cs @@ -30,12 +30,18 @@ namespace libexeinfo { public partial class MZ { - /// - /// Gets a string with human readable information for a given MZ header - /// - /// Human readable information for given MZ header. - /// MZ executable header. - public static string GetInfo(MZHeader header) + /// + /// Gets a string with human readable information for the MZ executable represented by this instance + /// + /// Human readable information for this instance. + public string Information => GetInfo(Header); + + /// + /// Gets a string with human readable information for a given MZ header + /// + /// Human readable information for given MZ header. + /// MZ executable header. + public static string GetInfo(MZHeader header) { StringBuilder sb = new StringBuilder(); sb.AppendLine("DOS MZ executable:"); @@ -60,14 +66,5 @@ namespace libexeinfo sb.AppendFormat("\tOffset to new header: {0}", header.new_offset).AppendLine(); return sb.ToString(); } - - /// - /// Gets a string with human readable information for the MZ executable represented by this instance - /// - /// Human readable information for this instance. - public string GetInfo() - { - return GetInfo(Header); - } } } \ No newline at end of file diff --git a/libexeinfo/MZ/MZ.cs b/libexeinfo/MZ/MZ.cs index ed679ec..1a576f8 100644 --- a/libexeinfo/MZ/MZ.cs +++ b/libexeinfo/MZ/MZ.cs @@ -30,77 +30,94 @@ using System.Runtime.InteropServices; namespace libexeinfo { - /// - /// Represents a DOS relocatable executable - /// - public partial class MZ + /// + /// Represents a DOS relocatable executable + /// + public partial class MZ : IExecutable { - /// - /// The that contains the executable represented by this instance - /// - public readonly FileStream BaseStream; - /// - /// Header for this executable - /// - public readonly MZHeader Header; - /// - /// If true this instance correctly represents a DOS relocatable executable - /// - public readonly bool IsMZ; + /// + /// Header for this executable + /// + internal MZHeader Header; - /// - /// Initializes a new instance of the class. - /// - /// Executable path. - public MZ(string path) + /// + /// Initializes a new instance of the class. + /// + /// Executable path. + public MZ(string path) { + BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); + Initialize(); + } + + /// + /// Initializes a new instance of the class. + /// + /// Stream containing the executable. + public MZ(Stream stream) + { + BaseStream = stream; + Initialize(); + } + + /// + /// Initializes a new instance of the class. + /// + /// Byte array containing the executable. + public MZ(byte[] data) + { + BaseStream = new MemoryStream(data); + Initialize(); + } + + /// + /// The that contains the executable represented by this instance + /// + public Stream BaseStream { get; } + public bool IsBigEndian => false; + /// + /// If true this instance correctly represents a DOS relocatable executable + /// + public bool Recognized { get; private set; } + public string Type { get; private set; } + + void Initialize() + { + Recognized = false; + if(BaseStream == null) return; + byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))]; - BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream.Position = 0; BaseStream.Read(buffer, 0, buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Header = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader)); Marshal.FreeHGlobal(hdrPtr); - IsMZ = Header.signature == Signature; + Recognized = Header.signature == Signature; + + if(!Recognized) return; + + Type = "DOS Executable (MZ)"; } - /// - /// Initializes a new instance of the class. - /// - /// Stream containing the executable. - public MZ(FileStream stream) - { - byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))]; - - BaseStream = stream; - BaseStream.Position = 0; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader)); - Marshal.FreeHGlobal(hdrPtr); - IsMZ = Header.signature == Signature; - } - - /// - /// Identifies if the specified executable is a DOS relocatable executable - /// - /// true if the specified executable is a DOS relocatable executable, false otherwise. - /// Executable path. - public static bool Identify(string path) + /// + /// Identifies if the specified executable is a DOS relocatable executable + /// + /// true if the specified executable is a DOS relocatable executable, false otherwise. + /// Executable path. + public static bool Identify(string path) { FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read); return Identify(exeFs); } - /// - /// Identifies if the specified executable is a DOS relocatable executable - /// - /// true if the specified executable is a DOS relocatable executable, false otherwise. - /// Stream containing the executable. - public static bool Identify(FileStream stream) + /// + /// Identifies if the specified executable is a DOS relocatable executable + /// + /// true if the specified executable is a DOS relocatable executable, false otherwise. + /// Stream containing the executable. + public static bool Identify(FileStream stream) { byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))]; diff --git a/libexeinfo/NE/Consts.cs b/libexeinfo/NE/Consts.cs index 5ba94d4..cf8a0bb 100644 --- a/libexeinfo/NE/Consts.cs +++ b/libexeinfo/NE/Consts.cs @@ -28,25 +28,25 @@ namespace libexeinfo { public partial class NE { - /// - /// New Executable signature, "NE" - /// - public const ushort Signature = 0x454E; - /// - /// Signature for a - /// - public static readonly string FixedFileInfoSig = "VS_VERSION_INFO"; - /// - /// Signature for list of name=value strings inside a version resource - /// - public static readonly string StringFileInfo = "StringFileInfo"; + /// + /// New Executable signature, "NE" + /// + public const ushort Signature = 0x454E; + /// + /// Signature for a + /// + public static readonly string FixedFileInfoSig = "VS_VERSION_INFO"; + /// + /// Signature for list of name=value strings inside a version resource + /// + public static readonly string StringFileInfo = "StringFileInfo"; - /// - /// Gets the name of a resource type according to its identifier - /// - /// The resource type name. - /// Resource type identifier. - public static string ResourceIdToName(ushort id) + /// + /// Gets the name of a resource type according to its identifier + /// + /// The resource type name. + /// Resource type identifier. + public static string ResourceIdToName(ushort id) { switch(id & 0x7FFF) { diff --git a/libexeinfo/NE/Info.cs b/libexeinfo/NE/Info.cs index ea26287..f2f75e2 100644 --- a/libexeinfo/NE/Info.cs +++ b/libexeinfo/NE/Info.cs @@ -33,6 +33,8 @@ namespace libexeinfo { public partial class NE { + public string Information => GetInfo(Header); + public static string GetInfo(NEHeader header) { StringBuilder sb = new StringBuilder(); @@ -192,12 +194,7 @@ namespace libexeinfo return sb.ToString(); } - public string GetInfo() - { - return GetInfo(Header); - } - - public static ResourceTable GetResources(FileStream stream, uint neStart, ushort tableOff) + public static ResourceTable GetResources(Stream stream, uint neStart, ushort tableOff) { long oldPosition = stream.Position; byte[] DW = new byte[2]; diff --git a/libexeinfo/NE/NE.cs b/libexeinfo/NE/NE.cs index 2d3dd89..0eb9c4c 100644 --- a/libexeinfo/NE/NE.cs +++ b/libexeinfo/NE/NE.cs @@ -30,139 +30,131 @@ using System.Runtime.InteropServices; namespace libexeinfo { - /// - /// Represents a Microsoft New Executable - /// - public partial class NE + /// + /// Represents a Microsoft New Executable + /// + public partial class NE : IExecutable { - public readonly MZ BaseExecutable; - /// - /// The that contains the executable represented by this instance - /// - public readonly FileStream BaseStream; - /// - /// Header for this executable - /// - public readonly NEHeader Header; - /// - /// If true this instance correctly represents a Microsoft New Executable - /// - public readonly bool IsNE; - public readonly ResourceTable Resources; - public readonly Version[] Versions; + MZ BaseExecutable; + /// + /// Header for this executable + /// + public NEHeader Header; + public ResourceTable Resources; + public Version[] Versions; - /// - /// Initializes a new instance of the class. - /// - /// Executable path. - public NE(string path) + /// + /// Initializes a new instance of the class. + /// + /// Executable path. + public NE(string path) { - IsNE = false; - BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); - BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); - Marshal.FreeHGlobal(hdrPtr); - if(Header.signature == Signature) - { - IsNE = true; - if(Header.resource_entries > 0) - { - Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, - Header.resource_table_offset); - Versions = GetVersions().ToArray(); - } - } - } + BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); + Initialize(); } - /// - /// Initializes a new instance of the class. - /// - /// Stream containing the executable. - public NE(FileStream stream) + /// + /// Initializes a new instance of the class. + /// + /// Stream containing the executable. + public NE(Stream stream) { - IsNE = false; - BaseStream = stream; - BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); - Marshal.FreeHGlobal(hdrPtr); - if(Header.signature == Signature) - { - IsNE = true; - if(Header.resource_entries > 0) - { - Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, - Header.resource_table_offset); - Versions = GetVersions().ToArray(); - } - } - } + BaseStream = stream; + Initialize(); } - /// - /// Identifies if the specified executable is a Microsoft New Executable - /// - /// true if the specified executable is a Microsoft New Executable, false otherwise. - /// Executable path. - public static bool Identify(string path) + /// + /// Initializes a new instance of the class. + /// + /// Stream containing the executable. + public NE(byte[] data) + { + BaseStream = new MemoryStream(data); + Initialize(); + } + + /// + /// The that contains the executable represented by this instance + /// + public Stream BaseStream { get; } + public bool IsBigEndian => false; + /// + /// If true this instance correctly represents a Microsoft New Executable + /// + public bool Recognized { get; private set; } + public string Type { get; } + + void Initialize() + { + Recognized = false; + + if(BaseStream == null) return; + + BaseExecutable = new MZ(BaseStream); + if(!BaseExecutable.Recognized) return; + + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); + Marshal.FreeHGlobal(hdrPtr); + if(Header.signature != Signature) return; + + Recognized = true; + if(Header.resource_entries <= 0) return; + + Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Header.resource_table_offset); + Versions = GetVersions().ToArray(); + } + + /// + /// Identifies if the specified executable is a Microsoft New Executable + /// + /// true if the specified executable is a Microsoft New Executable, false otherwise. + /// Executable path. + public static bool Identify(string path) { FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); MZ BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - NEHeader Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); - Marshal.FreeHGlobal(hdrPtr); - return Header.signature == Signature; - } + if(!BaseExecutable.Recognized) return false; - return false; + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + NEHeader Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); + Marshal.FreeHGlobal(hdrPtr); + return Header.signature == Signature; } - /// - /// Identifies if the specified executable is a Microsoft New Executable - /// - /// true if the specified executable is a Microsoft New Executable, false otherwise. - /// Stream containing the executable. - public static bool Identify(FileStream stream) + /// + /// Identifies if the specified executable is a Microsoft New Executable + /// + /// true if the specified executable is a Microsoft New Executable, false otherwise. + /// Stream containing the executable. + public static bool Identify(FileStream stream) { FileStream BaseStream = stream; MZ BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - NEHeader Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); - Marshal.FreeHGlobal(hdrPtr); - return Header.signature == Signature; - } + if(!BaseExecutable.Recognized) return false; - return false; + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + NEHeader Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); + Marshal.FreeHGlobal(hdrPtr); + return Header.signature == Signature; } } } \ No newline at end of file diff --git a/libexeinfo/PE/Consts.cs b/libexeinfo/PE/Consts.cs index 161e2ea..2709591 100644 --- a/libexeinfo/PE/Consts.cs +++ b/libexeinfo/PE/Consts.cs @@ -28,10 +28,10 @@ namespace libexeinfo { public partial class PE { - /// - /// Portable Executable signature, "PE\0\0" - /// - public const ushort Signature = 0x00004550; + /// + /// Portable Executable signature, "PE\0\0" + /// + public const ushort Signature = 0x00004550; public const ushort PE32 = COFF.ZMAGIC; public const ushort PE32Plus = 0x20b; } diff --git a/libexeinfo/PE/Enums.cs b/libexeinfo/PE/Enums.cs index 1627586..06caf02 100644 --- a/libexeinfo/PE/Enums.cs +++ b/libexeinfo/PE/Enums.cs @@ -32,26 +32,26 @@ namespace libexeinfo { public enum DebugTypes : uint { - /// - /// Unknown value, ignored by all tools. - /// - IMAGE_DEBUG_TYPE_UNKNOWN = 0, - /// - /// COFF debug information (line numbers, symbol table, and string table). - /// This type of debug information is also pointed to by fields in the file headers. - /// - IMAGE_DEBUG_TYPE_COFF = 1, - /// - /// CodeView debug information. The format of the data block is described - /// by the CV4 specification. - /// - IMAGE_DEBUG_TYPE_CODEVIEW = 2, - /// - /// Frame Pointer Omission (FPO) information. This information tells the - /// debugger how to interpret non-standard stack frames, which use the - /// EBP register for a purpose other than as a frame pointer. - /// - IMAGE_DEBUG_TYPE_FPO = 3, + /// + /// Unknown value, ignored by all tools. + /// + IMAGE_DEBUG_TYPE_UNKNOWN = 0, + /// + /// COFF debug information (line numbers, symbol table, and string table). + /// This type of debug information is also pointed to by fields in the file headers. + /// + IMAGE_DEBUG_TYPE_COFF = 1, + /// + /// CodeView debug information. The format of the data block is described + /// by the CV4 specification. + /// + IMAGE_DEBUG_TYPE_CODEVIEW = 2, + /// + /// Frame Pointer Omission (FPO) information. This information tells the + /// debugger how to interpret non-standard stack frames, which use the + /// EBP register for a purpose other than as a frame pointer. + /// + IMAGE_DEBUG_TYPE_FPO = 3, IMAGE_DEBUG_TYPE_MISC = 4, IMAGE_DEBUG_TYPE_EXCEPTION = 5, IMAGE_DEBUG_TYPE_FIXUP = 6, @@ -60,120 +60,120 @@ namespace libexeinfo IMAGE_DEBUG_TYPE_BORLAND = 9 } - /// - /// The following values are defined for the DllCharacteristics field of the optional header. - /// - [Flags] + /// + /// The following values are defined for the DllCharacteristics field of the optional header. + /// + [Flags] public enum DllCharacteristics : ushort { - /// - /// Image can handle a high entropy 64-bit virtual address space. - /// - IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, - /// - /// DLL can be relocated at load time. - /// - IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040, - /// - /// Code Integrity checks are enforced. - /// - IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080, - /// - /// Image is NX compatible. - /// - IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100, - /// - /// Isolation aware, but do not isolate the image. - /// - IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200, - /// - /// Does not use structured exception (SE) handling. No SE handler may be called in this image. - /// - IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400, - /// - /// Do not bind the image. - /// - IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800, - /// - /// Image must execute in an AppContainer. - /// - IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000, - /// - /// A WDM driver. - /// - IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000, - /// - /// Image supports Control Flow Guard. - /// - IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000, - /// - /// Terminal Server aware. - /// - IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 + /// + /// Image can handle a high entropy 64-bit virtual address space. + /// + IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, + /// + /// DLL can be relocated at load time. + /// + IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040, + /// + /// Code Integrity checks are enforced. + /// + IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080, + /// + /// Image is NX compatible. + /// + IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100, + /// + /// Isolation aware, but do not isolate the image. + /// + IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200, + /// + /// Does not use structured exception (SE) handling. No SE handler may be called in this image. + /// + IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400, + /// + /// Do not bind the image. + /// + IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800, + /// + /// Image must execute in an AppContainer. + /// + IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000, + /// + /// A WDM driver. + /// + IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000, + /// + /// Image supports Control Flow Guard. + /// + IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000, + /// + /// Terminal Server aware. + /// + IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 } - /// - /// The following values defined for the Subsystem field of the optional header determine which Windows subsystem (if - /// any) is required to run the image. - /// - public enum Subsystems : ushort + /// + /// The following values defined for the Subsystem field of the optional header determine which Windows subsystem (if + /// any) is required to run the image. + /// + public enum Subsystems : ushort { - /// - /// An unknown subsystem - /// - IMAGE_SUBSYSTEM_UNKNOWN = 0, - /// - /// Device drivers and native Windows processes - /// - IMAGE_SUBSYSTEM_NATIVE = 1, - /// - /// The Windows graphical user interface (GUI) subsystem - /// - IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, - /// - /// The Windows character subsystem - /// - IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, - /// - /// The OS/2 character subsystem - /// - IMAGE_SUBSYSTEM_OS2_CUI = 5, - /// - /// The Posix character subsystem - /// - IMAGE_SUBSYSTEM_POSIX_CUI = 7, - /// - /// Native Win9x driver - /// - IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, - /// - /// Windows CE - /// - IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, - /// - /// An Extensible Firmware Interface (EFI) application - /// - IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, - /// - /// An EFI driver with boot services - /// - IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, - /// - /// An EFI driver with run-time services - /// - IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, - /// - /// An EFI ROM image - /// - IMAGE_SUBSYSTEM_EFI_ROM = 13, - /// - /// XBOX - /// - IMAGE_SUBSYSTEM_XBOX = 14, - /// - /// Windows boot application - /// - IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 + /// + /// An unknown subsystem + /// + IMAGE_SUBSYSTEM_UNKNOWN = 0, + /// + /// Device drivers and native Windows processes + /// + IMAGE_SUBSYSTEM_NATIVE = 1, + /// + /// The Windows graphical user interface (GUI) subsystem + /// + IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, + /// + /// The Windows character subsystem + /// + IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, + /// + /// The OS/2 character subsystem + /// + IMAGE_SUBSYSTEM_OS2_CUI = 5, + /// + /// The Posix character subsystem + /// + IMAGE_SUBSYSTEM_POSIX_CUI = 7, + /// + /// Native Win9x driver + /// + IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, + /// + /// Windows CE + /// + IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, + /// + /// An Extensible Firmware Interface (EFI) application + /// + IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, + /// + /// An EFI driver with boot services + /// + IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, + /// + /// An EFI driver with run-time services + /// + IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, + /// + /// An EFI ROM image + /// + IMAGE_SUBSYSTEM_EFI_ROM = 13, + /// + /// XBOX + /// + IMAGE_SUBSYSTEM_XBOX = 14, + /// + /// Windows boot application + /// + IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 } } } \ No newline at end of file diff --git a/libexeinfo/PE/Info.cs b/libexeinfo/PE/Info.cs index cac1b90..5010826 100644 --- a/libexeinfo/PE/Info.cs +++ b/libexeinfo/PE/Info.cs @@ -30,6 +30,8 @@ namespace libexeinfo { public partial class PE { + public string Information => GetInfo(Header, WinHeader); + public static string GetInfo(PEHeader header, WindowsHeader64 winheader) { StringBuilder sb = new StringBuilder(); @@ -97,10 +99,5 @@ namespace libexeinfo return sb.ToString(); } - - public string GetInfo() - { - return GetInfo(Header, WinHeader); - } } } \ No newline at end of file diff --git a/libexeinfo/PE/PE.cs b/libexeinfo/PE/PE.cs index fa4e01a..5842efa 100644 --- a/libexeinfo/PE/PE.cs +++ b/libexeinfo/PE/PE.cs @@ -30,164 +30,148 @@ using System.Runtime.InteropServices; namespace libexeinfo { - /// - /// Represents a Microsoft Portable Executable - /// - public partial class PE + /// + /// Represents a Microsoft Portable Executable + /// + public partial class PE : IExecutable { - public readonly MZ BaseExecutable; - /// - /// The that contains the executable represented by this instance - /// - public readonly FileStream BaseStream; - /// - /// Header for this executable - /// - public readonly PEHeader Header; - /// - /// If true this instance correctly represents a Microsoft Portable Executable - /// - public readonly bool IsPE; - public readonly WindowsHeader64 WinHeader; + MZ BaseExecutable; + /// + /// Header for this executable + /// + PEHeader Header; + WindowsHeader64 WinHeader; - /// - /// Initializes a new instance of the class. - /// - /// Executable path. - public PE(string path) + /// + /// Initializes a new instance of the class. + /// + /// Executable path. + public PE(string path) { - IsPE = false; - BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); - BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); - Marshal.FreeHGlobal(hdrPtr); - IsPE = Header.signature == Signature; - - if(IsPE) - if(Header.coff.optionalHeader.magic == PE32Plus) - { - BaseStream.Position -= 4; - buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader64))]; - BaseStream.Read(buffer, 0, buffer.Length); - hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - WinHeader = (WindowsHeader64)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader64)); - Marshal.FreeHGlobal(hdrPtr); - } - else - { - buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - WindowsHeader hdr32 = (WindowsHeader)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader)); - Marshal.FreeHGlobal(hdrPtr); - WinHeader = ToPlus(hdr32); - } - } + BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); + Initialize(); } - /// - /// Initializes a new instance of the class. - /// - /// Stream containing the executable. - public PE(FileStream stream) + /// + /// Initializes a new instance of the class. + /// + /// Stream containing the executable. + public PE(Stream stream) { - IsPE = false; - BaseStream = stream; - BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); - Marshal.FreeHGlobal(hdrPtr); - IsPE = Header.signature == Signature; - - if(IsPE) - if(Header.coff.optionalHeader.magic == PE32Plus) - { - BaseStream.Position -= 4; - buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader64))]; - BaseStream.Read(buffer, 0, buffer.Length); - hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - WinHeader = (WindowsHeader64)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader64)); - Marshal.FreeHGlobal(hdrPtr); - } - else - { - buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - WindowsHeader hdr32 = (WindowsHeader)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader)); - Marshal.FreeHGlobal(hdrPtr); - WinHeader = ToPlus(hdr32); - } - } + BaseStream = stream; + Initialize(); } - /// - /// Identifies if the specified executable is a Microsoft Portable Executable - /// - /// true if the specified executable is a Microsoft Portable Executable, false otherwise. - /// Executable path. - public static bool Identify(string path) + /// + /// Initializes a new instance of the class. + /// + /// Byte array containing the executable. + public PE(byte[] data) + { + BaseStream = new MemoryStream(data); + Initialize(); + } + + /// + /// The that contains the executable represented by this instance + /// + public Stream BaseStream { get; } + public bool IsBigEndian => false; + /// + /// If true this instance correctly represents a Microsoft Portable Executable + /// + public bool Recognized { get; private set; } + public string Type { get; private set; } + + void Initialize() + { + Recognized = false; + if(BaseStream == null) return; + + BaseExecutable = new MZ(BaseStream); + if(!BaseExecutable.Recognized) return; + + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); + Marshal.FreeHGlobal(hdrPtr); + Recognized = Header.signature == Signature; + + if(!Recognized) return; + + Type = "Portable Executable (PE)"; + + if(Header.coff.optionalHeader.magic == PE32Plus) + { + BaseStream.Position -= 4; + buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader64))]; + BaseStream.Read(buffer, 0, buffer.Length); + hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + WinHeader = (WindowsHeader64)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader64)); + Marshal.FreeHGlobal(hdrPtr); + } + else + { + buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + WindowsHeader hdr32 = (WindowsHeader)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader)); + Marshal.FreeHGlobal(hdrPtr); + WinHeader = ToPlus(hdr32); + } + } + + /// + /// Identifies if the specified executable is a Microsoft Portable Executable + /// + /// true if the specified executable is a Microsoft Portable Executable, false otherwise. + /// Executable path. + public static bool Identify(string path) { FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); MZ BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); - Marshal.FreeHGlobal(hdrPtr); - return Header.signature == Signature; - } + if(!BaseExecutable.Recognized) return false; - return false; + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); + Marshal.FreeHGlobal(hdrPtr); + return Header.signature == Signature; } - /// - /// Identifies if the specified executable is a Microsoft Portable Executable - /// - /// true if the specified executable is a Microsoft Portable Executable, false otherwise. - /// Stream containing the executable. - public static bool Identify(FileStream stream) + /// + /// Identifies if the specified executable is a Microsoft Portable Executable + /// + /// true if the specified executable is a Microsoft Portable Executable, false otherwise. + /// Stream containing the executable. + public static bool Identify(FileStream stream) { FileStream BaseStream = stream; MZ BaseExecutable = new MZ(BaseStream); - if(BaseExecutable.IsMZ) - if(BaseExecutable.Header.new_offset < BaseStream.Length) - { - BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); - byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; - BaseStream.Read(buffer, 0, buffer.Length); - IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); - Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); - PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); - Marshal.FreeHGlobal(hdrPtr); - return Header.signature == Signature; - } + if(!BaseExecutable.Recognized) return false; - return false; + if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false; + + BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); + byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; + BaseStream.Read(buffer, 0, buffer.Length); + IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); + Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); + PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); + Marshal.FreeHGlobal(hdrPtr); + return Header.signature == Signature; } static WindowsHeader64 ToPlus(WindowsHeader header) diff --git a/libexeinfo/PE/Structs.cs b/libexeinfo/PE/Structs.cs index b5bc310..57dff0e 100644 --- a/libexeinfo/PE/Structs.cs +++ b/libexeinfo/PE/Structs.cs @@ -31,345 +31,345 @@ namespace libexeinfo { public partial class PE { - /// - /// Header for a Microsoft New Executable - /// - [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] + /// + /// Header for a Microsoft New Executable + /// + [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct PEHeader { - /// - /// After the MS-DOS stub, at the file offset specified at offset 0x3c, is a 4-byte signature that identifies the file - /// as a PE format image file. This signature is "PE\0\0" (the letters "P" and "E" followed by two null bytes). - /// - public uint signature; + /// + /// After the MS-DOS stub, at the file offset specified at offset 0x3c, is a 4-byte signature that identifies the file + /// as a PE format image file. This signature is "PE\0\0" (the letters "P" and "E" followed by two null bytes). + /// + public uint signature; public COFFHeader coff; } - /// - /// The next 21 fields are an extension to the COFF optional header format. They contain additional information that is - /// required by the linker and loader in Windows. - /// - [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] + /// + /// The next 21 fields are an extension to the COFF optional header format. They contain additional information that is + /// required by the linker and loader in Windows. + /// + [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct WindowsHeader { - /// - /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. The default - /// for DLLs is 0x10000000. The default for Windows CE EXEs is 0x00010000. The default for Windows NT, Windows 2000, - /// Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000. - /// - public uint imageBase; - /// - /// The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to - /// FileAlignment. The default is the page size for the architecture. - /// - public uint sectionAlignment; - /// - /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file. The value should - /// be a power of 2 between 512 and 64 K, inclusive. The default is 512. If the SectionAlignment is less than the - /// architecture's page size, then FileAlignment must match SectionAlignment. - /// - public uint fileAlignment; - /// - /// The major version number of the required operating system. - /// - public ushort majorOperatingSystemVersion; - /// - /// The minor version number of the required operating system. - /// - public ushort minorOperatingSystemVersion; - /// - /// The major version number of the image. - /// - public ushort majorImageVersion; - /// - /// The minor version number of the image. - /// - public ushort minorImageVersion; - /// - /// The major version number of the subsystem. - /// - public ushort majorSubsystemVersion; - /// - /// The minor version number of the subsystem. - /// - public ushort minorSubsystemVersion; - /// - /// Reserved, must be zero. - /// - public uint win32VersionValue; - /// - /// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of - /// SectionAlignment. - /// - public uint sizeOfImage; - /// - /// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. - /// - public uint sizeOfHeaders; - /// - /// The image file checksum. The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. The following - /// are checked for validation at load time: all drivers, any DLL loaded at boot time, and any DLL that is loaded into - /// a critical Windows process. - /// - public uint checksum; - /// - /// The subsystem that is required to run this image. For more information, . - /// - public Subsystems subsystem; - /// - /// For more information, . - /// - public DllCharacteristics dllCharacteristics; - /// - /// The size of the stack to reserve. Only SizeOfStackCommit is committed; the rest is made available one page at a - /// time until the reserve size is reached. - /// - public uint sizeOfStackReserve; - /// - /// The size of the stack to commit. - /// - public uint sizeOfStackCommit; - /// - /// The size of the local heap space to reserve. Only SizeOfHeapCommit is committed; the rest is made available one - /// page at a time until the reserve size is reached. - /// - public uint sizeOfHeapReserve; - /// - /// The size of the local heap space to commit. - /// - public uint sizeOfHeapCommit; - /// - /// Reserved, must be zero. - /// - public uint loaderFlags; - /// - /// The number of data-directory entries in the remainder of the optional header. Each describes a location and size. - /// - public uint numberOfRvaAndSizes; + /// + /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. The default + /// for DLLs is 0x10000000. The default for Windows CE EXEs is 0x00010000. The default for Windows NT, Windows 2000, + /// Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000. + /// + public uint imageBase; + /// + /// The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to + /// FileAlignment. The default is the page size for the architecture. + /// + public uint sectionAlignment; + /// + /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file. The value should + /// be a power of 2 between 512 and 64 K, inclusive. The default is 512. If the SectionAlignment is less than the + /// architecture's page size, then FileAlignment must match SectionAlignment. + /// + public uint fileAlignment; + /// + /// The major version number of the required operating system. + /// + public ushort majorOperatingSystemVersion; + /// + /// The minor version number of the required operating system. + /// + public ushort minorOperatingSystemVersion; + /// + /// The major version number of the image. + /// + public ushort majorImageVersion; + /// + /// The minor version number of the image. + /// + public ushort minorImageVersion; + /// + /// The major version number of the subsystem. + /// + public ushort majorSubsystemVersion; + /// + /// The minor version number of the subsystem. + /// + public ushort minorSubsystemVersion; + /// + /// Reserved, must be zero. + /// + public uint win32VersionValue; + /// + /// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of + /// SectionAlignment. + /// + public uint sizeOfImage; + /// + /// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. + /// + public uint sizeOfHeaders; + /// + /// The image file checksum. The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. The following + /// are checked for validation at load time: all drivers, any DLL loaded at boot time, and any DLL that is loaded into + /// a critical Windows process. + /// + public uint checksum; + /// + /// The subsystem that is required to run this image. For more information, . + /// + public Subsystems subsystem; + /// + /// For more information, . + /// + public DllCharacteristics dllCharacteristics; + /// + /// The size of the stack to reserve. Only SizeOfStackCommit is committed; the rest is made available one page at a + /// time until the reserve size is reached. + /// + public uint sizeOfStackReserve; + /// + /// The size of the stack to commit. + /// + public uint sizeOfStackCommit; + /// + /// The size of the local heap space to reserve. Only SizeOfHeapCommit is committed; the rest is made available one + /// page at a time until the reserve size is reached. + /// + public uint sizeOfHeapReserve; + /// + /// The size of the local heap space to commit. + /// + public uint sizeOfHeapCommit; + /// + /// Reserved, must be zero. + /// + public uint loaderFlags; + /// + /// The number of data-directory entries in the remainder of the optional header. Each describes a location and size. + /// + public uint numberOfRvaAndSizes; } - /// - /// The next 21 fields are an extension to the COFF optional header format. They contain additional information that is - /// required by the linker and loader in Windows. - /// - [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] + /// + /// The next 21 fields are an extension to the COFF optional header format. They contain additional information that is + /// required by the linker and loader in Windows. + /// + [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct WindowsHeader64 { - /// - /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. The default - /// for DLLs is 0x10000000. The default for Windows CE EXEs is 0x00010000. The default for Windows NT, Windows 2000, - /// Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000. - /// - public ulong imageBase; - /// - /// The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to - /// FileAlignment. The default is the page size for the architecture. - /// - public uint sectionAlignment; - /// - /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file. The value should - /// be a power of 2 between 512 and 64 K, inclusive. The default is 512. If the SectionAlignment is less than the - /// architecture's page size, then FileAlignment must match SectionAlignment. - /// - public uint fileAlignment; - /// - /// The major version number of the required operating system. - /// - public ushort majorOperatingSystemVersion; - /// - /// The minor version number of the required operating system. - /// - public ushort minorOperatingSystemVersion; - /// - /// The major version number of the image. - /// - public ushort majorImageVersion; - /// - /// The minor version number of the image. - /// - public ushort minorImageVersion; - /// - /// The major version number of the subsystem. - /// - public ushort majorSubsystemVersion; - /// - /// The minor version number of the subsystem. - /// - public ushort minorSubsystemVersion; - /// - /// Reserved, must be zero. - /// - public uint win32VersionValue; - /// - /// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of - /// SectionAlignment. - /// - public uint sizeOfImage; - /// - /// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. - /// - public uint sizeOfHeaders; - /// - /// The image file checksum. The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. The following - /// are checked for validation at load time: all drivers, any DLL loaded at boot time, and any DLL that is loaded into - /// a critical Windows process. - /// - public uint checksum; - /// - /// The subsystem that is required to run this image. For more information, . - /// - public Subsystems subsystem; - /// - /// For more information, . - /// - public DllCharacteristics dllCharacteristics; - /// - /// The size of the stack to reserve. Only SizeOfStackCommit is committed; the rest is made available one page at a - /// time until the reserve size is reached. - /// - public ulong sizeOfStackReserve; - /// - /// The size of the stack to commit. - /// - public ulong sizeOfStackCommit; - /// - /// The size of the local heap space to reserve. Only SizeOfHeapCommit is committed; the rest is made available one - /// page at a time until the reserve size is reached. - /// - public ulong sizeOfHeapReserve; - /// - /// The size of the local heap space to commit. - /// - public ulong sizeOfHeapCommit; - /// - /// Reserved, must be zero. - /// - public uint loaderFlags; - /// - /// The number of data-directory entries in the remainder of the optional header. Each describes a location and size. - /// - public uint numberOfRvaAndSizes; + /// + /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. The default + /// for DLLs is 0x10000000. The default for Windows CE EXEs is 0x00010000. The default for Windows NT, Windows 2000, + /// Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000. + /// + public ulong imageBase; + /// + /// The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to + /// FileAlignment. The default is the page size for the architecture. + /// + public uint sectionAlignment; + /// + /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file. The value should + /// be a power of 2 between 512 and 64 K, inclusive. The default is 512. If the SectionAlignment is less than the + /// architecture's page size, then FileAlignment must match SectionAlignment. + /// + public uint fileAlignment; + /// + /// The major version number of the required operating system. + /// + public ushort majorOperatingSystemVersion; + /// + /// The minor version number of the required operating system. + /// + public ushort minorOperatingSystemVersion; + /// + /// The major version number of the image. + /// + public ushort majorImageVersion; + /// + /// The minor version number of the image. + /// + public ushort minorImageVersion; + /// + /// The major version number of the subsystem. + /// + public ushort majorSubsystemVersion; + /// + /// The minor version number of the subsystem. + /// + public ushort minorSubsystemVersion; + /// + /// Reserved, must be zero. + /// + public uint win32VersionValue; + /// + /// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of + /// SectionAlignment. + /// + public uint sizeOfImage; + /// + /// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. + /// + public uint sizeOfHeaders; + /// + /// The image file checksum. The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. The following + /// are checked for validation at load time: all drivers, any DLL loaded at boot time, and any DLL that is loaded into + /// a critical Windows process. + /// + public uint checksum; + /// + /// The subsystem that is required to run this image. For more information, . + /// + public Subsystems subsystem; + /// + /// For more information, . + /// + public DllCharacteristics dllCharacteristics; + /// + /// The size of the stack to reserve. Only SizeOfStackCommit is committed; the rest is made available one page at a + /// time until the reserve size is reached. + /// + public ulong sizeOfStackReserve; + /// + /// The size of the stack to commit. + /// + public ulong sizeOfStackCommit; + /// + /// The size of the local heap space to reserve. Only SizeOfHeapCommit is committed; the rest is made available one + /// page at a time until the reserve size is reached. + /// + public ulong sizeOfHeapReserve; + /// + /// The size of the local heap space to commit. + /// + public ulong sizeOfHeapCommit; + /// + /// Reserved, must be zero. + /// + public uint loaderFlags; + /// + /// The number of data-directory entries in the remainder of the optional header. Each describes a location and size. + /// + public uint numberOfRvaAndSizes; } [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct ImageDataDirectory { - /// - /// Relative virtual address of the table - /// - uint rva; - /// - /// The size in bytes - /// - uint size; + /// + /// Relative virtual address of the table + /// + uint rva; + /// + /// The size in bytes + /// + uint size; } [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct DebugDirectory { - /// - /// A reserved field intended to be used for flags, set to zero for now. - /// - public uint characteristics; - /// - /// Time and date the debug data was created. - /// - public uint timeDateStamp; - /// - /// Major version number of the debug data format. - /// - public ushort majorVersion; - /// - /// Minor version number of the debug data format. - /// - public ushort minorVersion; - /// - /// Format of debugging information: this field enables support of multiple debuggers. for - /// more information. - /// - public DebugTypes type; - /// - /// Size of the debug data (not including the debug directory itself). - /// - public uint sizeOfData; - /// - /// Address of the debug data when loaded, relative to the image base. - /// - public uint addressOfRawData; - /// - /// File pointer to the debug data. - /// - public uint pointerToRawData; + /// + /// A reserved field intended to be used for flags, set to zero for now. + /// + public uint characteristics; + /// + /// Time and date the debug data was created. + /// + public uint timeDateStamp; + /// + /// Major version number of the debug data format. + /// + public ushort majorVersion; + /// + /// Minor version number of the debug data format. + /// + public ushort minorVersion; + /// + /// Format of debugging information: this field enables support of multiple debuggers. for + /// more information. + /// + public DebugTypes type; + /// + /// Size of the debug data (not including the debug directory itself). + /// + public uint sizeOfData; + /// + /// Address of the debug data when loaded, relative to the image base. + /// + public uint addressOfRawData; + /// + /// File pointer to the debug data. + /// + public uint pointerToRawData; } [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct ResourceDirectoryTable { - /// - /// Resource flags, reserved for future use; currently set to zero. - /// - public uint characteristics; - /// - /// Time the resource data was created by the resource compiler. - /// - public uint timeDateStamp; - /// - /// Major version number, set by the user. - /// - public ushort majorVersion; - /// - /// Minor version number. - /// - public ushort minorVersion; - /// - /// Number of directory entries, immediately following the table, - /// that use strings to identify Type, Name, or Language - /// (depending on the level of the table). - /// - public ushort nameEntries; - /// - /// Number of directory entries, immediately following the Name - /// entries, that use numeric identifiers for Type, Name, or Language. - /// - public ushort idEntries; + /// + /// Resource flags, reserved for future use; currently set to zero. + /// + public uint characteristics; + /// + /// Time the resource data was created by the resource compiler. + /// + public uint timeDateStamp; + /// + /// Major version number, set by the user. + /// + public ushort majorVersion; + /// + /// Minor version number. + /// + public ushort minorVersion; + /// + /// Number of directory entries, immediately following the table, + /// that use strings to identify Type, Name, or Language + /// (depending on the level of the table). + /// + public ushort nameEntries; + /// + /// Number of directory entries, immediately following the Name + /// entries, that use numeric identifiers for Type, Name, or Language. + /// + public ushort idEntries; } [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct ResourceDirectoryEntries { - /// - /// Address of string that gives the Type, Name, or Language identifier, depending on level of table. - /// or - /// 32-bit integer that identifies Type, Name, or Language. - /// - public uint nameOrID; - /// - /// High bit 0: Address of a Resource Data Entry(a leaf). - /// High bit 1: Lower 31 bits are the address of another Resource Directory Table(the next level down). - /// - public uint rva; + /// + /// Address of string that gives the Type, Name, or Language identifier, depending on level of table. + /// or + /// 32-bit integer that identifies Type, Name, or Language. + /// + public uint nameOrID; + /// + /// High bit 0: Address of a Resource Data Entry(a leaf). + /// High bit 1: Lower 31 bits are the address of another Resource Directory Table(the next level down). + /// + public uint rva; } [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)] public struct ResourceDataEntry { - /// - /// Address of a unit of resource data in the Resource Data area. - /// - public uint rva; - /// - /// Size, in bytes, of the resource data pointed to by the Data RVA field. - /// - public uint size; - /// - /// Code page used to decode code point values within the resource data.Typically, the code page would be the Unicode - /// code page. - /// - public uint codepage; - /// - /// Reserved (must be set to 0) - /// - public uint reserved; + /// + /// Address of a unit of resource data in the Resource Data area. + /// + public uint rva; + /// + /// Size, in bytes, of the resource data pointed to by the Data RVA field. + /// + public uint size; + /// + /// Code page used to decode code point values within the resource data.Typically, the code page would be the Unicode + /// code page. + /// + public uint codepage; + /// + /// Reserved (must be set to 0) + /// + public uint reserved; } } } \ No newline at end of file diff --git a/libexeinfo/libexeinfo.csproj b/libexeinfo/libexeinfo.csproj index e95a53c..c839a84 100644 --- a/libexeinfo/libexeinfo.csproj +++ b/libexeinfo/libexeinfo.csproj @@ -1,4 +1,4 @@ - + @@ -43,6 +43,7 @@ +