Convert classes to interface.

This commit is contained in:
2018-02-25 18:42:56 +00:00
parent a58d4a636b
commit 7bfb6744f2
26 changed files with 1613 additions and 1586 deletions

View File

@@ -33,7 +33,7 @@ using libexeinfo;
namespace exeinfo namespace exeinfo
{ {
class MainClass static class MainClass
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
@@ -48,25 +48,25 @@ namespace exeinfo
bool recognized = false; bool recognized = false;
MZ mzExe = new MZ(exeFs); IExecutable mzExe = new MZ(exeFs);
NE neExe = new NE(exeFs); IExecutable neExe = new NE(exeFs);
AtariST stExe = new AtariST(exeFs); IExecutable stExe = new AtariST(exeFs);
LX lxExe = new LX(exeFs); IExecutable lxExe = new LX(exeFs);
COFF coffExe = new COFF(exeFs); IExecutable coffExe = new COFF(exeFs);
PE peExe = new PE(exeFs); IExecutable peExe = new PE(exeFs);
if(mzExe.IsMZ) if(mzExe.Recognized)
{ {
recognized = true; recognized = true;
Console.Write(mzExe.GetInfo()); Console.Write(mzExe.Information);
} }
if(neExe.IsNE) if(neExe.Recognized)
{ {
recognized = true; recognized = true;
Console.Write(neExe.GetInfo()); Console.Write(neExe.Information);
if(neExe.Versions != null) if(((NE)neExe).Versions != null)
foreach(NE.Version vers in neExe.Versions) foreach(NE.Version vers in ((NE)neExe).Versions)
{ {
Console.WriteLine("\tVersion resource {0}:", vers.Name); Console.WriteLine("\tVersion resource {0}:", vers.Name);
Console.WriteLine("\t\tFile version: {0}", vers.FileVersion); Console.WriteLine("\t\tFile version: {0}", vers.FileVersion);
@@ -117,28 +117,28 @@ namespace exeinfo
} }
} }
if(stExe.IsAtariST) if(stExe.Recognized)
{ {
recognized = true; recognized = true;
Console.Write(stExe.GetInfo()); Console.Write(stExe.Information);
} }
if(lxExe.IsLX) if(lxExe.Recognized)
{ {
recognized = true; recognized = true;
Console.Write(lxExe.GetInfo()); Console.Write(lxExe.Information);
} }
if(coffExe.IsCOFF) if(coffExe.Recognized)
{ {
recognized = true; recognized = true;
Console.Write(coffExe.GetInfo()); Console.Write(coffExe.Information);
} }
if(peExe.IsPE) if(peExe.Recognized)
{ {
recognized = true; recognized = true;
Console.Write(peExe.GetInfo()); Console.Write(peExe.Information);
} }
if(!recognized) Console.WriteLine("Executable format not recognized"); if(!recognized) Console.WriteLine("Executable format not recognized");

View File

@@ -57,44 +57,44 @@ namespace exeinfogui
FileStream exeFs = File.Open(dlgOpen.FileName, FileMode.Open, FileAccess.Read); FileStream exeFs = File.Open(dlgOpen.FileName, FileMode.Open, FileAccess.Read);
MZ mzExe = new MZ(exeFs); IExecutable mzExe = new MZ(exeFs);
NE neExe = new NE(exeFs); IExecutable neExe = new NE(exeFs);
AtariST stExe = new AtariST(exeFs); IExecutable stExe = new AtariST(exeFs);
LX lxExe = new LX(exeFs); IExecutable lxExe = new LX(exeFs);
COFF coffExe = new COFF(exeFs); IExecutable coffExe = new COFF(exeFs);
PE peExe = new PE(exeFs); IExecutable peExe = new PE(exeFs);
if(mzExe.IsMZ) if(mzExe.Recognized)
{ {
if(neExe.IsNE) if(neExe.Recognized)
{ {
txtType.Text = "New Executable (NE)"; txtType.Text = neExe.Type;
txtInformation.Text = neExe.GetInfo(); txtInformation.Text = neExe.Information;
} }
else if(lxExe.IsLX) else if(lxExe.Recognized)
{ {
txtType.Text = "Linear eXecutable (LX)"; txtType.Text = lxExe.Type;
txtInformation.Text = lxExe.GetInfo(); txtInformation.Text = lxExe.Information;
} }
else if(peExe.IsPE) else if(peExe.Recognized)
{ {
txtType.Text = "Portable Executable (PE)"; txtType.Text = peExe.Type;
txtInformation.Text = peExe.GetInfo(); txtInformation.Text = peExe.Information;
} }
else 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"; txtType.Text = stExe.Type;
txtInformation.Text = stExe.GetInfo(); txtInformation.Text = stExe.Information;
} }
else if(coffExe.IsCOFF) else if(coffExe.Recognized)
{ {
txtType.Text = "Common Object File Format (COFF)"; txtType.Text = coffExe.Type;
txtInformation.Text = coffExe.GetInfo(); txtInformation.Text = coffExe.Information;
} }
else else
txtType.Text = "Format not recognized"; txtType.Text = "Format not recognized";

View File

@@ -32,49 +32,60 @@ namespace libexeinfo
/// <summary> /// <summary>
/// Represents an Atari ST executable /// Represents an Atari ST executable
/// </summary> /// </summary>
public partial class AtariST public partial class AtariST : IExecutable
{ {
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public readonly FileStream BaseStream;
/// <summary>
/// Header for this executable
/// </summary>
public readonly AtariHeader Header;
/// <summary>
/// If true this instance correctly represents an Atari ST executable
/// </summary>
public readonly bool IsAtariST;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class.
/// </summary> /// </summary>
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public AtariST(string path) public AtariST(string path)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))];
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseStream.Position = 0; Initialize();
BaseStream.Read(buffer, 0, buffer.Length);
Header = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariHeader>(buffer);
IsAtariST = Header.signature == SIGNATURE;
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class.
/// </summary> /// </summary>
/// <param name="stream">Stream containing the executable.</param> /// <param name="stream">Stream containing the executable.</param>
public AtariST(FileStream stream) public AtariST(Stream stream)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))];
BaseStream = stream; BaseStream = stream;
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class.
/// </summary>
/// <param name="data">Byte array containing the executable.</param>
public AtariST(byte[] data)
{
BaseStream = new MemoryStream(data);
Initialize();
}
/// <summary>
/// Header for this executable
/// </summary>
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.Position = 0;
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
Header = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariHeader>(buffer); Header = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariHeader>(buffer);
IsAtariST = Header.signature == SIGNATURE; Recognized = Header.signature == SIGNATURE;
if(Recognized) Type = "Atari ST executable";
} }
/// <summary> /// <summary>
@@ -93,7 +104,7 @@ namespace libexeinfo
/// </summary> /// </summary>
/// <returns><c>true</c> if the specified executable is a Atari ST executable, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Atari ST executable, <c>false</c> otherwise.</returns>
/// <param name="stream">Stream containing the executable.</param> /// <param name="stream">Stream containing the executable.</param>
public static bool Identify(FileStream stream) public static bool Identify(Stream stream)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))];

View File

@@ -30,12 +30,18 @@ namespace libexeinfo
{ {
public partial class AtariST public partial class AtariST
{ {
/// <summary>
/// Gets a string with human readable information for the Atari ST executable represented by this instance
/// </summary>
/// <value>Human readable information for this instance.</value>
public string Information => GetInfo(Header);
/// <summary> /// <summary>
/// Gets a string with human readable information for a given Atari ST header /// Gets a string with human readable information for a given Atari ST header
/// </summary> /// </summary>
/// <returns>Human readable information for given Atari ST header.</returns> /// <returns>Human readable information for given Atari ST header.</returns>
/// <param name="header">Atari ST executable header.</param> /// <param name="header">Atari ST executable header.</param>
public static string GetInfo(AtariHeader header) static string GetInfo(AtariHeader header)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.AppendLine("Atari ST executable:"); sb.AppendLine("Atari ST executable:");
@@ -45,14 +51,5 @@ namespace libexeinfo
sb.AppendFormat("\t{0} bytes in symbol table", header.symb_len).AppendLine(); sb.AppendFormat("\t{0} bytes in symbol table", header.symb_len).AppendLine();
return sb.ToString(); return sb.ToString();
} }
/// <summary>
/// Gets a string with human readable information for the Atari ST executable represented by this instance
/// </summary>
/// <returns>Human readable information for this instance.</returns>
public string GetInfo()
{
return GetInfo(Header);
}
} }
} }

View File

@@ -33,80 +33,83 @@ namespace libexeinfo
/// <summary> /// <summary>
/// Represents a Common Object File Format /// Represents a Common Object File Format
/// </summary> /// </summary>
public partial class COFF public partial class COFF : IExecutable
{ {
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public readonly FileStream BaseStream;
/// <summary>
/// Header for this executable
/// </summary>
public readonly COFFHeader Header;
public readonly bool IsBigEndian;
/// <summary>
/// If true this instance correctly represents a Common Object File Format
/// </summary>
public readonly bool IsCOFF;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class.
/// </summary> /// </summary>
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public COFF(string path) public COFF(string path)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))];
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseStream.Position = 0; Initialize();
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 ||
Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
IsBigEndian = !IsCOFF;
}
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class.
/// </summary> /// </summary>
/// <param name="stream">Stream containing the executable.</param> /// <param name="stream">Stream containing the executable.</param>
public COFF(FileStream stream) public COFF(Stream stream)
{ {
BaseStream = stream;
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class.
/// </summary>
/// <param name="data">Byte array containing the executable.</param>
public COFF(byte[] data)
{
BaseStream = new MemoryStream(data);
Initialize();
}
/// <summary>
/// Header for this executable
/// </summary>
public COFFHeader Header { get; private set; }
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public Stream BaseStream { get; }
public bool IsBigEndian { get; private set; }
/// <summary>
/// If true this instance correctly represents a Common Object File Format
/// </summary>
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))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))];
BaseStream = stream;
BaseStream.Position = 0; BaseStream.Position = 0;
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Header = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader)); Header = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
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 == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
IsBigEndian = false; IsBigEndian = false;
if(!IsCOFF) if(!Recognized)
{ {
Header = SwapHeader(Header); 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 == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
IsBigEndian = !IsCOFF; IsBigEndian = !Recognized;
} }
if(!Recognized) return;
Type = "Common Object File Format (COFF)";
} }
/// <summary> /// <summary>
@@ -133,17 +136,17 @@ namespace libexeinfo
stream.Read(buffer, 0, buffer.Length); stream.Read(buffer, 0, buffer.Length);
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, 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); Marshal.FreeHGlobal(hdrPtr);
if(COFFHdr.optionalHeader.magic == STMAGIC || COFFHdr.optionalHeader.magic == OMAGIC || if(coffHdr.optionalHeader.magic == STMAGIC || coffHdr.optionalHeader.magic == OMAGIC ||
COFFHdr.optionalHeader.magic == JMAGIC || COFFHdr.optionalHeader.magic == DMAGIC || coffHdr.optionalHeader.magic == JMAGIC || coffHdr.optionalHeader.magic == DMAGIC ||
COFFHdr.optionalHeader.magic == ZMAGIC || COFFHdr.optionalHeader.magic == SHMAGIC) return true; coffHdr.optionalHeader.magic == ZMAGIC || coffHdr.optionalHeader.magic == SHMAGIC) return true;
COFFHdr = SwapHeader(COFFHdr); coffHdr = SwapHeader(coffHdr);
return COFFHdr.optionalHeader.magic == STMAGIC || COFFHdr.optionalHeader.magic == OMAGIC || return coffHdr.optionalHeader.magic == STMAGIC || coffHdr.optionalHeader.magic == OMAGIC ||
COFFHdr.optionalHeader.magic == JMAGIC || COFFHdr.optionalHeader.magic == DMAGIC || coffHdr.optionalHeader.magic == JMAGIC || coffHdr.optionalHeader.magic == DMAGIC ||
COFFHdr.optionalHeader.magic == ZMAGIC || COFFHdr.optionalHeader.magic == SHMAGIC; coffHdr.optionalHeader.magic == ZMAGIC || coffHdr.optionalHeader.magic == SHMAGIC;
} }
static COFFHeader SwapHeader(COFFHeader header) static COFFHeader SwapHeader(COFFHeader header)

View File

@@ -28,24 +28,24 @@ namespace libexeinfo
{ {
public partial class COFF public partial class COFF
{ {
public const ushort STMAGIC = 0x101; const ushort STMAGIC = 0x101;
public const ushort OMAGIC = 0x104; const ushort OMAGIC = 0x104;
/// <summary> /// <summary>
/// dirty text and data image, can't share /// dirty text and data image, can't share
/// </summary> /// </summary>
public const ushort JMAGIC = 0x107; const ushort JMAGIC = 0x107;
/// <summary> /// <summary>
/// dirty text segment, data aligned /// dirty text segment, data aligned
/// </summary> /// </summary>
public const ushort DMAGIC = 0x108; const ushort DMAGIC = 0x108;
/// <summary> /// <summary>
/// The proper magic number for executables /// The proper magic number for executables
/// </summary> /// </summary>
public const ushort ZMAGIC = 0x10b; internal const ushort ZMAGIC = 0x10b;
/// <summary> /// <summary>
/// shared library header /// shared library header
/// </summary> /// </summary>
public const ushort SHMAGIC = 0x123; const ushort SHMAGIC = 0x123;
/// <summary> /// <summary>
/// Alpha architecture information /// Alpha architecture information

View File

@@ -26,6 +26,8 @@
using System; using System;
// ReSharper disable InconsistentNaming
namespace libexeinfo namespace libexeinfo
{ {
public partial class COFF public partial class COFF

View File

@@ -31,7 +31,9 @@ namespace libexeinfo
{ {
public partial class COFF 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); DateTime epoch = new DateTime(1970, 1, 1);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -63,9 +65,9 @@ namespace libexeinfo
if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_RELOCS_STRIPPED)) if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_RELOCS_STRIPPED))
sb.AppendLine("\tExecutable contains no relocations."); sb.AppendLine("\tExecutable contains no relocations.");
if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_EXECUTABLE_IMAGE)) sb.AppendLine(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_EXECUTABLE_IMAGE)
sb.AppendLine("\tExecutable is valid."); ? "\tExecutable is valid."
else sb.AppendLine("\tExecutable is invalid, contains errors or has not been linked correctly."); : "\tExecutable is invalid, contains errors or has not been linked correctly.");
if(!header.characteristics.HasFlag(Characteristics.IMAGE_FILE_LINE_NUMS_STRIPPED)) if(!header.characteristics.HasFlag(Characteristics.IMAGE_FILE_LINE_NUMS_STRIPPED))
sb.AppendLine("\tExecutable contains line numbers."); sb.AppendLine("\tExecutable contains line numbers.");
if(!header.characteristics.HasFlag(Characteristics.IMAGE_FILE_LOCAL_SYMS_STRIPPED)) 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(); sb.AppendFormat("\tData starts at {0}", header.optionalHeader.baseOfData).AppendLine();
return sb.ToString(); return sb.ToString();
} }
public string GetInfo()
{
return GetInfo(Header);
}
} }
} }

View File

@@ -28,7 +28,7 @@ namespace libexeinfo
{ {
public partial class COFF public partial class COFF
{ {
public static string MachineTypeToString(MachineTypes machine) static string MachineTypeToString(MachineTypes machine)
{ {
switch(machine) switch(machine)
{ {
@@ -69,7 +69,7 @@ namespace libexeinfo
case MachineTypes.IMAGE_FILE_MACHINE_CLIPPER: return "Clipper"; case MachineTypes.IMAGE_FILE_MACHINE_CLIPPER: return "Clipper";
case MachineTypes.IMAGE_FILE_MACHINE_WE32000: return "WE32000 series"; case MachineTypes.IMAGE_FILE_MACHINE_WE32000: return "WE32000 series";
default: default:
return string.Format("Unknown machine type with code {0}", (ushort)machine); return $"Unknown machine type with code {(ushort)machine}";
} }
} }
} }

28
libexeinfo/IExecutable.cs Normal file
View File

@@ -0,0 +1,28 @@
using System.IO;
namespace libexeinfo
{
public interface IExecutable
{
/// <summary>
/// If <c>true</c> the executable is recognized by this instance
/// </summary>
bool Recognized { get; }
/// <summary>
/// Name of executable format
/// </summary>
string Type { get; }
/// <summary>
/// The <see cref="Stream" /> that contains the executable represented by this instance
/// </summary>
Stream BaseStream { get; }
/// <summary>
/// If <c>true</c> the executable is for a big-endian architecture
/// </summary>
bool IsBigEndian { get; }
/// <summary>
/// General description of executable contents
/// </summary>
string Information { get; }
}
}

View File

@@ -30,6 +30,8 @@ namespace libexeinfo
{ {
public partial class LX public partial class LX
{ {
public string Information => GetInfo(Header);
public static string GetInfo(LXHeader header) public static string GetInfo(LXHeader header)
{ {
StringBuilder sb = new StringBuilder(); 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(); sb.AppendFormat("\tHeap size added to the auto ds object: {0}", header.heap_size).AppendLine();
return sb.ToString(); return sb.ToString();
} }
public string GetInfo()
{
return GetInfo(Header);
}
} }
} }

View File

@@ -34,21 +34,23 @@ namespace libexeinfo
/// Represents a Microsoft/IBM Linear EXecutable /// Represents a Microsoft/IBM Linear EXecutable
/// </summary> /// </summary>
// TODO: Big-endian (really needed?) // TODO: Big-endian (really needed?)
public partial class LX public partial class LX : IExecutable
{ {
public readonly MZ BaseExecutable; MZ BaseExecutable;
/// <summary> /// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance /// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary> /// </summary>
public readonly FileStream BaseStream; public Stream BaseStream { get; }
public bool IsBigEndian => false;
/// <summary> /// <summary>
/// Header for this executable /// Header for this executable
/// </summary> /// </summary>
public readonly LXHeader Header; LXHeader Header;
/// <summary> /// <summary>
/// If true this instance correctly represents a Microsoft/IBM Linear EXecutable /// If true this instance correctly represents a Microsoft/IBM Linear EXecutable
/// </summary> /// </summary>
public readonly bool IsLX; public bool Recognized { get; private set;}
public string Type { get; private set;}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class.
@@ -56,35 +58,39 @@ namespace libexeinfo
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public LX(string path) public LX(string path)
{ {
IsLX = false;
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseExecutable = new MZ(BaseStream); Initialize();
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;
}
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class.
/// </summary> /// </summary>
/// <param name="stream">Stream containing the executable.</param> /// <param name="stream">Stream containing the executable.</param>
public LX(FileStream stream) public LX(Stream stream)
{ {
IsLX = false;
BaseStream = stream; BaseStream = stream;
BaseExecutable = new MZ(BaseStream); Initialize();
if(BaseExecutable.IsMZ) }
if(BaseExecutable.Header.new_offset < BaseStream.Length)
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class.
/// </summary>
/// <param name="data">Byte array containing the executable.</param>
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); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -92,8 +98,11 @@ namespace libexeinfo
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
IsLX = Header.signature == Signature || Header.signature == Signature16; Recognized = Header.signature == Signature || Header.signature == Signature16;
}
if(!Recognized) return;
Type = Header.signature == Signature16 ? "Linear Executable (LE)" : "Linear eXecutable (LX)";
} }
/// <summary> /// <summary>
@@ -105,9 +114,10 @@ namespace libexeinfo
{ {
FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(!BaseExecutable.Recognized) return false;
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false;
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -116,9 +126,7 @@ namespace libexeinfo
LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
return Header.signature == Signature || Header.signature == Signature16; return Header.signature == Signature || Header.signature == Signature16;
}
return false;
} }
/// <summary> /// <summary>
@@ -130,9 +138,10 @@ namespace libexeinfo
{ {
FileStream BaseStream = stream; FileStream BaseStream = stream;
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(!BaseExecutable.Recognized) return false;
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false;
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -141,9 +150,7 @@ namespace libexeinfo
LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader)); LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
return Header.signature == Signature || Header.signature == Signature16; return Header.signature == Signature || Header.signature == Signature16;
}
return false;
} }
} }
} }

View File

@@ -30,6 +30,12 @@ namespace libexeinfo
{ {
public partial class MZ public partial class MZ
{ {
/// <summary>
/// Gets a string with human readable information for the MZ executable represented by this instance
/// </summary>
/// <value>Human readable information for this instance.</value>
public string Information => GetInfo(Header);
/// <summary> /// <summary>
/// Gets a string with human readable information for a given MZ header /// Gets a string with human readable information for a given MZ header
/// </summary> /// </summary>
@@ -60,14 +66,5 @@ namespace libexeinfo
sb.AppendFormat("\tOffset to new header: {0}", header.new_offset).AppendLine(); sb.AppendFormat("\tOffset to new header: {0}", header.new_offset).AppendLine();
return sb.ToString(); return sb.ToString();
} }
/// <summary>
/// Gets a string with human readable information for the MZ executable represented by this instance
/// </summary>
/// <returns>Human readable information for this instance.</returns>
public string GetInfo()
{
return GetInfo(Header);
}
} }
} }

View File

@@ -33,20 +33,12 @@ namespace libexeinfo
/// <summary> /// <summary>
/// Represents a DOS relocatable executable /// Represents a DOS relocatable executable
/// </summary> /// </summary>
public partial class MZ public partial class MZ : IExecutable
{ {
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public readonly FileStream BaseStream;
/// <summary> /// <summary>
/// Header for this executable /// Header for this executable
/// </summary> /// </summary>
public readonly MZHeader Header; internal MZHeader Header;
/// <summary>
/// If true this instance correctly represents a DOS relocatable executable
/// </summary>
public readonly bool IsMZ;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.MZ" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.MZ" /> class.
@@ -54,34 +46,59 @@ namespace libexeinfo
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public MZ(string path) public MZ(string path)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))];
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseStream.Position = 0; Initialize();
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;
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.MZ" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.MZ" /> class.
/// </summary> /// </summary>
/// <param name="stream">Stream containing the executable.</param> /// <param name="stream">Stream containing the executable.</param>
public MZ(FileStream stream) public MZ(Stream stream)
{ {
BaseStream = stream;
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.MZ" /> class.
/// </summary>
/// <param name="data">Byte array containing the executable.</param>
public MZ(byte[] data)
{
BaseStream = new MemoryStream(data);
Initialize();
}
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public Stream BaseStream { get; }
public bool IsBigEndian => false;
/// <summary>
/// If true this instance correctly represents a DOS relocatable executable
/// </summary>
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))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))];
BaseStream = stream;
BaseStream.Position = 0; BaseStream.Position = 0;
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Header = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader)); Header = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
IsMZ = Header.signature == Signature; Recognized = Header.signature == Signature;
if(!Recognized) return;
Type = "DOS Executable (MZ)";
} }
/// <summary> /// <summary>

View File

@@ -33,6 +33,8 @@ namespace libexeinfo
{ {
public partial class NE public partial class NE
{ {
public string Information => GetInfo(Header);
public static string GetInfo(NEHeader header) public static string GetInfo(NEHeader header)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -192,12 +194,7 @@ namespace libexeinfo
return sb.ToString(); return sb.ToString();
} }
public string GetInfo() public static ResourceTable GetResources(Stream stream, uint neStart, ushort tableOff)
{
return GetInfo(Header);
}
public static ResourceTable GetResources(FileStream stream, uint neStart, ushort tableOff)
{ {
long oldPosition = stream.Position; long oldPosition = stream.Position;
byte[] DW = new byte[2]; byte[] DW = new byte[2];

View File

@@ -33,23 +33,15 @@ namespace libexeinfo
/// <summary> /// <summary>
/// Represents a Microsoft New Executable /// Represents a Microsoft New Executable
/// </summary> /// </summary>
public partial class NE public partial class NE : IExecutable
{ {
public readonly MZ BaseExecutable; MZ BaseExecutable;
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public readonly FileStream BaseStream;
/// <summary> /// <summary>
/// Header for this executable /// Header for this executable
/// </summary> /// </summary>
public readonly NEHeader Header; public NEHeader Header;
/// <summary> public ResourceTable Resources;
/// If true this instance correctly represents a Microsoft New Executable public Version[] Versions;
/// </summary>
public readonly bool IsNE;
public readonly ResourceTable Resources;
public readonly Version[] Versions;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class.
@@ -57,44 +49,52 @@ namespace libexeinfo
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public NE(string path) public NE(string path)
{ {
IsNE = false;
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseExecutable = new MZ(BaseStream); Initialize();
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();
}
}
}
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class.
/// </summary> /// </summary>
/// <param name="stream">Stream containing the executable.</param> /// <param name="stream">Stream containing the executable.</param>
public NE(FileStream stream) public NE(Stream stream)
{ {
IsNE = false;
BaseStream = stream; BaseStream = stream;
BaseExecutable = new MZ(BaseStream); Initialize();
if(BaseExecutable.IsMZ) }
if(BaseExecutable.Header.new_offset < BaseStream.Length)
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class.
/// </summary>
/// <param name="data">Stream containing the executable.</param>
public NE(byte[] data)
{ {
BaseStream = new MemoryStream(data);
Initialize();
}
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public Stream BaseStream { get; }
public bool IsBigEndian => false;
/// <summary>
/// If true this instance correctly represents a Microsoft New Executable
/// </summary>
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); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -102,18 +102,14 @@ namespace libexeinfo
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
if(Header.signature == Signature) if(Header.signature != Signature) return;
{
IsNE = true; Recognized = true;
if(Header.resource_entries > 0) if(Header.resource_entries <= 0) return;
{
Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Header.resource_table_offset);
Header.resource_table_offset);
Versions = GetVersions().ToArray(); Versions = GetVersions().ToArray();
} }
}
}
}
/// <summary> /// <summary>
/// Identifies if the specified executable is a Microsoft New Executable /// Identifies if the specified executable is a Microsoft New Executable
@@ -124,9 +120,10 @@ namespace libexeinfo
{ {
FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(!BaseExecutable.Recognized) return false;
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false;
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -137,9 +134,6 @@ namespace libexeinfo
return Header.signature == Signature; return Header.signature == Signature;
} }
return false;
}
/// <summary> /// <summary>
/// Identifies if the specified executable is a Microsoft New Executable /// Identifies if the specified executable is a Microsoft New Executable
/// </summary> /// </summary>
@@ -149,9 +143,10 @@ namespace libexeinfo
{ {
FileStream BaseStream = stream; FileStream BaseStream = stream;
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(!BaseExecutable.Recognized) return false;
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false;
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -161,8 +156,5 @@ namespace libexeinfo
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
return Header.signature == Signature; return Header.signature == Signature;
} }
return false;
}
} }
} }

View File

@@ -30,6 +30,8 @@ namespace libexeinfo
{ {
public partial class PE public partial class PE
{ {
public string Information => GetInfo(Header, WinHeader);
public static string GetInfo(PEHeader header, WindowsHeader64 winheader) public static string GetInfo(PEHeader header, WindowsHeader64 winheader)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -97,10 +99,5 @@ namespace libexeinfo
return sb.ToString(); return sb.ToString();
} }
public string GetInfo()
{
return GetInfo(Header, WinHeader);
}
} }
} }

View File

@@ -33,22 +33,14 @@ namespace libexeinfo
/// <summary> /// <summary>
/// Represents a Microsoft Portable Executable /// Represents a Microsoft Portable Executable
/// </summary> /// </summary>
public partial class PE public partial class PE : IExecutable
{ {
public readonly MZ BaseExecutable; MZ BaseExecutable;
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public readonly FileStream BaseStream;
/// <summary> /// <summary>
/// Header for this executable /// Header for this executable
/// </summary> /// </summary>
public readonly PEHeader Header; PEHeader Header;
/// <summary> WindowsHeader64 WinHeader;
/// If true this instance correctly represents a Microsoft Portable Executable
/// </summary>
public readonly bool IsPE;
public readonly WindowsHeader64 WinHeader;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class.
@@ -56,57 +48,51 @@ namespace libexeinfo
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public PE(string path) public PE(string path)
{ {
IsPE = false;
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseExecutable = new MZ(BaseStream); Initialize();
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);
}
}
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class. /// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class.
/// </summary> /// </summary>
/// <param name="stream">Stream containing the executable.</param> /// <param name="stream">Stream containing the executable.</param>
public PE(FileStream stream) public PE(Stream stream)
{ {
IsPE = false;
BaseStream = stream; BaseStream = stream;
BaseExecutable = new MZ(BaseStream); Initialize();
if(BaseExecutable.IsMZ) }
if(BaseExecutable.Header.new_offset < BaseStream.Length)
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class.
/// </summary>
/// <param name="data">Byte array containing the executable.</param>
public PE(byte[] data)
{ {
BaseStream = new MemoryStream(data);
Initialize();
}
/// <summary>
/// The <see cref="FileStream" /> that contains the executable represented by this instance
/// </summary>
public Stream BaseStream { get; }
public bool IsBigEndian => false;
/// <summary>
/// If true this instance correctly represents a Microsoft Portable Executable
/// </summary>
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); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -114,9 +100,12 @@ namespace libexeinfo
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
IsPE = Header.signature == Signature; Recognized = Header.signature == Signature;
if(!Recognized) return;
Type = "Portable Executable (PE)";
if(IsPE)
if(Header.coff.optionalHeader.magic == PE32Plus) if(Header.coff.optionalHeader.magic == PE32Plus)
{ {
BaseStream.Position -= 4; BaseStream.Position -= 4;
@@ -138,7 +127,6 @@ namespace libexeinfo
WinHeader = ToPlus(hdr32); WinHeader = ToPlus(hdr32);
} }
} }
}
/// <summary> /// <summary>
/// Identifies if the specified executable is a Microsoft Portable Executable /// Identifies if the specified executable is a Microsoft Portable Executable
@@ -149,9 +137,10 @@ namespace libexeinfo
{ {
FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(!BaseExecutable.Recognized) return false;
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false;
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -162,9 +151,6 @@ namespace libexeinfo
return Header.signature == Signature; return Header.signature == Signature;
} }
return false;
}
/// <summary> /// <summary>
/// Identifies if the specified executable is a Microsoft Portable Executable /// Identifies if the specified executable is a Microsoft Portable Executable
/// </summary> /// </summary>
@@ -174,9 +160,10 @@ namespace libexeinfo
{ {
FileStream BaseStream = stream; FileStream BaseStream = stream;
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(!BaseExecutable.Recognized) return false;
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ if(BaseExecutable.Header.new_offset >= BaseStream.Length) return false;
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(PEHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
@@ -187,9 +174,6 @@ namespace libexeinfo
return Header.signature == Signature; return Header.signature == Signature;
} }
return false;
}
static WindowsHeader64 ToPlus(WindowsHeader header) static WindowsHeader64 ToPlus(WindowsHeader header)
{ {
return new WindowsHeader64 return new WindowsHeader64

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\NuGet.Build.Packaging.0.1.276\build\NuGet.Build.Packaging.props" Condition="Exists('..\packages\NuGet.Build.Packaging.0.1.276\build\NuGet.Build.Packaging.props')" /> <Import Project="..\packages\NuGet.Build.Packaging.0.1.276\build\NuGet.Build.Packaging.props" Condition="Exists('..\packages\NuGet.Build.Packaging.0.1.276\build\NuGet.Build.Packaging.props')" />
<PropertyGroup> <PropertyGroup>
@@ -43,6 +43,7 @@
<Reference Include="System" /> <Reference Include="System" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="IExecutable.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="MZ\Consts.cs" /> <Compile Include="MZ\Consts.cs" />
<Compile Include="MZ\Info.cs" /> <Compile Include="MZ\Info.cs" />