This commit is contained in:
2018-02-25 03:08:28 +00:00
parent 9dd6c1efa0
commit cf1f1c0289
38 changed files with 3118 additions and 3138 deletions

View File

@@ -25,10 +25,9 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Text; using System.Text;
using libexeinfo; using libexeinfo;
@@ -38,7 +37,7 @@ namespace exeinfo
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
if (args.Length != 1) if(args.Length != 1)
{ {
Console.WriteLine("exeinfo version 0.1 © 2017 Natalia Portillo"); Console.WriteLine("exeinfo version 0.1 © 2017 Natalia Portillo");
Console.WriteLine("Usage: exeinfo file.exe"); Console.WriteLine("Usage: exeinfo file.exe");
@@ -49,97 +48,100 @@ namespace exeinfo
bool recognized = false; bool recognized = false;
MZ mzExe = new MZ(exeFs); MZ mzExe = new MZ(exeFs);
NE neExe = new NE(exeFs); NE neExe = new NE(exeFs);
AtariST stExe = new AtariST(exeFs); AtariST stExe = new AtariST(exeFs);
LX lxExe = new LX(exeFs); LX lxExe = new LX(exeFs);
COFF coffExe = new COFF(exeFs); COFF coffExe = new COFF(exeFs);
PE peExe = new PE(exeFs); PE peExe = new PE(exeFs);
if (mzExe.IsMZ) if(mzExe.IsMZ)
{ {
recognized = true; recognized = true;
Console.Write(mzExe.GetInfo()); Console.Write(mzExe.GetInfo());
} }
if (neExe.IsNE) if(neExe.IsNE)
{ {
recognized = true; recognized = true;
Console.Write(neExe.GetInfo()); Console.Write(neExe.GetInfo());
if (neExe.Versions != null) if(neExe.Versions != null)
{ foreach(NE.Version vers in neExe.Versions)
foreach (NE.Version vers in 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);
Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion); Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion);
Console.WriteLine("\t\tFile type: {0}", NE.Version.TypeToString(vers.FileType)); Console.WriteLine("\t\tFile type: {0}", NE.Version.TypeToString(vers.FileType));
if (vers.FileType == NE.VersionFileType.VFT_DRV) if(vers.FileType == NE.VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} driver", NE.Version.DriverToString(vers.FileSubtype)); Console.WriteLine("\t\tFile subtype: {0} driver",
else if (vers.FileType == NE.VersionFileType.VFT_DRV) NE.Version.DriverToString(vers.FileSubtype));
else if(vers.FileType == NE.VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} font", NE.Version.FontToString(vers.FileSubtype)); Console.WriteLine("\t\tFile subtype: {0} font", NE.Version.FontToString(vers.FileSubtype));
else if (vers.FileSubtype > 0) else if(vers.FileSubtype > 0)
Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype); Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype);
Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags); Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags);
Console.WriteLine("\t\tFile OS: {0}", NE.Version.OsToString(vers.FileOS)); Console.WriteLine("\t\tFile OS: {0}", NE.Version.OsToString(vers.FileOS));
foreach (KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage) foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage)
{ {
string cultureName; string cultureName;
string encodingName; string encodingName;
try try
{ {
cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16)).DisplayName; cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16))
.DisplayName;
} }
catch catch
{ {
cultureName = string.Format("unsupported culture 0x{0:X4}", Convert.ToInt32(strByLang.Key.Substring(0, 4), 16)); cultureName =
$"unsupported culture 0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}";
} }
try try
{ {
encodingName = Encoding.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16)).EncodingName; encodingName = Encoding
.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16))
.EncodingName;
} }
catch catch
{ {
encodingName = string.Format("unsupported encoding 0x{0:X4}", Convert.ToInt32(strByLang.Key.Substring(4), 16)); encodingName =
$"unsupported encoding 0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}";
} }
Console.WriteLine("\t\tStrings for {0} in codepage {1}:", cultureName, encodingName); Console.WriteLine("\t\tStrings for {0} in codepage {1}:", cultureName, encodingName);
foreach (KeyValuePair<string, string> strings in strByLang.Value) foreach(KeyValuePair<string, string> strings in strByLang.Value)
Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value); Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value);
} }
} }
}
} }
if (stExe.IsAtariST) if(stExe.IsAtariST)
{ {
recognized = true; recognized = true;
Console.Write(stExe.GetInfo()); Console.Write(stExe.GetInfo());
} }
if (lxExe.IsLX) if(lxExe.IsLX)
{ {
recognized = true; recognized = true;
Console.Write(lxExe.GetInfo()); Console.Write(lxExe.GetInfo());
} }
if (coffExe.IsCOFF) if(coffExe.IsCOFF)
{ {
recognized = true; recognized = true;
Console.Write(coffExe.GetInfo()); Console.Write(coffExe.GetInfo());
} }
if (peExe.IsPE) if(peExe.IsPE)
{ {
recognized = true; recognized = true;
Console.Write(peExe.GetInfo()); Console.Write(peExe.GetInfo());
} }
if (!recognized) if(!recognized) Console.WriteLine("Executable format not recognized");
Console.WriteLine("Executable format not recognized");
} }
} }
} }

View File

@@ -1,15 +1,41 @@
using System; //
// Program.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using Eto;
using Eto.Forms; using Eto.Forms;
using Eto.Drawing;
namespace exeinfogui.Desktop namespace exeinfogui.Desktop
{ {
class Program static class Program
{ {
[STAThread] [STAThread]
static void Main(string[] args) static void Main(string[] args)
{ {
new Application(Eto.Platform.Detect).Run(new MainForm()); new Application(Platform.Detect).Run(new MainForm());
} }
} }
} }

View File

@@ -1,4 +1,30 @@
using AppKit; //
// Program.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using AppKit;
using Eto.Forms; using Eto.Forms;
namespace exeinfogui.XamMac namespace exeinfogui.XamMac

View File

@@ -1,3 +1,29 @@
//
// MainForm.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System; using System;
using System.IO; using System.IO;
using Eto.Forms; using Eto.Forms;
@@ -8,9 +34,9 @@ namespace exeinfogui
{ {
public class MainForm : Form public class MainForm : Form
{ {
TextBox txtFile; TextBox txtFile;
TextBox txtType;
TextArea txtInformation; TextArea txtInformation;
TextBox txtType;
public MainForm() public MainForm()
{ {
@@ -19,9 +45,9 @@ namespace exeinfogui
protected void OnBtnLoadClick(object sender, EventArgs e) protected void OnBtnLoadClick(object sender, EventArgs e)
{ {
txtFile.Text = ""; txtFile.Text = "";
txtType.Text = ""; txtType.Text = "";
txtInformation.Text =""; txtInformation.Text = "";
OpenFileDialog dlgOpen = new OpenFileDialog {Title = "Choose executable file", MultiSelect = false}; OpenFileDialog dlgOpen = new OpenFileDialog {Title = "Choose executable file", MultiSelect = false};
@@ -57,17 +83,17 @@ namespace exeinfogui
} }
else else
txtType.Text = "DOS Executable (MZ)"; txtType.Text = "DOS Executable (MZ)";
txtInformation.Text += mzExe.GetInfo(); txtInformation.Text += mzExe.GetInfo();
} }
else if(stExe.IsAtariST) else if(stExe.IsAtariST)
{ {
txtType.Text = "Atari ST executable"; txtType.Text = "Atari ST executable";
txtInformation.Text = stExe.GetInfo(); txtInformation.Text = stExe.GetInfo();
} }
else if(coffExe.IsCOFF) else if(coffExe.IsCOFF)
{ {
txtType.Text = "Common Object File Format (COFF)"; txtType.Text = "Common Object File Format (COFF)";
txtInformation.Text = coffExe.GetInfo(); txtInformation.Text = coffExe.GetInfo();
} }
else else

View File

@@ -23,84 +23,85 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
{ {
/// <summary> /// <summary>
/// Represents an Atari ST executable /// Represents an Atari ST executable
/// </summary> /// </summary>
public partial class AtariST public partial class AtariST
{ {
/// <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 readonly FileStream BaseStream;
/// <summary> /// <summary>
/// Header for this executable /// Header for this executable
/// </summary> /// </summary>
public readonly AtariHeader Header; public readonly AtariHeader Header;
/// <summary> /// <summary>
/// If true this instance correctly represents an Atari ST executable /// If true this instance correctly represents an Atari ST executable
/// </summary> /// </summary>
public readonly bool IsAtariST; 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))]; 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; 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; 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(FileStream stream)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))];
BaseStream = stream; BaseStream = stream;
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; IsAtariST = Header.signature == SIGNATURE;
} }
/// <summary> /// <summary>
/// Identifies if the specified executable is a Atari ST executable /// Identifies if the specified executable is a Atari ST executable
/// </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="path">Executable path.</param> /// <param name="path">Executable path.</param>
public static bool Identify(string path) public static bool Identify(string path)
{ {
FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read); FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read);
return Identify(exeFs); return Identify(exeFs);
} }
/// <summary> /// <summary>
/// Identifies if the specified executable is a Atari ST executable /// Identifies if the specified executable is a Atari ST executable
/// </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(FileStream stream)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))];
stream.Position = 0; stream.Position = 0;
stream.Read(buffer, 0, buffer.Length); stream.Read(buffer, 0, buffer.Length);
AtariHeader hdr = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariHeader>(buffer); AtariHeader hdr = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariHeader>(buffer);
return hdr.signature == Signature; return hdr.signature == SIGNATURE;
} }
} }
} }

View File

@@ -23,11 +23,11 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class AtariST public partial class AtariST
{ {
public const ushort Signature = 0x601A; const ushort SIGNATURE = 0x601A;
} }
} }

View File

@@ -29,30 +29,30 @@ using System.Text;
namespace libexeinfo namespace libexeinfo
{ {
public partial class AtariST public partial class AtariST
{ {
/// <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) public static string GetInfo(AtariHeader header)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.AppendLine("Atari ST executable:"); sb.AppendLine("Atari ST executable:");
sb.AppendFormat("\t{0} bytes in text segment", header.text_len).AppendLine(); sb.AppendFormat("\t{0} bytes in text segment", header.text_len).AppendLine();
sb.AppendFormat("\t{0} bytes in data segment", header.data_len).AppendLine(); sb.AppendFormat("\t{0} bytes in data segment", header.data_len).AppendLine();
sb.AppendFormat("\t{0} bytes in BSS segment", header.bss_len).AppendLine(); sb.AppendFormat("\t{0} bytes in BSS segment", header.bss_len).AppendLine();
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> /// <summary>
/// Gets a string with human readable information for the Atari ST executable represented by this instance /// Gets a string with human readable information for the Atari ST executable represented by this instance
/// </summary> /// </summary>
/// <returns>Human readable information for this instance.</returns> /// <returns>Human readable information for this instance.</returns>
public string GetInfo() public string GetInfo()
{ {
return GetInfo(Header); return GetInfo(Header);
} }
} }
} }

View File

@@ -23,24 +23,24 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
{ {
public partial class AtariST public partial class AtariST
{ {
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AtariHeader public struct AtariHeader
{ {
public ushort signature; public ushort signature;
public uint text_len; public uint text_len;
public uint data_len; public uint data_len;
public uint bss_len; public uint bss_len;
public uint symb_len; public uint symb_len;
public uint reserved; public uint reserved;
public uint flags; public uint flags;
public ushort absflags; public ushort absflags;
} }
} }
} }

View File

@@ -23,6 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@@ -33,8 +34,8 @@ namespace libexeinfo
public static class BigEndianMarshal public static class BigEndianMarshal
{ {
/// <summary> /// <summary>
/// Marshals a big endian structure from a byte array. /// Marshals a big endian structure from a byte array.
/// Nested structures are still marshalled as little endian. /// Nested structures are still marshalled as little endian.
/// </summary> /// </summary>
/// <returns>The structure.</returns> /// <returns>The structure.</returns>
/// <param name="bytes">Byte array.</param> /// <param name="bytes">Byte array.</param>
@@ -42,81 +43,80 @@ namespace libexeinfo
public static T ByteArrayToStructureBigEndian<T>(byte[] bytes) where T : struct public static T ByteArrayToStructureBigEndian<T>(byte[] bytes) where T : struct
{ {
GCHandle ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned); GCHandle ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T str = (T)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T)); T str = (T)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
ptr.Free(); ptr.Free();
return SwapStructureMembersEndian(str); return SwapStructureMembersEndian(str);
} }
/// <summary> /// <summary>
/// Swaps endian of structure members that correspond to numerical types. /// Swaps endian of structure members that correspond to numerical types.
/// Does not traverse nested structures. /// Does not traverse nested structures.
/// </summary> /// </summary>
/// <returns>The structure with its members endian swapped.</returns> /// <returns>The structure with its members endian swapped.</returns>
/// <param name="str">The structure.</param> /// <param name="str">The structure.</param>
/// <typeparam name="T">Structure type.</typeparam> /// <typeparam name="T">Structure type.</typeparam>
public static T SwapStructureMembersEndian<T>(T str) where T : struct public static T SwapStructureMembersEndian<T>(T str) where T : struct
{ {
Type t = str.GetType(); Type t = str.GetType();
FieldInfo[] fieldInfo = t.GetFields(); FieldInfo[] fieldInfo = t.GetFields();
foreach (FieldInfo fi in fieldInfo) foreach(FieldInfo fi in fieldInfo)
{ if(fi.FieldType == typeof(short))
if (fi.FieldType == typeof(short))
{ {
short int16 = (short)fi.GetValue(str); short int16 = (short)fi.GetValue(str);
byte[] int16_b = BitConverter.GetBytes(int16); byte[] int16_b = BitConverter.GetBytes(int16);
byte[] int16_r = int16_b.Reverse().ToArray(); byte[] int16_r = int16_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt16(int16_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToInt16(int16_r, 0));
} }
else if (fi.FieldType == typeof(int)) else if(fi.FieldType == typeof(int))
{ {
int int32 = (int)fi.GetValue(str); int int32 = (int)fi.GetValue(str);
byte[] int32_b = BitConverter.GetBytes(int32); byte[] int32_b = BitConverter.GetBytes(int32);
byte[] int32_r = int32_b.Reverse().ToArray(); byte[] int32_r = int32_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt32(int32_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToInt32(int32_r, 0));
} }
else if (fi.FieldType == typeof(long)) else if(fi.FieldType == typeof(long))
{ {
long int64 = (long)fi.GetValue(str); long int64 = (long)fi.GetValue(str);
byte[] int64_b = BitConverter.GetBytes(int64); byte[] int64_b = BitConverter.GetBytes(int64);
byte[] int64_r = int64_b.Reverse().ToArray(); byte[] int64_r = int64_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt64(int64_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToInt64(int64_r, 0));
} }
else if (fi.FieldType == typeof(ushort)) else if(fi.FieldType == typeof(ushort))
{ {
ushort uint16 = (ushort)fi.GetValue(str); ushort uint16 = (ushort)fi.GetValue(str);
byte[] uint16_b = BitConverter.GetBytes(uint16); byte[] uint16_b = BitConverter.GetBytes(uint16);
byte[] uint16_r = uint16_b.Reverse().ToArray(); byte[] uint16_r = uint16_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt16(uint16_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToInt16(uint16_r, 0));
} }
else if (fi.FieldType == typeof(uint)) else if(fi.FieldType == typeof(uint))
{ {
uint uint32 = (uint)fi.GetValue(str); uint uint32 = (uint)fi.GetValue(str);
byte[] uint32_b = BitConverter.GetBytes(uint32); byte[] uint32_b = BitConverter.GetBytes(uint32);
byte[] uint32_r = uint32_b.Reverse().ToArray(); byte[] uint32_r = uint32_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt32(uint32_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToInt32(uint32_r, 0));
} }
else if (fi.FieldType == typeof(ulong)) else if(fi.FieldType == typeof(ulong))
{ {
ulong uint64 = (ulong)fi.GetValue(str); ulong uint64 = (ulong)fi.GetValue(str);
byte[] uint64_b = BitConverter.GetBytes(uint64); byte[] uint64_b = BitConverter.GetBytes(uint64);
byte[] uint64_r = uint64_b.Reverse().ToArray(); byte[] uint64_r = uint64_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt64(uint64_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToInt64(uint64_r, 0));
} }
else if (fi.FieldType == typeof(float)) else if(fi.FieldType == typeof(float))
{ {
float flt = (float)fi.GetValue(str); float flt = (float)fi.GetValue(str);
byte[] flt_b = BitConverter.GetBytes(flt); byte[] flt_b = BitConverter.GetBytes(flt);
byte[] flt_r = flt_b.Reverse().ToArray(); byte[] flt_r = flt_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToSingle(flt_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToSingle(flt_r, 0));
} }
else if (fi.FieldType == typeof(double)) else if(fi.FieldType == typeof(double))
{ {
double dbl = (double)fi.GetValue(str); double dbl = (double)fi.GetValue(str);
byte[] dbl_b = BitConverter.GetBytes(dbl); byte[] dbl_b = BitConverter.GetBytes(dbl);
byte[] dbl_r = dbl_b.Reverse().ToArray(); byte[] dbl_r = dbl_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToDouble(dbl_r, 0)); fi.SetValueDirect(__makeref(str), BitConverter.ToDouble(dbl_r, 0));
} }
}
return str; return str;
} }
} }

View File

@@ -23,130 +23,136 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace libexeinfo 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
{ {
/// <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 readonly FileStream BaseStream;
/// <summary> /// <summary>
/// Header for this executable /// Header for this executable
/// </summary> /// </summary>
public readonly COFFHeader Header; public readonly COFFHeader Header;
/// <summary> public readonly bool IsBigEndian;
/// If true this instance correctly represents a Common Object File Format /// <summary>
/// </summary> /// If true this instance correctly represents a Common Object File Format
public readonly bool IsCOFF; /// </summary>
public readonly bool IsBigEndian; 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))]; 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; 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 || Header.optionalHeader.magic == JMAGIC || IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC ||
Header.optionalHeader.magic == DMAGIC || Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
IsBigEndian = false; IsBigEndian = false;
if(!IsCOFF) if(!IsCOFF)
{ {
Header = SwapHeader(Header); Header = SwapHeader(Header);
IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || Header.optionalHeader.magic == JMAGIC || IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC ||
Header.optionalHeader.magic == DMAGIC || Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
IsBigEndian = !IsCOFF; Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
} IsBigEndian = !IsCOFF;
} }
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.COFF"/> class.
/// </summary>
/// <param name="stream">Stream containing the executable.</param>
public COFF(FileStream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))];
BaseStream = stream; /// <summary>
BaseStream.Position = 0; /// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class.
BaseStream.Read(buffer, 0, buffer.Length); /// </summary>
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); /// <param name="stream">Stream containing the executable.</param>
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); public COFF(FileStream stream)
Header = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader)); {
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); Marshal.FreeHGlobal(hdrPtr);
IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || Header.optionalHeader.magic == JMAGIC || IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC ||
Header.optionalHeader.magic == DMAGIC || Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
IsBigEndian = false; IsBigEndian = false;
if (!IsCOFF) if(!IsCOFF)
{ {
Header = SwapHeader(Header); Header = SwapHeader(Header);
IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC || Header.optionalHeader.magic == JMAGIC || IsCOFF = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC ||
Header.optionalHeader.magic == DMAGIC || Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC; Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
IsBigEndian = !IsCOFF; Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
} IsBigEndian = !IsCOFF;
} }
}
/// <summary> /// <summary>
/// Identifies if the specified executable is a Common Object File Format /// Identifies if the specified executable is a Common Object File Format
/// </summary> /// </summary>
/// <returns><c>true</c> if the specified executable is a Common Object File Format, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Common Object File Format, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public static bool Identify(string path) public static bool Identify(string path)
{ {
FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read); FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read);
return Identify(exeFs); return Identify(exeFs);
} }
/// <summary> /// <summary>
/// Identifies if the specified executable is a Common Object File Format /// Identifies if the specified executable is a Common Object File Format
/// </summary> /// </summary>
/// <returns><c>true</c> if the specified executable is a Common Object File Format, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Common Object File Format, <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(FileStream stream)
{ {
byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))]; byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))];
stream.Position = 0; stream.Position = 0;
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 || COFFHdr.optionalHeader.magic == JMAGIC || if(COFFHdr.optionalHeader.magic == STMAGIC || COFFHdr.optionalHeader.magic == OMAGIC ||
COFFHdr.optionalHeader.magic == DMAGIC || COFFHdr.optionalHeader.magic == ZMAGIC || COFFHdr.optionalHeader.magic == SHMAGIC) COFFHdr.optionalHeader.magic == JMAGIC || COFFHdr.optionalHeader.magic == DMAGIC ||
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 || COFFHdr.optionalHeader.magic == JMAGIC || return COFFHdr.optionalHeader.magic == STMAGIC || COFFHdr.optionalHeader.magic == OMAGIC ||
COFFHdr.optionalHeader.magic == DMAGIC || COFFHdr.optionalHeader.magic == ZMAGIC || COFFHdr.optionalHeader.magic == SHMAGIC; COFFHdr.optionalHeader.magic == JMAGIC || COFFHdr.optionalHeader.magic == DMAGIC ||
} COFFHdr.optionalHeader.magic == ZMAGIC || COFFHdr.optionalHeader.magic == SHMAGIC;
}
static COFFHeader SwapHeader(COFFHeader header) static COFFHeader SwapHeader(COFFHeader header)
{ {
COFFHeader swapped = BigEndianMarshal.SwapStructureMembersEndian(header); COFFHeader swapped = BigEndianMarshal.SwapStructureMembersEndian(header);
swapped.characteristics = (Characteristics)Swapping.Swap((ushort)header.characteristics); swapped.characteristics = (Characteristics)Swapping.Swap((ushort)header.characteristics);
swapped.machine = (MachineTypes)Swapping.Swap((ushort)header.machine); swapped.machine = (MachineTypes)Swapping.Swap((ushort)header.machine);
swapped.optionalHeader = BigEndianMarshal.SwapStructureMembersEndian(header.optionalHeader); swapped.optionalHeader = BigEndianMarshal.SwapStructureMembersEndian(header.optionalHeader);
return swapped; return swapped;
} }
} }
} }

View File

@@ -28,86 +28,86 @@ namespace libexeinfo
{ {
public partial class COFF public partial class COFF
{ {
public const ushort STMAGIC = 0x101; public const ushort STMAGIC = 0x101;
public const ushort OMAGIC = 0x104; public 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; public const ushort JMAGIC = 0x107;
/// <summary> /// <summary>
/// dirty text segment, data aligned /// dirty text segment, data aligned
/// </summary> /// </summary>
public const ushort DMAGIC = 0x108; public 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; public const ushort ZMAGIC = 0x10b;
/// <summary> /// <summary>
/// shared library header /// shared library header
/// </summary> /// </summary>
public const ushort SHMAGIC = 0x123; public const ushort SHMAGIC = 0x123;
/// <summary> /// <summary>
/// Alpha architecture information /// Alpha architecture information
/// </summary> /// </summary>
public readonly string SectionAlpha = ".arch"; public readonly string SectionAlpha = ".arch";
/// <summary> /// <summary>
/// Uninitialized data /// Uninitialized data
/// </summary> /// </summary>
public readonly string SectionBss = ".bss"; public readonly string SectionBss = ".bss";
/// <summary> /// <summary>
/// Initialized data /// Initialized data
/// </summary> /// </summary>
public readonly string SectionData = ".data"; public readonly string SectionData = ".data";
/// <summary> /// <summary>
/// The export data section, named .edata, contains information about /// Debug information
/// symbols that other images can access through dynamic linking. /// </summary>
/// Exports are generally found in DLLs, but DLLs can import symbols as public readonly string SectionDebug = ".debug";
/// well. /// <summary>
/// </summary> /// A .drectve section consists of a string of ASCII text. This string is
public readonly string SectionExport = ".edata"; /// a series of linker options (each option containing hyphen, option
/// <summary> /// name, and any appropriate attribute) separated by spaces.The
/// Import tables /// .drectve section must not have relocations or line numbers.
/// </summary> /// </summary>
public readonly string SectionImport = ".idata"; public readonly string SectionDirectives = ".drectve";
/// <summary> /// <summary>
/// Exception information /// Exception information
/// </summary> /// </summary>
public readonly string SectionException = ".pdata"; public readonly string SectioneXception = ".xdata";
/// <summary> /// <summary>
/// Read-only initialized data /// Exception information
/// </summary> /// </summary>
public readonly string SectionReadOnly = ".rdata"; public readonly string SectionException = ".pdata";
/// <summary> /// <summary>
/// Image relocations /// Executable code
/// </summary> /// </summary>
public readonly string SectionRelocations = ".reloc"; public readonly string SectionExecutable = ".text";
/// <summary> /// <summary>
/// Resource directory /// The export data section, named .edata, contains information about
/// </summary> /// symbols that other images can access through dynamic linking.
public readonly string SectionResource = ".rsrc"; /// Exports are generally found in DLLs, but DLLs can import symbols as
/// <summary> /// well.
/// Executable code /// </summary>
/// </summary> public readonly string SectionExport = ".edata";
public readonly string SectionExecutable = ".text"; /// <summary>
/// <summary> /// Import tables
/// Thread-local storage /// </summary>
/// </summary> public readonly string SectionImport = ".idata";
public readonly string SectionTls = ".tls"; /// <summary>
/// <summary> /// Read-only initialized data
/// Exception information /// </summary>
/// </summary> public readonly string SectionReadOnly = ".rdata";
public readonly string SectioneXception = ".xdata"; /// <summary>
/// <summary> /// Image relocations
/// Debug information /// </summary>
/// </summary> public readonly string SectionRelocations = ".reloc";
public readonly string SectionDebug = ".debug"; /// <summary>
/// <summary> /// Resource directory
/// A .drectve section consists of a string of ASCII text. This string is /// </summary>
/// a series of linker options (each option containing hyphen, option public readonly string SectionResource = ".rsrc";
/// name, and any appropriate attribute) separated by spaces.The /// <summary>
/// .drectve section must not have relocations or line numbers. /// Thread-local storage
/// </summary> /// </summary>
public readonly string SectionDirectives = ".drectve"; public readonly string SectionTls = ".tls";
} }
} }

View File

@@ -25,391 +25,401 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class COFF public partial class COFF
{ {
/// <summary> /// <summary>
/// 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. /// The Characteristics field contains flags that indicate attributes of the object or image file.
/// </summary> /// </summary>
public enum MachineTypes : ushort [Flags]
{
/// <summary>
/// The contents of this field are assumed to be applicable to any machine type
/// </summary>
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
/// <summary>
/// Alpha AXP
/// </summary>
IMAGE_FILE_MACHINE_ALPHA = 0x184,
/// <summary>
/// Alpha AXP 64-bit.
/// </summary>
IMAGE_FILE_MACHINE_ALPHA64 = 0x284,
/// <summary>
/// Matsushita AM33
/// </summary>
IMAGE_FILE_MACHINE_AM33 = 0x1d3,
/// <summary>
/// x64
/// </summary>
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
/// <summary>
/// ARM little endian
/// </summary>
IMAGE_FILE_MACHINE_ARM = 0x1c0,
/// <summary>
/// ARM64 little endian
/// </summary>
IMAGE_FILE_MACHINE_ARM64 = 0xaa64,
/// <summary>
/// ARM Thumb-2 little endian
/// </summary>
IMAGE_FILE_MACHINE_ARMNT = 0x1c4,
/// <summary>
/// Clipper
/// </summary>
IMAGE_FILE_MACHINE_CLIPPER = 0x17f,
/// <summary>
/// EFI byte code
/// </summary>
IMAGE_FILE_MACHINE_EBC = 0xebc,
/// <summary>
/// Intel 386 or later processors and compatible processors
/// </summary>
IMAGE_FILE_MACHINE_I386 = 0x14c,
/// <summary>
/// Intel 386 or later processors and compatible processors, used by AIX
/// </summary>
IMAGE_FILE_MACHINE_I386_AIX = 0x175,
/// <summary>
/// Intel Itanium processor family
/// </summary>
IMAGE_FILE_MACHINE_IA64 = 0x200,
/// <summary>
/// Mitsubishi M32R little endian
/// </summary>
IMAGE_FILE_MACHINE_M32R = 0x9041,
/// <summary>
/// Motorola 68000 series
/// </summary>
IMAGE_FILE_MACHINE_M68K = 0x268,
/// <summary>
/// Motorola 68000 series
/// </summary>
IMAGE_FILE_MACHINE_M68K_OTHER = 0x150,
/// <summary>
/// MIPS16
/// </summary>
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
/// <summary>
/// MIPS with FPU
/// </summary>
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
/// <summary>
/// MIPS16 with FPU
/// </summary>
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
/// <summary>
/// PowerPC little endian
/// </summary>
IMAGE_FILE_MACHINE_POWERPC = 0x1f0,
/// <summary>
/// Power PC with floating point support
/// </summary>
IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1,
/// <summary>
/// MIPS big endian
/// </summary>
IMAGE_FILE_MACHINE_MIPSEB = 0x160,
/// <summary>
/// MIPS little endian
/// </summary>
IMAGE_FILE_MACHINE_R3000 = 0x162,
/// <summary>
/// MIPS little endian
/// </summary>
IMAGE_FILE_MACHINE_R4000 = 0x166,
/// <summary>
/// MIPS little endian
/// </summary>
IMAGE_FILE_MACHINE_R10000 = 0x168,
/// <summary>
/// RISC-V 32-bit address space
/// </summary>
IMAGE_FILE_MACHINE_RISCV32 = 0x5032,
/// <summary>
/// RISC-V 64-bit address space
/// </summary>
IMAGE_FILE_MACHINE_RISCV64 = 0x5064,
/// <summary>
/// RISC-V 128-bit address space
/// </summary>
IMAGE_FILE_MACHINE_RISCV128 = 0x5128,
/// <summary>
/// Hitachi SH3
/// </summary>
IMAGE_FILE_MACHINE_SH3 = 0x1a2,
/// <summary>
/// Hitachi SH3 DSP
/// </summary>
IMAGE_FILE_MACHINE_SH3DSP = 0x1a3,
/// <summary>
/// Hitachi SH4
/// </summary>
IMAGE_FILE_MACHINE_SH4 = 0x1a6,
/// <summary>
/// Hitachi SH5
/// </summary>
IMAGE_FILE_MACHINE_SH5 = 0x1a8,
/// <summary>
/// Thumb
/// </summary>
IMAGE_FILE_MACHINE_THUMB = 0x1c2,
/// <summary>
/// MIPS little-endian WCE v2
/// </summary>
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169,
/// <summary>
/// WE32000
/// </summary>
IMAGE_FILE_MACHINE_WE32000 = 0x170
}
/// <summary>
/// The Characteristics field contains flags that indicate attributes of the object or image file.
/// </summary>
[Flags]
public enum Characteristics : ushort public enum Characteristics : ushort
{ {
/// <summary> /// <summary>
/// Image only, Windows CE, and Microsoft Windows NT and later. This indicates that the file does not contain base relocations and must therefore be loaded at its preferred base address. If the base address is not available, the loader reports an error. The default behavior of the linker is to strip base relocations from executable (EXE) files. /// Image only, Windows CE, and Microsoft Windows NT and later. This indicates that the file does not contain base
/// </summary> /// relocations and must therefore be loaded at its preferred base address. If the base address is not available, the
IMAGE_FILE_RELOCS_STRIPPED = 0x0001, /// loader reports an error. The default behavior of the linker is to strip base relocations from executable (EXE)
/// <summary> /// files.
/// Image only. This indicates that the image file is valid and can be run. If this flag is not set, it indicates a linker error. /// </summary>
/// </summary> IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002, /// <summary>
/// <summary> /// Image only. This indicates that the image file is valid and can be run. If this flag is not set, it indicates a
/// COFF line numbers have been removed. This flag is deprecated and should be zero. /// linker error.
/// </summary> /// </summary>
IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004, IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
/// <summary> /// <summary>
/// COFF symbol table entries for local symbols have been removed. This flag is deprecated and should be zero. /// COFF line numbers have been removed. This flag is deprecated and should be zero.
/// </summary> /// </summary>
IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008, IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
/// <summary> /// <summary>
/// Obsolete. Aggressively trim working set. This flag is deprecated for Windows 2000 and later and must be zero. /// COFF symbol table entries for local symbols have been removed. This flag is deprecated and should be zero.
/// </summary> /// </summary>
IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010, IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
/// <summary> /// <summary>
/// Application can handle > 2-GB addresses. /// Obsolete. Aggressively trim working set. This flag is deprecated for Windows 2000 and later and must be zero.
/// </summary> /// </summary>
IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020, IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
/// <summary> /// <summary>
/// Machine is based on a 16-bit-word architecture. /// Application can handle > 2-GB addresses.
/// </summary> /// </summary>
IMAGE_FILE_16BIT_MACHINE = 0x0040, IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
/// <summary> /// <summary>
/// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory. This flag is deprecated and should be zero. /// Machine is based on a 16-bit-word architecture.
/// </summary> /// </summary>
IMAGE_FILE_BYTES_REVERSED_LO = 0x0080, IMAGE_FILE_16BIT_MACHINE = 0x0040,
/// <summary> /// <summary>
/// Machine is based on a 32-bit-word architecture. /// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory. This flag is
/// </summary> /// deprecated and should be zero.
IMAGE_FILE_32BIT_MACHINE = 0x0100, /// </summary>
/// <summary> IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
/// Debugging information is removed from the image file. /// <summary>
/// </summary> /// Machine is based on a 32-bit-word architecture.
IMAGE_FILE_DEBUG_STRIPPED = 0x0200, /// </summary>
/// <summary> IMAGE_FILE_32BIT_MACHINE = 0x0100,
/// If the image is on removable media, fully load it and copy it to the swap file. /// <summary>
/// </summary> /// Debugging information is removed from the image file.
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400, /// </summary>
/// <summary> IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
/// If the image is on network media, fully load it and copy it to the swap file. /// <summary>
/// </summary> /// If the image is on removable media, fully load it and copy it to the swap file.
IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800, /// </summary>
/// <summary> IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
/// The image file is a system file, not a user program. /// <summary>
/// </summary> /// If the image is on network media, fully load it and copy it to the swap file.
IMAGE_FILE_SYSTEM = 0x1000, /// </summary>
/// <summary> IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
/// The image file is a dynamic-link library (DLL). Such files are considered executable files for almost all purposes, although they cannot be directly run. /// <summary>
/// </summary> /// The image file is a system file, not a user program.
IMAGE_FILE_DLL = 0x2000, /// </summary>
/// <summary> IMAGE_FILE_SYSTEM = 0x1000,
/// The file should be run only on a uniprocessor machine. /// <summary>
/// </summary> /// The image file is a dynamic-link library (DLL). Such files are considered executable files for almost all purposes,
IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000, /// although they cannot be directly run.
/// <summary> /// </summary>
/// Big endian: the MSB precedes the LSB in memory. This flag is deprecated and should be zero. IMAGE_FILE_DLL = 0x2000,
/// </summary> /// <summary>
IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 /// The file should be run only on a uniprocessor machine.
/// </summary>
IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
/// <summary>
/// Big endian: the MSB precedes the LSB in memory. This flag is deprecated and should be zero.
/// </summary>
IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
}
/// <summary>
/// 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.
/// </summary>
public enum MachineTypes : ushort
{
/// <summary>
/// The contents of this field are assumed to be applicable to any machine type
/// </summary>
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
/// <summary>
/// Alpha AXP
/// </summary>
IMAGE_FILE_MACHINE_ALPHA = 0x184,
/// <summary>
/// Alpha AXP 64-bit.
/// </summary>
IMAGE_FILE_MACHINE_ALPHA64 = 0x284,
/// <summary>
/// Matsushita AM33
/// </summary>
IMAGE_FILE_MACHINE_AM33 = 0x1d3,
/// <summary>
/// x64
/// </summary>
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
/// <summary>
/// ARM little endian
/// </summary>
IMAGE_FILE_MACHINE_ARM = 0x1c0,
/// <summary>
/// ARM64 little endian
/// </summary>
IMAGE_FILE_MACHINE_ARM64 = 0xaa64,
/// <summary>
/// ARM Thumb-2 little endian
/// </summary>
IMAGE_FILE_MACHINE_ARMNT = 0x1c4,
/// <summary>
/// Clipper
/// </summary>
IMAGE_FILE_MACHINE_CLIPPER = 0x17f,
/// <summary>
/// EFI byte code
/// </summary>
IMAGE_FILE_MACHINE_EBC = 0xebc,
/// <summary>
/// Intel 386 or later processors and compatible processors
/// </summary>
IMAGE_FILE_MACHINE_I386 = 0x14c,
/// <summary>
/// Intel 386 or later processors and compatible processors, used by AIX
/// </summary>
IMAGE_FILE_MACHINE_I386_AIX = 0x175,
/// <summary>
/// Intel Itanium processor family
/// </summary>
IMAGE_FILE_MACHINE_IA64 = 0x200,
/// <summary>
/// Mitsubishi M32R little endian
/// </summary>
IMAGE_FILE_MACHINE_M32R = 0x9041,
/// <summary>
/// Motorola 68000 series
/// </summary>
IMAGE_FILE_MACHINE_M68K = 0x268,
/// <summary>
/// Motorola 68000 series
/// </summary>
IMAGE_FILE_MACHINE_M68K_OTHER = 0x150,
/// <summary>
/// MIPS16
/// </summary>
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
/// <summary>
/// MIPS with FPU
/// </summary>
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
/// <summary>
/// MIPS16 with FPU
/// </summary>
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
/// <summary>
/// PowerPC little endian
/// </summary>
IMAGE_FILE_MACHINE_POWERPC = 0x1f0,
/// <summary>
/// Power PC with floating point support
/// </summary>
IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1,
/// <summary>
/// MIPS big endian
/// </summary>
IMAGE_FILE_MACHINE_MIPSEB = 0x160,
/// <summary>
/// MIPS little endian
/// </summary>
IMAGE_FILE_MACHINE_R3000 = 0x162,
/// <summary>
/// MIPS little endian
/// </summary>
IMAGE_FILE_MACHINE_R4000 = 0x166,
/// <summary>
/// MIPS little endian
/// </summary>
IMAGE_FILE_MACHINE_R10000 = 0x168,
/// <summary>
/// RISC-V 32-bit address space
/// </summary>
IMAGE_FILE_MACHINE_RISCV32 = 0x5032,
/// <summary>
/// RISC-V 64-bit address space
/// </summary>
IMAGE_FILE_MACHINE_RISCV64 = 0x5064,
/// <summary>
/// RISC-V 128-bit address space
/// </summary>
IMAGE_FILE_MACHINE_RISCV128 = 0x5128,
/// <summary>
/// Hitachi SH3
/// </summary>
IMAGE_FILE_MACHINE_SH3 = 0x1a2,
/// <summary>
/// Hitachi SH3 DSP
/// </summary>
IMAGE_FILE_MACHINE_SH3DSP = 0x1a3,
/// <summary>
/// Hitachi SH4
/// </summary>
IMAGE_FILE_MACHINE_SH4 = 0x1a6,
/// <summary>
/// Hitachi SH5
/// </summary>
IMAGE_FILE_MACHINE_SH5 = 0x1a8,
/// <summary>
/// Thumb
/// </summary>
IMAGE_FILE_MACHINE_THUMB = 0x1c2,
/// <summary>
/// MIPS little-endian WCE v2
/// </summary>
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169,
/// <summary>
/// WE32000
/// </summary>
IMAGE_FILE_MACHINE_WE32000 = 0x170
} }
public const uint IMAGE_SCN_ALIGN_MASK = 0x00F00000;
[Flags] [Flags]
public enum SectionFlags : uint public enum SectionFlags : uint
{ {
/// <summary> /// <summary>
/// Reserved for future use. /// Reserved for future use.
/// </summary> /// </summary>
IMAGE_SCN_TYPE_DSECT=0x00000001, IMAGE_SCN_TYPE_DSECT = 0x00000001,
/// <summary> /// <summary>
/// Reserved for future use. /// Reserved for future use.
/// </summary> /// </summary>
IMAGE_SCN_TYPE_NOLOAD=0x00000002, IMAGE_SCN_TYPE_NOLOAD = 0x00000002,
/// <summary> /// <summary>
/// Reserved for future use. /// Reserved for future use.
/// </summary> /// </summary>
IMAGE_SCN_TYPE_GROUP=0x00000004, IMAGE_SCN_TYPE_GROUP = 0x00000004,
/// <summary> /// <summary>
/// Section should not be padded to next boundary. /// Section should not be padded to next boundary.
/// This is obsolete and replaced by <see cref="IMAGE_SCN_ALIGN_1BYTES"/>. /// This is obsolete and replaced by <see cref="IMAGE_SCN_ALIGN_1BYTES" />.
/// This is valid for object files only. /// This is valid for object files only.
/// </summary> /// </summary>
IMAGE_SCN_TYPE_NO_PAD=0x00000008, IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
/// <summary> /// <summary>
/// Reserved for future use. /// Reserved for future use.
/// </summary> /// </summary>
IMAGE_SCN_TYPE_COPY=0x00000010, IMAGE_SCN_TYPE_COPY = 0x00000010,
/// <summary> /// <summary>
/// Section contains executable code. /// Section contains executable code.
/// </summary> /// </summary>
IMAGE_SCN_CNT_CODE=0x00000020, IMAGE_SCN_CNT_CODE = 0x00000020,
/// <summary> /// <summary>
/// Section contains initialized data. /// Section contains initialized data.
/// </summary> /// </summary>
IMAGE_SCN_CNT_INITIALIZED_DATA=0x00000040, IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
/// <summary> /// <summary>
/// Section contains uninitialized data. /// Section contains uninitialized data.
/// </summary> /// </summary>
IMAGE_SCN_CNT_UNINITIALIZED_DATA=0x00000080, IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
/// <summary> /// <summary>
/// Reserved for future use. /// Reserved for future use.
/// </summary> /// </summary>
IMAGE_SCN_LNK_OTHER=0x00000100, IMAGE_SCN_LNK_OTHER = 0x00000100,
/// <summary> /// <summary>
/// Section contains comments or other information. The .drectve section has this type. This is valid for object files only. /// Section contains comments or other information. The .drectve section has this type. This is valid for object files
/// </summary> /// only.
IMAGE_SCN_LNK_INFO=0x00000200, /// </summary>
/// <summary> IMAGE_SCN_LNK_INFO = 0x00000200,
/// Reserved for future use. /// <summary>
/// </summary> /// Reserved for future use.
IMAGE_SCN_TYPE_OVER=0x00000400, /// </summary>
/// <summary> IMAGE_SCN_TYPE_OVER = 0x00000400,
/// Section will not become part of the image. This is valid for object files only. /// <summary>
/// </summary> /// Section will not become part of the image. This is valid for object files only.
IMAGE_SCN_LNK_REMOVE=0x00000800, /// </summary>
/// <summary> IMAGE_SCN_LNK_REMOVE = 0x00000800,
/// Section contains COMDAT data. This is valid for object files only. /// <summary>
/// </summary> /// Section contains COMDAT data. This is valid for object files only.
IMAGE_SCN_LNK_COMDAT=0x00001000, /// </summary>
/// <summary> IMAGE_SCN_LNK_COMDAT = 0x00001000,
/// Reserved for future use. /// <summary>
/// </summary> /// Reserved for future use.
IMAGE_SCN_MEM_FARDATA=0x00008000, /// </summary>
/// <summary> IMAGE_SCN_MEM_FARDATA = 0x00008000,
/// Reserved for future use. /// <summary>
/// </summary> /// Reserved for future use.
IMAGE_SCN_MEM_16BIT =0x00020000, /// </summary>
/// <summary> IMAGE_SCN_MEM_16BIT = 0x00020000,
/// Reserved for future use. /// <summary>
/// </summary> /// Reserved for future use.
IMAGE_SCN_MEM_LOCKED=0x00040000, /// </summary>
/// <summary> IMAGE_SCN_MEM_LOCKED = 0x00040000,
/// Reserved for future use. /// <summary>
/// </summary> /// Reserved for future use.
IMAGE_SCN_MEM_PRELOAD=0x00080000, /// </summary>
/// <summary> IMAGE_SCN_MEM_PRELOAD = 0x00080000,
/// Align data on a 1-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 1-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_1BYTES=0x00100000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
/// Align data on a 2-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 2-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_2BYTES=0x00200000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
/// Align data on a 4-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 4-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_4BYTES=0x00300000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
/// Align data on a 8-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 8-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_8BYTES=0x00400000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
/// Align data on a 16-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 16-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_16BYTES=0x00500000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
/// Align data on a 32-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 32-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_32BYTES=0x00600000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
/// Align data on a 64-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 64-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_64BYTES=0x00700000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
/// Align data on a 128-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 128-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_128BYTES=0x00800000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
/// Align data on a 256-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 256-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_256BYTES=0x00900000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
/// Align data on a 512-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 512-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_512BYTES=0x00A00000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
/// Align data on a 1024-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 1024-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_1024BYTES=0x00B00000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
/// Align data on a 2048-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 2048-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_2048BYTES=0x00C00000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
/// Align data on a 4096-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 4096-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_4096BYTES=0x00D00000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
/// Align data on a 8192-byte boundary. This is valid for object files only. /// <summary>
/// </summary> /// Align data on a 8192-byte boundary. This is valid for object files only.
IMAGE_SCN_ALIGN_8192BYTES=0x00E00000, /// </summary>
/// <summary> IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
/// Section contains extended relocations. /// <summary>
/// </summary> /// Section contains extended relocations.
IMAGE_SCN_LNK_NRELOC_OVFL=0x01000000, /// </summary>
/// <summary> IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
/// Section can be discarded as needed. /// <summary>
/// </summary> /// Section can be discarded as needed.
IMAGE_SCN_MEM_DISCARDABLE=0x02000000, /// </summary>
/// <summary> IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
/// Section cannot be cached. /// <summary>
/// </summary> /// Section cannot be cached.
IMAGE_SCN_MEM_NOT_CACHED=0x04000000, /// </summary>
/// <summary> IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
/// Section is not pageable. /// <summary>
/// </summary> /// Section is not pageable.
IMAGE_SCN_MEM_NOT_PAGED=0x08000000, /// </summary>
/// <summary> IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
/// Section can be shared in memory. /// <summary>
/// </summary> /// Section can be shared in memory.
IMAGE_SCN_MEM_SHARED=0x10000000, /// </summary>
/// <summary> IMAGE_SCN_MEM_SHARED = 0x10000000,
/// Section can be executed as code. /// <summary>
/// </summary> /// Section can be executed as code.
IMAGE_SCN_MEM_EXECUTE=0x20000000, /// </summary>
/// <summary> IMAGE_SCN_MEM_EXECUTE = 0x20000000,
/// Section can be read. /// <summary>
/// </summary> /// Section can be read.
IMAGE_SCN_MEM_READ=0x40000000, /// </summary>
/// <summary> IMAGE_SCN_MEM_READ = 0x40000000,
/// Section can be written to. /// <summary>
/// </summary> /// Section can be written to.
IMAGE_SCN_MEM_WRITE=0x80000000 /// </summary>
IMAGE_SCN_MEM_WRITE = 0x80000000
} }
public const uint IMAGE_SCN_ALIGN_MASK = 0x00F00000;
} }
} }

View File

@@ -25,97 +25,99 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
namespace libexeinfo namespace libexeinfo
{ {
public partial class COFF public partial class COFF
{ {
public static string GetInfo(COFFHeader header) public 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();
sb.AppendLine("Common Object File Format (COFF):"); sb.AppendLine("Common Object File Format (COFF):");
switch (header.optionalHeader.magic) switch(header.optionalHeader.magic)
{ {
case JMAGIC: case JMAGIC:
sb.AppendLine("\tExecutable is dirty and unshareable"); sb.AppendLine("\tExecutable is dirty and unshareable");
break; break;
case DMAGIC: case DMAGIC:
sb.AppendLine("\tExecutable is dirty, data is aligned"); sb.AppendLine("\tExecutable is dirty, data is aligned");
break; break;
case ZMAGIC: case ZMAGIC:
sb.AppendLine("\tNormal executable"); sb.AppendLine("\tNormal executable");
break; break;
case SHMAGIC: case SHMAGIC:
sb.AppendLine("\tShared library"); sb.AppendLine("\tShared library");
break; break;
case PE.PE32Plus: case PE.PE32Plus:
sb.AppendLine("\tPE32+ executable"); sb.AppendLine("\tPE32+ executable");
break; break;
default: default:
sb.AppendFormat("\tUnknown executable type with magic {0}", header.optionalHeader.magic).AppendLine(); sb.AppendFormat("\tUnknown executable type with magic {0}", header.optionalHeader.magic)
break; .AppendLine();
} break;
}
sb.AppendFormat("\tMachine: {0}", MachineTypeToString(header.machine)).AppendLine(); sb.AppendFormat("\tMachine: {0}", MachineTypeToString(header.machine)).AppendLine();
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)) if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_EXECUTABLE_IMAGE))
sb.AppendLine("\tExecutable is valid."); sb.AppendLine("\tExecutable is valid.");
else else sb.AppendLine("\tExecutable is invalid, contains errors or has not been linked correctly.");
sb.AppendLine("\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)) sb.AppendLine("\tExecutable contains debug symbols.");
sb.AppendLine("\tExecutable contains debug symbols."); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_AGGRESSIVE_WS_TRIM))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_AGGRESSIVE_WS_TRIM)) sb.AppendLine("\tWorking set should be aggressively trimmed");
sb.AppendLine("\tWorking set should be aggressively trimmed"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_LARGE_ADDRESS_AWARE))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_LARGE_ADDRESS_AWARE)) sb.AppendLine("\tExecutable can handle addresses bigger than 2GiB");
sb.AppendLine("\tExecutable can handle addresses bigger than 2GiB"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_16BIT_MACHINE))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_16BIT_MACHINE)) sb.AppendLine("\tExecutable is for a 16-bit per word machine");
sb.AppendLine("\tExecutable is for a 16-bit per word machine"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_BYTES_REVERSED_LO))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_BYTES_REVERSED_LO)) sb.AppendLine("\tExecutable is little-endian");
sb.AppendLine("\tExecutable is little-endian"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_32BIT_MACHINE))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_32BIT_MACHINE)) sb.AppendLine("\tExecutable is for a 32-bit per word machine");
sb.AppendLine("\tExecutable is for a 32-bit per word machine"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_DEBUG_STRIPPED))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_DEBUG_STRIPPED)) sb.AppendLine("\tDebug information has been removed");
sb.AppendLine("\tDebug information has been removed"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP)) sb.AppendLine("\tWhen executable is run from removable media, it should be copied to swap and run from there");
sb.AppendLine("\tWhen executable is run from removable media, it should be copied to swap and run from there"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_NET_RUN_FROM_SWAP))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_NET_RUN_FROM_SWAP)) sb.AppendLine("\tWhen executable is run from a network share, it should be copied to swap and run from there");
sb.AppendLine("\tWhen executable is run from a network share, it should be copied to swap and run from there"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_SYSTEM))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_SYSTEM)) sb.AppendLine("\tExecutable is a system file");
sb.AppendLine("\tExecutable is a system file"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_DLL))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_DLL)) sb.AppendLine("\tExecutable is a dynamically linkable library");
sb.AppendLine("\tExecutable is a dynamically linkable library"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_UP_SYSTEM_ONLY))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_UP_SYSTEM_ONLY)) sb.AppendLine("\tExecutable can only run on uniprocessor machines");
sb.AppendLine("\tExecutable can only run on uniprocessor machines"); if(header.characteristics.HasFlag(Characteristics.IMAGE_FILE_BYTES_REVERSED_HI))
if (header.characteristics.HasFlag(Characteristics.IMAGE_FILE_BYTES_REVERSED_HI)) sb.AppendLine("\tExecutable is big-endian");
sb.AppendLine("\tExecutable is big-endian");
sb.AppendFormat("\tExecutable has {0} sections", header.numberOfSections).AppendLine(); sb.AppendFormat("\tExecutable has {0} sections", header.numberOfSections).AppendLine();
sb.AppendFormat("\tExecutable was linked on {0}", epoch.AddSeconds(header.timeDateStamp)).AppendLine(); sb.AppendFormat("\tExecutable was linked on {0}", epoch.AddSeconds(header.timeDateStamp)).AppendLine();
sb.AppendFormat("\tSymbol table starts at {0} and contains {1} symbols", header.pointerToSymbolTable, header.numberOfSymbols).AppendLine(); sb.AppendFormat("\tSymbol table starts at {0} and contains {1} symbols", header.pointerToSymbolTable,
sb.AppendFormat("\tOptional header has {0} bytes", header.sizeOfOptionalHeader).AppendLine(); header.numberOfSymbols).AppendLine();
sb.AppendFormat("\tOptional header has {0} bytes", header.sizeOfOptionalHeader).AppendLine();
if(header.optionalHeader.majorLinkerVersion > 0 || header.optionalHeader.minorLinkerVersion > 0) if(header.optionalHeader.majorLinkerVersion > 0 || header.optionalHeader.minorLinkerVersion > 0)
sb.AppendFormat("\tLinker version: {0}.{1}", header.optionalHeader.majorLinkerVersion, header.optionalHeader.minorLinkerVersion).AppendLine(); sb.AppendFormat("\tLinker version: {0}.{1}", header.optionalHeader.majorLinkerVersion,
sb.AppendFormat("\tCode has {0} bytes", header.optionalHeader.sizeOfCode).AppendLine(); header.optionalHeader.minorLinkerVersion).AppendLine();
sb.AppendFormat("\tInitialized data has {0} bytes", header.optionalHeader.sizeOfInitializedData).AppendLine(); sb.AppendFormat("\tCode has {0} bytes", header.optionalHeader.sizeOfCode).AppendLine();
sb.AppendFormat("\tUninitialized data has {0} bytes", header.optionalHeader.sizeOfUninitializedData).AppendLine(); sb.AppendFormat("\tInitialized data has {0} bytes", header.optionalHeader.sizeOfInitializedData)
sb.AppendFormat("\tAddress point starts at {0}", header.optionalHeader.addressOfEntryPoint).AppendLine(); .AppendLine();
sb.AppendFormat("\tCode starts at {0}", header.optionalHeader.baseOfCode).AppendLine(); sb.AppendFormat("\tUninitialized data has {0} bytes", header.optionalHeader.sizeOfUninitializedData)
if (header.optionalHeader.magic != PE.PE32Plus) .AppendLine();
sb.AppendFormat("\tAddress point starts at {0}", header.optionalHeader.addressOfEntryPoint).AppendLine();
sb.AppendFormat("\tCode starts at {0}", header.optionalHeader.baseOfCode).AppendLine();
if(header.optionalHeader.magic != PE.PE32Plus)
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() public string GetInfo()
{ {
return GetInfo(Header); return GetInfo(Header);
} }
} }
} }

View File

@@ -30,79 +30,47 @@ namespace libexeinfo
{ {
public static string MachineTypeToString(MachineTypes machine) public static string MachineTypeToString(MachineTypes machine)
{ {
switch (machine) switch(machine)
{ {
case MachineTypes.IMAGE_FILE_MACHINE_UNKNOWN: case MachineTypes.IMAGE_FILE_MACHINE_UNKNOWN: return "Any machine";
return "Any machine"; case MachineTypes.IMAGE_FILE_MACHINE_ALPHA: return "Alpha AXP";
case MachineTypes.IMAGE_FILE_MACHINE_ALPHA: case MachineTypes.IMAGE_FILE_MACHINE_ALPHA64: return "Alpha AXP 64-bit.";
return "Alpha AXP"; case MachineTypes.IMAGE_FILE_MACHINE_AM33: return "Matsushita AM33";
case MachineTypes.IMAGE_FILE_MACHINE_ALPHA64: case MachineTypes.IMAGE_FILE_MACHINE_AMD64: return "AMD64 / EM64T";
return "Alpha AXP 64-bit."; case MachineTypes.IMAGE_FILE_MACHINE_ARM: return "ARM little endian";
case MachineTypes.IMAGE_FILE_MACHINE_AM33: case MachineTypes.IMAGE_FILE_MACHINE_ARM64: return "ARM64 little endian";
return "Matsushita AM33"; case MachineTypes.IMAGE_FILE_MACHINE_ARMNT: return "ARM Thumb-2 little endian";
case MachineTypes.IMAGE_FILE_MACHINE_AMD64: case MachineTypes.IMAGE_FILE_MACHINE_EBC: return "EFI byte code";
return "AMD64 / EM64T";
case MachineTypes.IMAGE_FILE_MACHINE_ARM:
return "ARM little endian";
case MachineTypes.IMAGE_FILE_MACHINE_ARM64:
return "ARM64 little endian";
case MachineTypes.IMAGE_FILE_MACHINE_ARMNT:
return "ARM Thumb-2 little endian";
case MachineTypes.IMAGE_FILE_MACHINE_EBC:
return "EFI byte code";
case MachineTypes.IMAGE_FILE_MACHINE_I386: case MachineTypes.IMAGE_FILE_MACHINE_I386:
case MachineTypes.IMAGE_FILE_MACHINE_I386_AIX: case MachineTypes.IMAGE_FILE_MACHINE_I386_AIX:
return "Intel 386 or later processors and compatible processors"; return "Intel 386 or later processors and compatible processors";
case MachineTypes.IMAGE_FILE_MACHINE_IA64: case MachineTypes.IMAGE_FILE_MACHINE_IA64: return "Intel Itanium processor family";
return "Intel Itanium processor family"; case MachineTypes.IMAGE_FILE_MACHINE_M32R: return "Mitsubishi M32R little endian";
case MachineTypes.IMAGE_FILE_MACHINE_M32R:
return "Mitsubishi M32R little endian";
case MachineTypes.IMAGE_FILE_MACHINE_M68K: case MachineTypes.IMAGE_FILE_MACHINE_M68K:
case MachineTypes.IMAGE_FILE_MACHINE_M68K_OTHER: case MachineTypes.IMAGE_FILE_MACHINE_M68K_OTHER: return "Motorola 68000 series";
return "Motorola 68000 series"; case MachineTypes.IMAGE_FILE_MACHINE_MIPS16: return "MIPS16";
case MachineTypes.IMAGE_FILE_MACHINE_MIPS16: case MachineTypes.IMAGE_FILE_MACHINE_MIPSFPU: return "MIPS with FPU";
return "MIPS16"; case MachineTypes.IMAGE_FILE_MACHINE_MIPSFPU16: return "MIPS16 with FPU";
case MachineTypes.IMAGE_FILE_MACHINE_MIPSFPU: case MachineTypes.IMAGE_FILE_MACHINE_POWERPC: return "PowerPC little endian";
return "MIPS with FPU"; case MachineTypes.IMAGE_FILE_MACHINE_POWERPCFP: return "PowerPC with floating point support";
case MachineTypes.IMAGE_FILE_MACHINE_MIPSFPU16: case MachineTypes.IMAGE_FILE_MACHINE_MIPSEB: return "MIPS R3000 or later (big endian)";
return "MIPS16 with FPU"; case MachineTypes.IMAGE_FILE_MACHINE_R3000: return "MIPS R3000 or later (little endian)";
case MachineTypes.IMAGE_FILE_MACHINE_POWERPC: case MachineTypes.IMAGE_FILE_MACHINE_R4000: return "MIPS R4000 or later (little endian)";
return "PowerPC little endian"; case MachineTypes.IMAGE_FILE_MACHINE_R10000: return "MIPS R10000 or later (little endian)";
case MachineTypes.IMAGE_FILE_MACHINE_POWERPCFP: case MachineTypes.IMAGE_FILE_MACHINE_RISCV32: return "RISC-V 32-bit address space";
return "PowerPC with floating point support"; case MachineTypes.IMAGE_FILE_MACHINE_RISCV64: return "RISC-V 64-bit address space";
case MachineTypes.IMAGE_FILE_MACHINE_MIPSEB: case MachineTypes.IMAGE_FILE_MACHINE_RISCV128: return "RISC-V 128-bit address space";
return "MIPS R3000 or later (big endian)"; case MachineTypes.IMAGE_FILE_MACHINE_SH3: return "Hitachi SH3";
case MachineTypes.IMAGE_FILE_MACHINE_R3000: case MachineTypes.IMAGE_FILE_MACHINE_SH3DSP: return "Hitachi SH3 DSP";
return "MIPS R3000 or later (little endian)"; case MachineTypes.IMAGE_FILE_MACHINE_SH4: return "Hitachi SH4";
case MachineTypes.IMAGE_FILE_MACHINE_R4000: case MachineTypes.IMAGE_FILE_MACHINE_SH5: return "Hitachi SH5";
return "MIPS R4000 or later (little endian)"; case MachineTypes.IMAGE_FILE_MACHINE_THUMB: return "ARM Thumb";
case MachineTypes.IMAGE_FILE_MACHINE_R10000: case MachineTypes.IMAGE_FILE_MACHINE_WCEMIPSV2: return "MIPS little-endian WCE v2";
return "MIPS R10000 or later (little endian)"; case MachineTypes.IMAGE_FILE_MACHINE_CLIPPER: return "Clipper";
case MachineTypes.IMAGE_FILE_MACHINE_RISCV32: case MachineTypes.IMAGE_FILE_MACHINE_WE32000: return "WE32000 series";
return "RISC-V 32-bit address space";
case MachineTypes.IMAGE_FILE_MACHINE_RISCV64:
return "RISC-V 64-bit address space";
case MachineTypes.IMAGE_FILE_MACHINE_RISCV128:
return "RISC-V 128-bit address space";
case MachineTypes.IMAGE_FILE_MACHINE_SH3:
return "Hitachi SH3";
case MachineTypes.IMAGE_FILE_MACHINE_SH3DSP:
return "Hitachi SH3 DSP";
case MachineTypes.IMAGE_FILE_MACHINE_SH4:
return "Hitachi SH4";
case MachineTypes.IMAGE_FILE_MACHINE_SH5:
return "Hitachi SH5";
case MachineTypes.IMAGE_FILE_MACHINE_THUMB:
return "ARM Thumb";
case MachineTypes.IMAGE_FILE_MACHINE_WCEMIPSV2:
return "MIPS little-endian WCE v2";
case MachineTypes.IMAGE_FILE_MACHINE_CLIPPER:
return "Clipper";
case MachineTypes.IMAGE_FILE_MACHINE_WE32000:
return "WE32000 series";
default: default:
return string.Format("Unknown machine type with code {0}", (ushort)machine); return string.Format("Unknown machine type with code {0}", (ushort)machine);
} }
} }
} }
} }

View File

@@ -24,7 +24,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
@@ -32,151 +31,161 @@ namespace libexeinfo
// TODO: Tru64 COFF is slightly different // TODO: Tru64 COFF is slightly different
public partial class COFF public partial class COFF
{ {
/// <summary> /// <summary>
/// At the beginning of an object file, or immediately after the signature of an image file, is a standard COFF file header in the following format. Note that the Windows loader limits the number of sections to 96. /// At the beginning of an object file, or immediately after the signature of an image file, is a standard COFF file
/// </summary> /// header in the following format. Note that the Windows loader limits the number of sections to 96.
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] /// </summary>
public struct COFFHeader [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
{ public struct COFFHeader
/// <summary>
/// The number that identifies the type of target machine. For more information, <see cref="MachineTypes"/>.
/// </summary>
public MachineTypes machine;
/// <summary>
/// The number of sections. This indicates the size of the section table, which immediately follows the headers.
/// </summary>
public ushort numberOfSections;
/// <summary>
/// The low 32 bits of the number of seconds since 00:00 January 1, 1970 (a C run-time time_t value), that indicates when the file was created.
/// </summary>
public uint timeDateStamp;
/// <summary>
/// The file offset of the COFF symbol table, or zero if no COFF symbol table is present. This value should be zero for an image because COFF debugging information is deprecated.
/// </summary>
public uint pointerToSymbolTable;
/// <summary>
/// The number of entries in the symbol table. This data can be used to locate the string table, which immediately follows the symbol table. This value should be zero for an image because COFF debugging information is deprecated.
/// </summary>
public uint numberOfSymbols;
public ushort sizeOfOptionalHeader;
/// <summary>
/// The flags that indicate the attributes of the file. For specific flag values, <see cref="Characteristics"/>
/// </summary>
public Characteristics characteristics;
public OptionalHeader optionalHeader;
}
/// <summary>
/// The first eight fields of the optional header are standard fields that are defined for every implementation of COFF. These fields contain general information that is useful for loading and running an executable file. They are unchanged for the PE32+ format.
/// </summary>
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)]
public struct OptionalHeader
{ {
/// <summary> /// <summary>
/// The unsigned integer that identifies the state of the image file. The most common number is 0x10B, which identifies it as a normal executable file. 0x107 identifies it as a ROM image, and 0x20B identifies it as a PE32+ executable. /// The number that identifies the type of target machine. For more information, <see cref="MachineTypes" />.
/// </summary> /// </summary>
public ushort magic; public MachineTypes machine;
/// <summary> /// <summary>
/// The linker major version number. /// The number of sections. This indicates the size of the section table, which immediately follows the headers.
/// </summary> /// </summary>
public byte majorLinkerVersion; public ushort numberOfSections;
/// <summary> /// <summary>
/// The linker minor version number. /// The low 32 bits of the number of seconds since 00:00 January 1, 1970 (a C run-time time_t value), that indicates
/// </summary> /// when the file was created.
public byte minorLinkerVersion; /// </summary>
/// <summary> public uint timeDateStamp;
/// The size of the code (text) section, or the sum of all code sections if there are multiple sections. /// <summary>
/// </summary> /// The file offset of the COFF symbol table, or zero if no COFF symbol table is present. This value should be zero for
public uint sizeOfCode; /// an image because COFF debugging information is deprecated.
/// <summary> /// </summary>
/// The size of the initialized data section, or the sum of all such sections if there are multiple data sections. public uint pointerToSymbolTable;
/// </summary> /// <summary>
public uint sizeOfInitializedData; /// The number of entries in the symbol table. This data can be used to locate the string table, which immediately
/// <summary> /// follows the symbol table. This value should be zero for an image because COFF debugging information is deprecated.
/// The size of the uninitialized data section (BSS), or the sum of all such sections if there are multiple BSS sections. /// </summary>
/// </summary> public uint numberOfSymbols;
public uint sizeOfUninitializedData; public ushort sizeOfOptionalHeader;
/// <summary> /// <summary>
/// The address of the entry point relative to the image base when the executable file is loaded into memory. For program images, this is the starting address. For device drivers, this is the address of the initialization function. An entry point is optional for DLLs. When no entry point is present, this field must be zero. /// The flags that indicate the attributes of the file. For specific flag values, <see cref="Characteristics" />
/// </summary> /// </summary>
public uint addressOfEntryPoint; public Characteristics characteristics;
/// <summary> public OptionalHeader optionalHeader;
/// The address that is relative to the image base of the beginning-of-code section when it is loaded into memory.
/// </summary>
public uint baseOfCode;
/// <summary>
/// PE32 contains this additional field, which is absent in PE32+, following BaseOfCode.<br/>
/// The address that is relative to the image base of the beginning-of-data section when it is loaded into memory.
/// </summary>
public uint baseOfData;
} }
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] /// <summary>
/// The first eight fields of the optional header are standard fields that are defined for every implementation of
/// COFF. These fields contain general information that is useful for loading and running an executable file. They are
/// unchanged for the PE32+ format.
/// </summary>
[StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct OptionalHeader
{
/// <summary>
/// The unsigned integer that identifies the state of the image file. The most common number is 0x10B, which identifies
/// it as a normal executable file. 0x107 identifies it as a ROM image, and 0x20B identifies it as a PE32+ executable.
/// </summary>
public ushort magic;
/// <summary>
/// The linker major version number.
/// </summary>
public byte majorLinkerVersion;
/// <summary>
/// The linker minor version number.
/// </summary>
public byte minorLinkerVersion;
/// <summary>
/// The size of the code (text) section, or the sum of all code sections if there are multiple sections.
/// </summary>
public uint sizeOfCode;
/// <summary>
/// The size of the initialized data section, or the sum of all such sections if there are multiple data sections.
/// </summary>
public uint sizeOfInitializedData;
/// <summary>
/// The size of the uninitialized data section (BSS), or the sum of all such sections if there are multiple BSS
/// sections.
/// </summary>
public uint sizeOfUninitializedData;
/// <summary>
/// The address of the entry point relative to the image base when the executable file is loaded into memory. For
/// program images, this is the starting address. For device drivers, this is the address of the initialization
/// function. An entry point is optional for DLLs. When no entry point is present, this field must be zero.
/// </summary>
public uint addressOfEntryPoint;
/// <summary>
/// The address that is relative to the image base of the beginning-of-code section when it is loaded into memory.
/// </summary>
public uint baseOfCode;
/// <summary>
/// PE32 contains this additional field, which is absent in PE32+, following BaseOfCode.<br />
/// The address that is relative to the image base of the beginning-of-data section when it is loaded into memory.
/// </summary>
public uint baseOfData;
}
[StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct SectionHeader public struct SectionHeader
{ {
/// <summary> /// <summary>
/// An 8-byte, null-padded ASCII string. There is no terminating null if the string is /// An 8-byte, null-padded ASCII string. There is no terminating null if the string is
/// exactly eight characters long. For longer names, this field contains a slash(/) /// exactly eight characters long. For longer names, this field contains a slash(/)
/// followed by ASCII representation of a decimal number: this number is an offset into /// followed by ASCII representation of a decimal number: this number is an offset into
/// the string table.Executable images do not use a string table and do not support /// the string table.Executable images do not use a string table and do not support
/// section names longer than eight characters. Long names in object files will be /// section names longer than eight characters. Long names in object files will be
/// truncated if emitted to an executable file. /// truncated if emitted to an executable file.
/// </summary> /// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string name; public string name;
/// <summary> /// <summary>
/// Total size of the section when loaded into memory. If this value is greater than /// Total size of the section when loaded into memory. If this value is greater than
/// <see cref="sizeOfRawData"/>, the section is zero-padded.This field is valid only /// <see cref="sizeOfRawData" />, the section is zero-padded.This field is valid only
/// for executable images and should be set to 0 for object files. /// for executable images and should be set to 0 for object files.
/// </summary> /// </summary>
public uint virtualSize; public uint virtualSize;
/// <summary> /// <summary>
/// For executable images this is the address of the first byte of the section, when /// For executable images this is the address of the first byte of the section, when
/// loaded into memory, relative to the image base. For object files, this field is /// loaded into memory, relative to the image base. For object files, this field is
/// the address of the first byte before relocation is applied; for simplicity, /// the address of the first byte before relocation is applied; for simplicity,
/// compilers should set this to zero. Otherwise, it is an arbitrary value that is /// compilers should set this to zero. Otherwise, it is an arbitrary value that is
/// subtracted from offsets during relocation. /// subtracted from offsets during relocation.
/// </summary> /// </summary>
public uint virtualAddress; public uint virtualAddress;
/// <summary> /// <summary>
/// Size of the section (object file) or size of the initialized data on disk(image /// Size of the section (object file) or size of the initialized data on disk(image
/// files). For executable image, this must be a multiple of FileAlignment from the /// files). For executable image, this must be a multiple of FileAlignment from the
/// optional header.If this is less than <see cref="virtualSize"/> the remainder of /// optional header.If this is less than <see cref="virtualSize" /> the remainder of
/// the section is zero filled. Because this field is rounded while the /// the section is zero filled. Because this field is rounded while the
/// <see cref="virtualSize"/> field is not it is possible for this to be greater /// <see cref="virtualSize" /> field is not it is possible for this to be greater
/// than <see cref="virtualSize"/> as well.When a section contains only /// than <see cref="virtualSize" /> as well.When a section contains only
/// uninitialized data, this field should be 0. /// uninitialized data, this field should be 0.
/// </summary> /// </summary>
public uint sizeOfRawData; public uint sizeOfRawData;
/// <summary> /// <summary>
/// File pointer to sectionís first page within the COFF file. For executable images, /// File pointer to sectionís first page within the COFF file. For executable images,
/// this must be a multiple of FileAlignment from the optional header. For object /// this must be a multiple of FileAlignment from the optional header. For object
/// files, the value should be aligned on a four-byte boundary for best performance. /// files, the value should be aligned on a four-byte boundary for best performance.
/// When a section contains only uninitialized data, this field should be 0. /// When a section contains only uninitialized data, this field should be 0.
/// </summary> /// </summary>
public uint pointerToRawData; public uint pointerToRawData;
/// <summary> /// <summary>
/// File pointer to beginning of relocation entries for the section. Set to 0 for /// File pointer to beginning of relocation entries for the section. Set to 0 for
/// executable images or if there are no relocations. /// executable images or if there are no relocations.
/// </summary> /// </summary>
public uint pointerToRelocations; public uint pointerToRelocations;
/// <summary> /// <summary>
/// File pointer to beginning of line-number entries for the section.Set to 0 if /// File pointer to beginning of line-number entries for the section.Set to 0 if
/// there are no COFF line numbers. /// there are no COFF line numbers.
/// </summary> /// </summary>
public uint pointerToLineNumbers; public uint pointerToLineNumbers;
/// <summary> /// <summary>
/// Number of relocation entries for the section. Set to 0 for executable images. /// Number of relocation entries for the section. Set to 0 for executable images.
/// </summary> /// </summary>
public ushort numberOfRelocations; public ushort numberOfRelocations;
/// <summary> /// <summary>
/// Number of line-number entries for the section. /// Number of line-number entries for the section.
/// </summary> /// </summary>
public ushort numberOfLineNumbers; public ushort numberOfLineNumbers;
/// <summary> /// <summary>
/// Flags describing sectionís characteristics. <see cref="SectionFlags"/> /// Flags describing sectionís characteristics. <see cref="SectionFlags" />
/// </summary> /// </summary>
public SectionFlags characteristics; public SectionFlags characteristics;
} }
} }
} }

View File

@@ -24,18 +24,17 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class LX public partial class LX
{ {
/// <summary> /// <summary>
/// Linear Executable signature, "LE" /// Linear Executable signature, "LE"
/// </summary> /// </summary>
public const ushort Signature16 = 0x454C; public const ushort Signature16 = 0x454C;
/// <summary> /// <summary>
/// Linear eXecutable signature, "LX" /// Linear eXecutable signature, "LX"
/// </summary> /// </summary>
public const ushort Signature = 0x584C; public const ushort Signature = 0x584C;
} }
} }

View File

@@ -25,90 +25,91 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class LX public partial class LX
{ {
/// <summary> /// <summary>
/// Executable module flags. /// Executable module flags.
/// </summary> /// </summary>
[Flags] [Flags]
public enum ModuleFlags : uint public enum ModuleFlags : uint
{ {
/// <summary> /// <summary>
/// Per-Process Library Initialization /// Per-Process Library Initialization
/// </summary> /// </summary>
PerProcessLibrary = 0x04, PerProcessLibrary = 0x04,
/// <summary> /// <summary>
/// Internal fixups for the module have been applied /// Internal fixups for the module have been applied
/// </summary> /// </summary>
InternalFixups = 0x10, InternalFixups = 0x10,
/// <summary> /// <summary>
/// External fixups for the module have been applied /// External fixups for the module have been applied
/// </summary> /// </summary>
ExternalFixups = 0x20, ExternalFixups = 0x20,
/// <summary> /// <summary>
/// Incompatible with Presentation Manager /// Incompatible with Presentation Manager
/// </summary> /// </summary>
PMIncompatible = 0x100, PMIncompatible = 0x100,
/// <summary> /// <summary>
/// Compatible with Presentation Manager /// Compatible with Presentation Manager
/// </summary> /// </summary>
PMCompatible = 0x200, PMCompatible = 0x200,
/// <summary> /// <summary>
/// Uses Presentation Manager /// Uses Presentation Manager
/// </summary> /// </summary>
UsesPM = 0x300, UsesPM = 0x300,
/// <summary> /// <summary>
/// Module is not loadable. Contains errors or is being linked /// Module is not loadable. Contains errors or is being linked
/// </summary> /// </summary>
NotLoadable = 0x2000, NotLoadable = 0x2000,
/// <summary> /// <summary>
/// Library module /// Library module
/// </summary> /// </summary>
Library = 0x8000, Library = 0x8000,
/// <summary> /// <summary>
/// Protected Memory Library module /// Protected Memory Library module
/// </summary> /// </summary>
ProtectedMemoryLibrary = 0x18000, ProtectedMemoryLibrary = 0x18000,
/// <summary> /// <summary>
/// Physical Device Driver module /// Physical Device Driver module
/// </summary> /// </summary>
PhysicalDeviceDriver = 0x20000, PhysicalDeviceDriver = 0x20000,
/// <summary> /// <summary>
/// Virtual Device Driver module /// Virtual Device Driver module
/// </summary> /// </summary>
VirtualDeviceDriver = 0x28000, VirtualDeviceDriver = 0x28000,
/// <summary> /// <summary>
/// Per-process Library Termination /// Per-process Library Termination
/// </summary> /// </summary>
PerProcessTermination = 0x40000000 PerProcessTermination = 0x40000000
} }
public enum TargetCpu : ushort public enum TargetCpu : ushort
{ {
Unknown = 0, Unknown = 0,
i286 = 1, i286 = 1,
i386 = 2, i386 = 2,
i486 = 3, i486 = 3,
Pentium = 4, Pentium = 4,
i860 = 0x20, i860 = 0x20,
N11 = 0x21, N11 = 0x21,
MIPS1 = 0x40, MIPS1 = 0x40,
MIPS2 = 0x41, MIPS2 = 0x41,
MIPS3 = 0x42 MIPS3 = 0x42
} }
/// <summary> /// <summary>
/// Target operating system. /// Target operating system.
/// </summary> /// </summary>
public enum TargetOS : ushort public enum TargetOS : ushort
{ {
Unknown = 0, Unknown = 0,
OS2 = 1, OS2 = 1,
Windows = 2, Windows = 2,
DOS = 3, DOS = 3,
Win32 = 4 Win32 = 4
} }
} }
} }

View File

@@ -24,158 +24,173 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
namespace libexeinfo namespace libexeinfo
{ {
public partial class LX public partial class LX
{ {
public static string GetInfo(LXHeader header) public static string GetInfo(LXHeader header)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if(header.signature == Signature16) if(header.signature == Signature16) sb.AppendLine("Linear Executable (LE):");
sb.AppendLine("Linear Executable (LE):"); else sb.AppendLine("Linear eXecutable (LX):");
if(header.os_type == TargetOS.OS2)
{
sb.AppendLine("\tOS/2 application");
if(header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
!header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is full screen, unaware of Presentation Manager");
else if(!header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is aware of Presentation Manager, but doesn't use it");
else if(header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication uses Presentation Manager");
}
else if(header.os_type == TargetOS.Windows || header.os_type == TargetOS.Win32 ||
header.os_type == TargetOS.Unknown)
{
if(header.os_type == TargetOS.Windows || header.os_type == TargetOS.Unknown)
sb.AppendLine("\t16-bit Windows application");
else if(header.os_type == TargetOS.Win32)
sb.AppendLine("\t32-bit Windows application");
if(header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
!header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is full screen, unaware of Windows");
else if(!header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is aware of Windows, but doesn't use it");
else if(header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication uses Windows");
}
else if(header.os_type == TargetOS.DOS)
{
sb.AppendLine("\tDOS application");
if(header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
!header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is full screen, unaware of Windows");
else if(!header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is aware of Windows, but doesn't use it");
else if(header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication uses Windows");
}
else else
sb.AppendLine("Linear eXecutable (LX):"); sb.AppendFormat("\tApplication for unknown OS {0}", (ushort)header.os_type).AppendLine();
if (header.os_type == TargetOS.OS2) sb.AppendFormat("\tByte ordering: {0}", header.byte_order == 1 ? "Big-endian" : "Little-Endian")
{ .AppendLine();
sb.AppendLine("\tOS/2 application"); sb.AppendFormat("\tWord ordering: {0}", header.word_order == 1 ? "Big-endian" : "Little-Endian")
if (header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && !header.module_flags.HasFlag(ModuleFlags.PMCompatible)) .AppendLine();
sb.AppendLine("\tApplication is full screen, unaware of Presentation Manager"); sb.AppendFormat("\tFormat level: {0}", header.format_level).AppendLine();
else if (!header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && header.module_flags.HasFlag(ModuleFlags.PMCompatible)) sb.AppendFormat("\tExecutable version: {0}", header.module_version).AppendLine();
sb.AppendLine("\tApplication is aware of Presentation Manager, but doesn't use it");
else if (header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication uses Presentation Manager");
}
else if (header.os_type == TargetOS.Windows || header.os_type == TargetOS.Win32 || header.os_type == TargetOS.Unknown)
{
if (header.os_type == TargetOS.Windows || header.os_type == TargetOS.Unknown)
sb.AppendLine("\t16-bit Windows application");
else if (header.os_type == TargetOS.Win32)
sb.AppendLine("\t32-bit Windows application");
if (header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && !header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is full screen, unaware of Windows");
else if (!header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is aware of Windows, but doesn't use it");
else if (header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication uses Windows");
}
else if (header.os_type == TargetOS.DOS)
{
sb.AppendLine("\tDOS application");
if (header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && !header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is full screen, unaware of Windows");
else if (!header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication is aware of Windows, but doesn't use it");
else if (header.module_flags.HasFlag(ModuleFlags.PMIncompatible) && header.module_flags.HasFlag(ModuleFlags.PMCompatible))
sb.AppendLine("\tApplication uses Windows");
}
else
{
sb.AppendFormat("\tApplication for unknown OS {0}", (ushort)header.os_type).AppendLine();
}
sb.AppendFormat("\tByte ordering: {0}", header.byte_order == 1 ? "Big-endian" : "Little-Endian").AppendLine();
sb.AppendFormat("\tWord ordering: {0}", header.word_order == 1 ? "Big-endian" : "Little-Endian").AppendLine();
sb.AppendFormat("\tFormat level: {0}", header.format_level).AppendLine();
sb.AppendFormat("\tExecutable version: {0}", header.module_version).AppendLine();
switch(header.cpu_type) switch(header.cpu_type)
{ {
case TargetCpu.i286: case TargetCpu.i286:
sb.AppendLine("\tExecutable requires at least an 80286 processor to run."); sb.AppendLine("\tExecutable requires at least an 80286 processor to run.");
break; break;
case TargetCpu.i386: case TargetCpu.i386:
sb.AppendLine("\tExecutable requires at least an 80386 processor to run."); sb.AppendLine("\tExecutable requires at least an 80386 processor to run.");
break; break;
case TargetCpu.i486: case TargetCpu.i486:
sb.AppendLine("\tExecutable requires at least an 80486 processor to run."); sb.AppendLine("\tExecutable requires at least an 80486 processor to run.");
break; break;
case TargetCpu.Pentium: case TargetCpu.Pentium:
sb.AppendLine("\tExecutable requires at least a Pentium processor to run."); sb.AppendLine("\tExecutable requires at least a Pentium processor to run.");
break; break;
case TargetCpu.i860: case TargetCpu.i860:
sb.AppendLine("\tExecutable requires at least an Intel 860 processor to run."); sb.AppendLine("\tExecutable requires at least an Intel 860 processor to run.");
break; break;
case TargetCpu.N11: case TargetCpu.N11:
sb.AppendLine("\tExecutable requires at least an Intel N11 processor to run."); sb.AppendLine("\tExecutable requires at least an Intel N11 processor to run.");
break; break;
case TargetCpu.MIPS1: case TargetCpu.MIPS1:
sb.AppendLine("\tExecutable requires at least a MIPS I processor to run."); sb.AppendLine("\tExecutable requires at least a MIPS I processor to run.");
break; break;
case TargetCpu.MIPS2: case TargetCpu.MIPS2:
sb.AppendLine("\tExecutable requires at least a MIPS II processor to run."); sb.AppendLine("\tExecutable requires at least a MIPS II processor to run.");
break; break;
case TargetCpu.MIPS3: case TargetCpu.MIPS3:
sb.AppendLine("\tExecutable requires at least a MIPS III processor to run."); sb.AppendLine("\tExecutable requires at least a MIPS III processor to run.");
break; break;
default: default:
sb.AppendFormat("\tExecutable requires unknown cpu with type code {0} to run.", (ushort)header.cpu_type).AppendLine(); sb.AppendFormat("\tExecutable requires unknown cpu with type code {0} to run.",
break; (ushort)header.cpu_type).AppendLine();
} break;
}
if (header.module_flags.HasFlag(ModuleFlags.PerProcessLibrary)) if(header.module_flags.HasFlag(ModuleFlags.PerProcessLibrary))
sb.AppendLine("Library should be initialized per-process."); sb.AppendLine("Library should be initialized per-process.");
if (header.module_flags.HasFlag(ModuleFlags.PerProcessTermination)) if(header.module_flags.HasFlag(ModuleFlags.PerProcessTermination))
sb.AppendLine("Library should be terminated per-process."); sb.AppendLine("Library should be terminated per-process.");
if (header.module_flags.HasFlag(ModuleFlags.InternalFixups)) if(header.module_flags.HasFlag(ModuleFlags.InternalFixups))
sb.AppendLine("Internal fixups have been applied."); sb.AppendLine("Internal fixups have been applied.");
if (header.module_flags.HasFlag(ModuleFlags.ExternalFixups)) if(header.module_flags.HasFlag(ModuleFlags.ExternalFixups))
sb.AppendLine("External fixups have been applied."); sb.AppendLine("External fixups have been applied.");
if (header.module_flags.HasFlag(ModuleFlags.NotLoadable)) if(header.module_flags.HasFlag(ModuleFlags.NotLoadable))
sb.AppendLine("Executable is not loadable, it contains errors or is still being linked."); sb.AppendLine("Executable is not loadable, it contains errors or is still being linked.");
if(header.module_flags.HasFlag(ModuleFlags.VirtualDeviceDriver)) if(header.module_flags.HasFlag(ModuleFlags.VirtualDeviceDriver))
sb.AppendLine("Executable is a driver for a virtual device."); sb.AppendLine("Executable is a driver for a virtual device.");
else if (header.module_flags.HasFlag(ModuleFlags.PhysicalDeviceDriver)) else if(header.module_flags.HasFlag(ModuleFlags.PhysicalDeviceDriver))
sb.AppendLine("Executable is a driver for a physical device."); sb.AppendLine("Executable is a driver for a physical device.");
else if (header.module_flags.HasFlag(ModuleFlags.ProtectedMemoryLibrary)) else if(header.module_flags.HasFlag(ModuleFlags.ProtectedMemoryLibrary))
sb.AppendLine("Executable is a protected mode library."); sb.AppendLine("Executable is a protected mode library.");
else if (header.module_flags.HasFlag(ModuleFlags.Library)) else if(header.module_flags.HasFlag(ModuleFlags.Library))
sb.AppendLine("Executable is a library."); sb.AppendLine("Executable is a library.");
sb.AppendFormat("\tThis executable contains {0} pages", header.module_pages_no).AppendLine(); sb.AppendFormat("\tThis executable contains {0} pages", header.module_pages_no)
sb.AppendFormat("\tObject number to which the Entry Address is relative: {0}", header.eip_object).AppendLine(); .AppendLine();
sb.AppendFormat("\tEntry address of module: {0:X8}h", header.eip).AppendLine(); sb.AppendFormat("\tObject number to which the Entry Address is relative: {0}", header.eip_object)
sb.AppendFormat("\tObject number to which the ESP is relative: {0}", header.esp_object).AppendLine(); .AppendLine();
sb.AppendFormat("\tStarting stack address of module: {0:X8}h", header.esp).AppendLine(); sb.AppendFormat("\tEntry address of module: {0:X8}h", header.eip).AppendLine();
sb.AppendFormat("\tOne page is {0} bytes", header.page_size).AppendLine(); sb.AppendFormat("\tObject number to which the ESP is relative: {0}", header.esp_object).AppendLine();
sb.AppendFormat("\tShift left bits for page offsets: {0}", header.page_off_shift).AppendLine(); sb.AppendFormat("\tStarting stack address of module: {0:X8}h", header.esp).AppendLine();
sb.AppendFormat("\tTotal size of the fixup information: {0}", header.fixup_size).AppendLine(); sb.AppendFormat("\tOne page is {0} bytes", header.page_size).AppendLine();
sb.AppendFormat("\tChecksum for fixup information: 0x{0:X8}", header.fixup_checksum).AppendLine(); sb.AppendFormat("\tShift left bits for page offsets: {0}", header.page_off_shift).AppendLine();
sb.AppendFormat("\tMemory resident tables are {0} bytes long", header.loader_size).AppendLine(); sb.AppendFormat("\tTotal size of the fixup information: {0}", header.fixup_size).AppendLine();
sb.AppendFormat("\tChecksum for loader section: 0x{0:X8}", header.loader_checksum).AppendLine(); sb.AppendFormat("\tChecksum for fixup information: 0x{0:X8}", header.fixup_checksum).AppendLine();
sb.AppendFormat("\tObject table starts at {0} and contains {1} objects", header.obj_table_off, header.obj_no).AppendLine(); sb.AppendFormat("\tMemory resident tables are {0} bytes long", header.loader_size).AppendLine();
sb.AppendFormat("\tObject page table starts at {0}", header.obj_page_table_off).AppendLine(); sb.AppendFormat("\tChecksum for loader section: 0x{0:X8}", header.loader_checksum).AppendLine();
sb.AppendFormat("\tObject iterated pages starts at {0}", header.obj_iter_pages_off).AppendLine(); sb.AppendFormat("\tObject table starts at {0} and contains {1} objects", header.obj_table_off,
sb.AppendFormat("\tResources table starts at {0} and contains {1} entries", header.resource_table_off, header.resource_entries).AppendLine(); header.obj_no).AppendLine();
sb.AppendFormat("\tResident name table starts at {0}", header.resident_names_off).AppendLine(); sb.AppendFormat("\tObject page table starts at {0}", header.obj_page_table_off).AppendLine();
sb.AppendFormat("\tEntry table starts at {0}", header.entry_table_off).AppendLine(); sb.AppendFormat("\tObject iterated pages starts at {0}", header.obj_iter_pages_off).AppendLine();
sb.AppendFormat("\tModule format directives table starts at {0} and contains {1} entries", header.directives_off, header.directives_no).AppendLine(); sb.AppendFormat("\tResources table starts at {0} and contains {1} entries", header.resource_table_off,
sb.AppendFormat("\tFixup page table starts at {0}", header.fixup_page_table_off).AppendLine(); header.resource_entries).AppendLine();
sb.AppendFormat("\tFixup record table starts at {0}", header.fixup_record_table_off).AppendLine(); sb.AppendFormat("\tResident name table starts at {0}", header.resident_names_off).AppendLine();
sb.AppendFormat("\tImport module name table starts at {0} and contains {1} entries", header.import_module_table_off, header.import_module_entries).AppendLine(); sb.AppendFormat("\tEntry table starts at {0}", header.entry_table_off).AppendLine();
sb.AppendFormat("\tImport procedure name table starts at {0}", header.import_proc_table_off).AppendLine(); sb.AppendFormat("\tModule format directives table starts at {0} and contains {1} entries",
sb.AppendFormat("\tPer-page checksum table starts at {0}", header.perpage_checksum_off).AppendLine(); header.directives_off, header.directives_no).AppendLine();
sb.AppendFormat("\tData pages start at {0}", header.data_pages_off).AppendLine(); sb.AppendFormat("\tFixup page table starts at {0}", header.fixup_page_table_off).AppendLine();
sb.AppendFormat("\t{0} pages to preload in this executable", header.preload_pages_no).AppendLine(); sb.AppendFormat("\tFixup record table starts at {0}", header.fixup_record_table_off).AppendLine();
sb.AppendFormat("\tNon-resident names table starts at {0} and runs for {1} bytes", header.nonresident_name_table_off, header.nonresident_name_table_len).AppendLine(); sb.AppendFormat("\tImport module name table starts at {0} and contains {1} entries",
sb.AppendFormat("\tNon-resident name table checksum: 0x{0:X8}", header.nonresident_name_table_checksum).AppendLine(); header.import_module_table_off, header.import_module_entries).AppendLine();
sb.AppendFormat("\tThe auto data segment object number: {0}", header.auto_ds_obj_no).AppendLine(); sb.AppendFormat("\tImport procedure name table starts at {0}", header.import_proc_table_off).AppendLine();
sb.AppendFormat("\tDebug information starts at {0} and is {1} bytes", header.debug_info_off, header.debug_info_len).AppendLine(); sb.AppendFormat("\tPer-page checksum table starts at {0}", header.perpage_checksum_off).AppendLine();
sb.AppendFormat("\tInstance pages in preload section: {0}", header.instance_preload_no).AppendLine(); sb.AppendFormat("\tData pages start at {0}", header.data_pages_off).AppendLine();
sb.AppendFormat("\tInstance pages in demand section: {0}", header.instance_demand_no).AppendLine(); sb.AppendFormat("\t{0} pages to preload in this executable", header.preload_pages_no).AppendLine();
sb.AppendFormat("\tHeap size added to the auto ds object: {0}", header.heap_size).AppendLine(); sb.AppendFormat("\tNon-resident names table starts at {0} and runs for {1} bytes",
return sb.ToString(); header.nonresident_name_table_off, header.nonresident_name_table_len).AppendLine();
} sb.AppendFormat("\tNon-resident name table checksum: 0x{0:X8}", header.nonresident_name_table_checksum)
.AppendLine();
sb.AppendFormat("\tThe auto data segment object number: {0}", header.auto_ds_obj_no).AppendLine();
sb.AppendFormat("\tDebug information starts at {0} and is {1} bytes", header.debug_info_off,
header.debug_info_len).AppendLine();
sb.AppendFormat("\tInstance pages in preload section: {0}", header.instance_preload_no).AppendLine();
sb.AppendFormat("\tInstance pages in demand section: {0}", header.instance_demand_no).AppendLine();
sb.AppendFormat("\tHeap size added to the auto ds object: {0}", header.heap_size).AppendLine();
return sb.ToString();
}
public string GetInfo() public string GetInfo()
{ {
return GetInfo(Header); return GetInfo(Header);
} }
} }
} }

View File

@@ -23,6 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -30,127 +31,119 @@ using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
{ {
/// <summary> /// <summary>
/// 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
{ {
/// <summary> public readonly MZ BaseExecutable;
/// The <see cref="FileStream"/> that contains the executable represented by this instance /// <summary>
/// </summary> /// The <see cref="FileStream" /> that contains the executable represented by this instance
public readonly FileStream BaseStream; /// </summary>
/// <summary> public readonly FileStream BaseStream;
/// Header for this executable /// <summary>
/// </summary> /// Header for this executable
public readonly LXHeader Header; /// </summary>
/// <summary> public readonly LXHeader Header;
/// If true this instance correctly represents a Microsoft/IBM Linear EXecutable /// <summary>
/// </summary> /// If true this instance correctly represents a Microsoft/IBM Linear EXecutable
public readonly bool IsLX; /// </summary>
public readonly MZ BaseExecutable; public readonly bool IsLX;
/// <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="path">Executable path.</param> /// <param name="path">Executable path.</param>
public LX(string path) public LX(string path)
{ {
IsLX = false; IsLX = false;
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseExecutable = new MZ(BaseStream); BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ {
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);
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 = (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; 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(FileStream stream)
{ {
IsLX = false; IsLX = false;
BaseStream = stream; BaseStream = stream;
BaseExecutable = new MZ(BaseStream); BaseExecutable = new MZ(BaseStream);
if (BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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 = (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;
IsLX = Header.signature == Signature || Header.signature == Signature16; }
} }
}
}
/// <summary> /// <summary>
/// Identifies if the specified executable is a Microsoft/IBM Linear EXecutable /// Identifies if the specified executable is a Microsoft/IBM Linear EXecutable
/// </summary> /// </summary>
/// <returns><c>true</c> if the specified executable is a Microsoft/IBM Linear EXecutable, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Microsoft/IBM Linear EXecutable, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public static bool Identify(string path) public static bool Identify(string path)
{ {
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.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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); 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; return false;
} }
/// <summary> /// <summary>
/// Identifies if the specified executable is a Microsoft/IBM Linear EXecutable /// Identifies if the specified executable is a Microsoft/IBM Linear EXecutable
/// </summary> /// </summary>
/// <returns><c>true</c> if the specified executable is a Microsoft/IBM Linear EXecutable, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Microsoft/IBM Linear 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(FileStream stream)
{ {
FileStream BaseStream = stream; FileStream BaseStream = stream;
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if (BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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); 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; return false;
} }
} }
} }

View File

@@ -24,7 +24,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
@@ -32,195 +31,195 @@ namespace libexeinfo
public partial class LX public partial class LX
{ {
/// <summary> /// <summary>
/// Header for a Microsoft Linear Executable and IBM Linear eXecutable /// Header for a Microsoft Linear Executable and IBM Linear eXecutable
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct LXHeader public struct LXHeader
{ {
/// <summary> /// <summary>
/// Executable signature /// Executable signature
/// </summary> /// </summary>
public ushort signature; public ushort signature;
/// <summary> /// <summary>
/// Byte ordering /// Byte ordering
/// </summary> /// </summary>
public byte byte_order; public byte byte_order;
/// <summary> /// <summary>
/// Word ordering /// Word ordering
/// </summary> /// </summary>
public byte word_order; public byte word_order;
/// <summary> /// <summary>
/// Format level, should be 0 /// Format level, should be 0
/// </summary> /// </summary>
public uint format_level; public uint format_level;
/// <summary> /// <summary>
/// Type of CPU required by this executable to run /// Type of CPU required by this executable to run
/// </summary> /// </summary>
public TargetCpu cpu_type; public TargetCpu cpu_type;
/// <summary> /// <summary>
/// Type of operating system requires by this executable to run /// Type of operating system requires by this executable to run
/// </summary> /// </summary>
public TargetOS os_type; public TargetOS os_type;
/// <summary> /// <summary>
/// Executable version /// Executable version
/// </summary> /// </summary>
public uint module_version; public uint module_version;
/// <summary> /// <summary>
/// Executable flags /// Executable flags
/// </summary> /// </summary>
public ModuleFlags module_flags; public ModuleFlags module_flags;
/// <summary> /// <summary>
/// Pages contained in this module /// Pages contained in this module
/// </summary> /// </summary>
public uint module_pages_no; public uint module_pages_no;
/// <summary> /// <summary>
/// Object number to which the Entry Address is relative /// Object number to which the Entry Address is relative
/// </summary> /// </summary>
public uint eip_object; public uint eip_object;
/// <summary> /// <summary>
/// Entry address of module /// Entry address of module
/// </summary> /// </summary>
public uint eip; public uint eip;
/// <summary> /// <summary>
/// Object number to which the ESP is relative /// Object number to which the ESP is relative
/// </summary> /// </summary>
public uint esp_object; public uint esp_object;
/// <summary> /// <summary>
/// Starting stack address of module /// Starting stack address of module
/// </summary> /// </summary>
public uint esp; public uint esp;
/// <summary> /// <summary>
/// Size of one page /// Size of one page
/// </summary> /// </summary>
public uint page_size; public uint page_size;
/// <summary> /// <summary>
/// Shift left bits for page offsets /// Shift left bits for page offsets
/// </summary> /// </summary>
public uint page_off_shift; public uint page_off_shift;
/// <summary> /// <summary>
/// Total size of the fixup information /// Total size of the fixup information
/// </summary> /// </summary>
public uint fixup_size; public uint fixup_size;
/// <summary> /// <summary>
/// Checksum for fixup information /// Checksum for fixup information
/// </summary> /// </summary>
public uint fixup_checksum; public uint fixup_checksum;
/// <summary> /// <summary>
/// Size of memory resident tables /// Size of memory resident tables
/// </summary> /// </summary>
public uint loader_size; public uint loader_size;
/// <summary> /// <summary>
/// Checksum for loader section /// Checksum for loader section
/// </summary> /// </summary>
public uint loader_checksum; public uint loader_checksum;
/// <summary> /// <summary>
/// Object table offset /// Object table offset
/// </summary> /// </summary>
public uint obj_table_off; public uint obj_table_off;
/// <summary> /// <summary>
/// Object table count /// Object table count
/// </summary> /// </summary>
public uint obj_no; public uint obj_no;
/// <summary> /// <summary>
/// Object page table offset /// Object page table offset
/// </summary> /// </summary>
public uint obj_page_table_off; public uint obj_page_table_off;
/// <summary> /// <summary>
/// Object iterated pages offset /// Object iterated pages offset
/// </summary> /// </summary>
public uint obj_iter_pages_off; public uint obj_iter_pages_off;
/// <summary> /// <summary>
/// Resource table offset /// Resource table offset
/// </summary> /// </summary>
public uint resource_table_off; public uint resource_table_off;
/// <summary> /// <summary>
/// Entries in resource table /// Entries in resource table
/// </summary> /// </summary>
public uint resource_entries; public uint resource_entries;
/// <summary> /// <summary>
/// Resident name table offset /// Resident name table offset
/// </summary> /// </summary>
public uint resident_names_off; public uint resident_names_off;
/// <summary> /// <summary>
/// Entry table offset /// Entry table offset
/// </summary> /// </summary>
public uint entry_table_off; public uint entry_table_off;
/// <summary> /// <summary>
/// Module format directives table offset /// Module format directives table offset
/// </summary> /// </summary>
public uint directives_off; public uint directives_off;
/// <summary> /// <summary>
/// Entries in module format directives table /// Entries in module format directives table
/// </summary> /// </summary>
public uint directives_no; public uint directives_no;
/// <summary> /// <summary>
/// Fixup page table offset /// Fixup page table offset
/// </summary> /// </summary>
public uint fixup_page_table_off; public uint fixup_page_table_off;
/// <summary> /// <summary>
/// Fixup record table offset /// Fixup record table offset
/// </summary> /// </summary>
public uint fixup_record_table_off; public uint fixup_record_table_off;
/// <summary> /// <summary>
/// Import module name table offset /// Import module name table offset
/// </summary> /// </summary>
public uint import_module_table_off; public uint import_module_table_off;
/// <summary> /// <summary>
/// Entries in the import module name table /// Entries in the import module name table
/// </summary> /// </summary>
public uint import_module_entries; public uint import_module_entries;
/// <summary> /// <summary>
/// Import procedure name table offset /// Import procedure name table offset
/// </summary> /// </summary>
public uint import_proc_table_off; public uint import_proc_table_off;
/// <summary> /// <summary>
/// Per-page checksum table offset /// Per-page checksum table offset
/// </summary> /// </summary>
public uint perpage_checksum_off; public uint perpage_checksum_off;
/// <summary> /// <summary>
/// Data pages offset /// Data pages offset
/// </summary> /// </summary>
public uint data_pages_off; public uint data_pages_off;
/// <summary> /// <summary>
/// Number of preload pages for this module /// Number of preload pages for this module
/// </summary> /// </summary>
public uint preload_pages_no; public uint preload_pages_no;
/// <summary> /// <summary>
/// Non-resident name table offset /// Non-resident name table offset
/// </summary> /// </summary>
public uint nonresident_name_table_off; public uint nonresident_name_table_off;
/// <summary> /// <summary>
/// Number of bytes in the non-resident name table /// Number of bytes in the non-resident name table
/// </summary> /// </summary>
public uint nonresident_name_table_len; public uint nonresident_name_table_len;
/// <summary> /// <summary>
/// Non-resident name table checksum /// Non-resident name table checksum
/// </summary> /// </summary>
public uint nonresident_name_table_checksum; public uint nonresident_name_table_checksum;
/// <summary> /// <summary>
/// The auto data segment object number /// The auto data segment object number
/// </summary> /// </summary>
public uint auto_ds_obj_no; public uint auto_ds_obj_no;
/// <summary> /// <summary>
/// Debug information offset /// Debug information offset
/// </summary> /// </summary>
public uint debug_info_off; public uint debug_info_off;
/// <summary> /// <summary>
/// Debug information length /// Debug information length
/// </summary> /// </summary>
public uint debug_info_len; public uint debug_info_len;
/// <summary> /// <summary>
/// Instance pages in preload section /// Instance pages in preload section
/// </summary> /// </summary>
public uint instance_preload_no; public uint instance_preload_no;
/// <summary> /// <summary>
/// Instance pages in demand section /// Instance pages in demand section
/// </summary> /// </summary>
public uint instance_demand_no; public uint instance_demand_no;
/// <summary> /// <summary>
/// Heap size added to the auto ds object /// Heap size added to the auto ds object
/// </summary> /// </summary>
public uint heap_size; public uint heap_size;
} }
} }
} }

View File

@@ -24,14 +24,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class MZ public partial class MZ
{ {
/// <summary> /// <summary>
/// MZ executable signature, "MZ" /// MZ executable signature, "MZ"
/// </summary> /// </summary>
public const ushort Signature = 0x5A4D; public const ushort Signature = 0x5A4D;
} }
} }

View File

@@ -29,42 +29,45 @@ using System.Text;
namespace libexeinfo namespace libexeinfo
{ {
public partial class MZ public partial class MZ
{ {
/// <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>
/// <returns>Human readable information for given MZ header.</returns> /// <returns>Human readable information for given MZ header.</returns>
/// <param name="header">MZ executable header.</param> /// <param name="header">MZ executable header.</param>
public static string GetInfo(MZHeader header) public static string GetInfo(MZHeader header)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.AppendLine("DOS MZ executable:"); sb.AppendLine("DOS MZ executable:");
sb.AppendFormat("\tBlocks in file: {0}", header.blocks_in_file).AppendLine(); sb.AppendFormat("\tBlocks in file: {0}", header.blocks_in_file).AppendLine();
sb.AppendFormat("\t{0} bytes used in last block", header.bytes_in_last_block == 0 ? 512 : header.bytes_in_last_block).AppendLine(); sb.AppendFormat("\t{0} bytes used in last block",
sb.AppendFormat("\t{0} relocations present after the header", header.num_relocs).AppendLine(); header.bytes_in_last_block == 0 ? 512 : header.bytes_in_last_block).AppendLine();
sb.AppendFormat("\t{0} paragraphs in header", header.header_paragraphs).AppendLine(); sb.AppendFormat("\t{0} relocations present after the header", header.num_relocs).AppendLine();
sb.AppendFormat("\t{0} paragraphs of additional memory required", header.min_extra_paragraphs).AppendLine(); sb.AppendFormat("\t{0} paragraphs in header", header.header_paragraphs).AppendLine();
sb.AppendFormat("\t{0} paragraphs of additional memory requested", header.max_extra_paragraphs).AppendLine(); sb.AppendFormat("\t{0} paragraphs of additional memory required", header.min_extra_paragraphs)
sb.AppendFormat("\tSegment address for SS: {0:X4}h", header.ss).AppendLine(); .AppendLine();
sb.AppendFormat("\tInitial value of SP: {0:X4}h", header.sp).AppendLine(); sb.AppendFormat("\t{0} paragraphs of additional memory requested", header.max_extra_paragraphs)
sb.AppendFormat("\tInitial value of IP: {0:X4}h", header.ip).AppendLine(); .AppendLine();
sb.AppendFormat("\tInitial value of CS: {0:X4}h", header.cs).AppendLine(); sb.AppendFormat("\tSegment address for SS: {0:X4}h", header.ss).AppendLine();
sb.AppendFormat("\tOffset to relocation table: {0}", header.reloc_table_offset).AppendLine(); sb.AppendFormat("\tInitial value of SP: {0:X4}h", header.sp).AppendLine();
sb.AppendFormat("\tFile contains {0} overlays", header.overlay_number).AppendLine(); sb.AppendFormat("\tInitial value of IP: {0:X4}h", header.ip).AppendLine();
sb.AppendFormat("\tFile checksum: 0x{0:X4}", header.checksum).AppendLine(); sb.AppendFormat("\tInitial value of CS: {0:X4}h", header.cs).AppendLine();
sb.AppendFormat("\tOEM ID: {0}", header.oem_id).AppendLine(); sb.AppendFormat("\tOffset to relocation table: {0}", header.reloc_table_offset).AppendLine();
sb.AppendFormat("\tOEM information: 0x{0:X4}", header.oem_info).AppendLine(); sb.AppendFormat("\tFile contains {0} overlays", header.overlay_number).AppendLine();
sb.AppendFormat("\tOffset to new header: {0}", header.new_offset).AppendLine(); sb.AppendFormat("\tFile checksum: 0x{0:X4}", header.checksum).AppendLine();
sb.AppendFormat("\tOEM ID: {0}", header.oem_id).AppendLine();
sb.AppendFormat("\tOEM information: 0x{0:X4}", header.oem_info).AppendLine();
sb.AppendFormat("\tOffset to new header: {0}", header.new_offset).AppendLine();
return sb.ToString(); return sb.ToString();
} }
/// <summary> /// <summary>
/// Gets a string with human readable information for the MZ executable represented by this instance /// Gets a string with human readable information for the MZ executable represented by this instance
/// </summary> /// </summary>
/// <returns>Human readable information for this instance.</returns> /// <returns>Human readable information for this instance.</returns>
public string GetInfo() public string GetInfo()
{ {
return GetInfo(Header); return GetInfo(Header);
} }
} }
} }

View File

@@ -23,94 +23,95 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
{ {
/// <summary> /// <summary>
/// Represents a DOS relocatable executable /// Represents a DOS relocatable executable
/// </summary> /// </summary>
public partial class MZ public partial class MZ
{ {
/// <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 readonly FileStream BaseStream;
/// <summary> /// <summary>
/// Header for this executable /// Header for this executable
/// </summary> /// </summary>
public readonly MZHeader Header; public readonly MZHeader Header;
/// <summary> /// <summary>
/// If true this instance correctly represents a DOS relocatable executable /// If true this instance correctly represents a DOS relocatable executable
/// </summary> /// </summary>
public readonly bool IsMZ; 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.
/// </summary> /// </summary>
/// <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))]; 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; 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; IsMZ = Header.signature == Signature;
} }
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.MZ"/> class.
/// </summary>
/// <param name="stream">Stream containing the executable.</param>
public MZ(FileStream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))];
BaseStream = stream; /// <summary>
BaseStream.Position = 0; /// Initializes a new instance of the <see cref="T:libexeinfo.MZ" /> class.
BaseStream.Read(buffer, 0, buffer.Length); /// </summary>
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); /// <param name="stream">Stream containing the executable.</param>
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); public MZ(FileStream stream)
Header = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader));
Marshal.FreeHGlobal(hdrPtr);
IsMZ = Header.signature == Signature;
}
/// <summary>
/// Identifies if the specified executable is a DOS relocatable executable
/// </summary>
/// <returns><c>true</c> if the specified executable is a DOS relocatable executable, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param>
public static bool Identify(string path)
{ {
FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read); byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))];
return Identify(exeFs);
}
/// <summary> BaseStream = stream;
/// Identifies if the specified executable is a DOS relocatable executable BaseStream.Position = 0;
/// </summary> BaseStream.Read(buffer, 0, buffer.Length);
/// <returns><c>true</c> if the specified executable is a DOS relocatable executable, <c>false</c> otherwise.</returns> IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
/// <param name="stream">Stream containing the executable.</param> Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
public static bool Identify(FileStream stream) Header = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader));
{ Marshal.FreeHGlobal(hdrPtr);
byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))]; IsMZ = Header.signature == Signature;
}
/// <summary>
/// Identifies if the specified executable is a DOS relocatable executable
/// </summary>
/// <returns><c>true</c> if the specified executable is a DOS relocatable executable, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param>
public static bool Identify(string path)
{
FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read);
return Identify(exeFs);
}
/// <summary>
/// Identifies if the specified executable is a DOS relocatable executable
/// </summary>
/// <returns><c>true</c> if the specified executable is a DOS relocatable executable, <c>false</c> otherwise.</returns>
/// <param name="stream">Stream containing the executable.</param>
public static bool Identify(FileStream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))];
stream.Position = 0; stream.Position = 0;
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);
MZHeader mzHdr = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader)); MZHeader mzHdr = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
return mzHdr.signature == Signature; return mzHdr.signature == Signature;
} }
} }
} }

View File

@@ -31,7 +31,7 @@ namespace libexeinfo
public partial class MZ public partial class MZ
{ {
/// <summary> /// <summary>
/// Header of a DOS relocatable executable /// Header of a DOS relocatable executable
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MZHeader public struct MZHeader
@@ -52,15 +52,15 @@ namespace libexeinfo
public ushort overlay_number; public ushort overlay_number;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ushort[] reserved; public ushort[] reserved;
public ushort oem_id; public ushort oem_id;
public ushort oem_info; public ushort oem_info;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public ushort[] reserved2; public ushort[] reserved2;
public uint new_offset; public uint new_offset;
} }
/// <summary> /// <summary>
/// Entry in the relocation table /// Entry in the relocation table
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct RelocationTableEntry public struct RelocationTableEntry

View File

@@ -24,89 +24,60 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.ComponentModel;
namespace libexeinfo namespace libexeinfo
{ {
public partial class NE public partial class NE
{ {
/// <summary> /// <summary>
/// New Executable signature, "NE" /// New Executable signature, "NE"
/// </summary> /// </summary>
public const ushort Signature = 0x454E; public const ushort Signature = 0x454E;
/// <summary> /// <summary>
/// Signature for a <see cref="FixedFileInfo"/> /// Signature for a <see cref="FixedFileInfo" />
/// </summary> /// </summary>
public static readonly string FixedFileInfoSig = "VS_VERSION_INFO"; public static readonly string FixedFileInfoSig = "VS_VERSION_INFO";
/// <summary> /// <summary>
/// Signature for list of name=value strings inside a version resource /// Signature for list of name=value strings inside a version resource
/// </summary> /// </summary>
public static readonly string StringFileInfo = "StringFileInfo"; public static readonly string StringFileInfo = "StringFileInfo";
/// <summary> /// <summary>
/// Gets the name of a resource type according to its identifier /// Gets the name of a resource type according to its identifier
/// </summary> /// </summary>
/// <returns>The resource type name.</returns> /// <returns>The resource type name.</returns>
/// <param name="id">Resource type identifier.</param> /// <param name="id">Resource type identifier.</param>
public static string ResourceIdToName(ushort id) public static string ResourceIdToName(ushort id)
{ {
switch (id & 0x7FFF) switch(id & 0x7FFF)
{ {
case (int)ResourceTypes.RT_ACCELERATOR: case (int)ResourceTypes.RT_ACCELERATOR: return "RT_ACCELERATOR";
return "RT_ACCELERATOR"; case (int)ResourceTypes.RT_ANICURSOR: return "RT_ANICURSOR";
case (int)ResourceTypes.RT_ANICURSOR: case (int)ResourceTypes.RT_ANIICON: return "RT_ANIICON";
return "RT_ANICURSOR"; case (int)ResourceTypes.RT_BITMAP: return "RT_BITMAP";
case (int)ResourceTypes.RT_ANIICON: case (int)ResourceTypes.RT_CURSOR: return "RT_CURSOR";
return "RT_ANIICON"; case (int)ResourceTypes.RT_DIALOG: return "RT_DIALOG";
case (int)ResourceTypes.RT_BITMAP: case (int)ResourceTypes.RT_DIALOGEX: return "RT_DIALOGEX";
return "RT_BITMAP"; case (int)ResourceTypes.RT_DLGINCLUDE: return "RT_DLGINCLUDE";
case (int)ResourceTypes.RT_CURSOR: case (int)ResourceTypes.RT_DLGINIT: return "RT_DLGINIT";
return "RT_CURSOR"; case (int)ResourceTypes.RT_FONT: return "RT_FONT";
case (int)ResourceTypes.RT_DIALOG: case (int)ResourceTypes.RT_FONTDIR: return "RT_FONTDIR";
return "RT_DIALOG"; case (int)ResourceTypes.RT_GROUP_CURSOR: return "RT_GROUP_CURSOR";
case (int)ResourceTypes.RT_DIALOGEX: case (int)ResourceTypes.RT_GROUP_ICON: return "RT_GROUP_ICON";
return "RT_DIALOGEX"; case (int)ResourceTypes.RT_HTML: return "RT_HTML";
case (int)ResourceTypes.RT_DLGINCLUDE: case (int)ResourceTypes.RT_ICON: return "RT_ICON";
return "RT_DLGINCLUDE"; case (int)ResourceTypes.RT_MANIFEST: return "RT_MANIFEST";
case (int)ResourceTypes.RT_DLGINIT: case (int)ResourceTypes.RT_MENU: return "RT_MENU";
return "RT_DLGINIT"; case (int)ResourceTypes.RT_MENUEX: return "RT_MENUEX";
case (int)ResourceTypes.RT_FONT: case (int)ResourceTypes.RT_MESSAGETABLE: return "RT_MESSAGETABLE";
return "RT_FONT"; case (int)ResourceTypes.RT_NEWBITMAP: return "RT_NEWBITMAP";
case (int)ResourceTypes.RT_FONTDIR: case (int)ResourceTypes.RT_PLUGPLAY: return "RT_PLUGPLAY";
return "RT_FONTDIR"; case (int)ResourceTypes.RT_RCDATA: return "RT_RCDATA";
case (int)ResourceTypes.RT_GROUP_CURSOR: case (int)ResourceTypes.RT_STRING: return "RT_STRING";
return "RT_GROUP_CURSOR"; case (int)ResourceTypes.RT_TOOLBAR: return "RT_TOOLBAR";
case (int)ResourceTypes.RT_GROUP_ICON: case (int)ResourceTypes.RT_VERSION: return "RT_VERSION";
return "RT_GROUP_ICON"; case (int)ResourceTypes.RT_VXD: return "RT_VXD";
case (int)ResourceTypes.RT_HTML: default: return string.Format("{0}", id & 0x7FFF);
return "RT_HTML"; }
case (int)ResourceTypes.RT_ICON: }
return "RT_ICON"; }
case (int)ResourceTypes.RT_MANIFEST: }
return "RT_MANIFEST";
case (int)ResourceTypes.RT_MENU:
return "RT_MENU";
case (int)ResourceTypes.RT_MENUEX:
return "RT_MENUEX";
case (int)ResourceTypes.RT_MESSAGETABLE:
return "RT_MESSAGETABLE";
case (int)ResourceTypes.RT_NEWBITMAP:
return "RT_NEWBITMAP";
case (int)ResourceTypes.RT_PLUGPLAY:
return "RT_PLUGPLAY";
case (int)ResourceTypes.RT_RCDATA:
return "RT_RCDATA";
case (int)ResourceTypes.RT_STRING:
return "RT_STRING";
case (int)ResourceTypes.RT_TOOLBAR:
return "RT_TOOLBAR";
case (int)ResourceTypes.RT_VERSION:
return "RT_VERSION";
case (int)ResourceTypes.RT_VXD:
return "RT_VXD";
default:
return string.Format("{0}", id & 0x7FFF);
}
}
}
}

View File

@@ -25,195 +25,196 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class NE public partial class NE
{ {
/// <summary> /// <summary>
/// Program flags. /// Application flags.
/// </summary>
[Flags]
public enum ProgramFlags : byte
{
NoDGroup = 0,
SingleDGroup = 1,
MultipleDGroup = 2,
GlobalInit = 1 << 2,
ProtectedMode = 1 << 3,
i86 = 1 << 4,
i286 = 1 << 5,
i386 = 1 << 6,
i87 = 1 << 7
}
/// <summary>
/// Target operating system.
/// </summary>
public enum TargetOS : byte
{
Unknown = 0,
OS2 = 1,
Windows = 2,
DOS = 3,
Win32 = 4,
Borland = 5
}
/// <summary>
/// Application flags.
/// </summary> /// </summary>
[Flags] [Flags]
public enum ApplicationFlags : byte public enum ApplicationFlags : byte
{ {
FullScreen = 1, FullScreen = 1,
GUICompatible = 2, GUICompatible = 2,
Errors = 1 << 5, Errors = 1 << 5,
NonConforming = 1 << 6, NonConforming = 1 << 6,
DLL = 1 << 7 DLL = 1 << 7
} }
/// <summary> /// <summary>
/// OS/2 flags. /// OS/2 flags.
/// </summary> /// </summary>
[Flags] [Flags]
public enum OS2Flags : byte public enum OS2Flags : byte
{ {
LongFilename = 1 << 0, LongFilename = 1 << 0,
ProtectedMode2 = 1 << 1, ProtectedMode2 = 1 << 1,
ProportionalFonts = 1 << 2, ProportionalFonts = 1 << 2,
GangloadArea = 1 << 3, GangloadArea = 1 << 3
} }
/// <summary> /// <summary>
/// Resource flags. /// Program flags.
/// </summary>
[Flags]
public enum ProgramFlags : byte
{
NoDGroup = 0,
SingleDGroup = 1,
MultipleDGroup = 2,
GlobalInit = 1 << 2,
ProtectedMode = 1 << 3,
i86 = 1 << 4,
i286 = 1 << 5,
i386 = 1 << 6,
i87 = 1 << 7
}
/// <summary>
/// Resource flags.
/// </summary> /// </summary>
[Flags] [Flags]
public enum ResourceFlags : ushort public enum ResourceFlags : ushort
{ {
Moveable = 0x10, Moveable = 0x10,
Pure = 0x20, Pure = 0x20,
Preload = 0x40 Preload = 0x40
} }
/// <summary> /// <summary>
/// Resource types. /// Resource types.
/// </summary> /// </summary>
public enum ResourceTypes : ushort public enum ResourceTypes : ushort
{ {
RT_ACCELERATOR = 9, RT_ACCELERATOR = 9,
RT_ANICURSOR = 21, RT_ANICURSOR = 21,
RT_ANIICON = 22, RT_ANIICON = 22,
RT_BITMAP = 2, RT_BITMAP = 2,
RT_CURSOR = 1, RT_CURSOR = 1,
RT_DIALOG = 5, RT_DIALOG = 5,
RT_DIALOGEX = 18, RT_DIALOGEX = 18,
RT_DLGINCLUDE = 17, RT_DLGINCLUDE = 17,
RT_DLGINIT = 240, RT_DLGINIT = 240,
RT_FONT = 8, RT_FONT = 8,
RT_FONTDIR = 7, RT_FONTDIR = 7,
RT_GROUP_CURSOR = 12, RT_GROUP_CURSOR = 12,
RT_GROUP_ICON = 13, RT_GROUP_ICON = 13,
RT_HTML = 23, RT_HTML = 23,
RT_ICON = 3, RT_ICON = 3,
RT_MANIFEST = 24, RT_MANIFEST = 24,
RT_MENU = 4, RT_MENU = 4,
RT_MENUEX = 15, RT_MENUEX = 15,
RT_MESSAGETABLE = 11, RT_MESSAGETABLE = 11,
RT_NEWBITMAP = RT_NEW | RT_BITMAP, RT_NEWBITMAP = RT_NEW | RT_BITMAP,
RT_PLUGPLAY = 19, RT_PLUGPLAY = 19,
RT_RCDATA = 10, RT_RCDATA = 10,
RT_STRING = 6, RT_STRING = 6,
RT_TOOLBAR = 241, RT_TOOLBAR = 241,
RT_VERSION = 16, RT_VERSION = 16,
RT_VXD = 20, RT_VXD = 20,
RT_NEW = 0x2000, RT_NEW = 0x2000
} }
/// <summary> /// <summary>
/// Version file flags. /// Target operating system.
/// </summary>
public enum TargetOS : byte
{
Unknown = 0,
OS2 = 1,
Windows = 2,
DOS = 3,
Win32 = 4,
Borland = 5
}
/// <summary>
/// Version file flags.
/// </summary> /// </summary>
[Flags] [Flags]
public enum VersionFileFlags : uint public enum VersionFileFlags : uint
{ {
VS_FF_DEBUG = 0x00000001, VS_FF_DEBUG = 0x00000001,
VS_FF_INFOINFERRED = 0x00000010, VS_FF_INFOINFERRED = 0x00000010,
VS_FF_PATCHED = 0x00000004, VS_FF_PATCHED = 0x00000004,
VS_FF_PRERELEASE = 0x00000002, VS_FF_PRERELEASE = 0x00000002,
VS_FF_PRIVATEBUILD = 0x00000008, VS_FF_PRIVATEBUILD = 0x00000008,
VS_FF_SPECIALBUILD = 0x00000020, VS_FF_SPECIALBUILD = 0x00000020
} }
/// <summary> /// <summary>
/// Version file operating system. /// Version file operating system.
/// </summary> /// </summary>
public enum VersionFileOS : uint public enum VersionFileOS : uint
{ {
VOS_DOS = 0x00010000, VOS_DOS = 0x00010000,
VOS_NT = 0x00040000, VOS_NT = 0x00040000,
VOS_WINDOWS16 = 0x00000001, VOS_WINDOWS16 = 0x00000001,
VOS_WINDOWS32 = 0x00000004, VOS_WINDOWS32 = 0x00000004,
VOS_OS216 = 0x00020000, VOS_OS216 = 0x00020000,
VOS_OS232 = 0x00030000, VOS_OS232 = 0x00030000,
VOS_PM16 = 0x00000002, VOS_PM16 = 0x00000002,
VOS_PM32 = 0x00000003, VOS_PM32 = 0x00000003,
VOS_UNKNOWN = 0x00000000, VOS_UNKNOWN = 0x00000000,
// Combinations, some have no sense // Combinations, some have no sense
VOS_DOS_NT = 0x00050000, VOS_DOS_NT = 0x00050000,
VOS_DOS_WINDOWS16 = 0x00010001, VOS_DOS_WINDOWS16 = 0x00010001,
VOS_DOS_WINDOWS32 = 0x00010004, VOS_DOS_WINDOWS32 = 0x00010004,
VOS_DOS_PM16 = 0x00010002, VOS_DOS_PM16 = 0x00010002,
VOS_DOS_PM32 = 0x00010003, VOS_DOS_PM32 = 0x00010003,
VOS_NT_WINDOWS16 = 0x00040001, VOS_NT_WINDOWS16 = 0x00040001,
VOS_NT_WINDOWS32 = 0x00040004, VOS_NT_WINDOWS32 = 0x00040004,
VOS_NT_PM16 = 0x00040002, VOS_NT_PM16 = 0x00040002,
VOS_NT_PM32 = 0x00040003, VOS_NT_PM32 = 0x00040003,
VOS_OS216_WINDOWS16 = 0x00020001, VOS_OS216_WINDOWS16 = 0x00020001,
VOS_OS216_WINDOWS32 = 0x00020004, VOS_OS216_WINDOWS32 = 0x00020004,
VOS_OS216_PM16 = 0x00020002, VOS_OS216_PM16 = 0x00020002,
VOS_OS216_PM32 = 0x00020003, VOS_OS216_PM32 = 0x00020003,
VOS_OS232_WINDOWS16 = 0x00030001, VOS_OS232_WINDOWS16 = 0x00030001,
VOS_OS232_WINDOWS32 = 0x00030004, VOS_OS232_WINDOWS32 = 0x00030004,
VOS_OS232_PM16 = 0x00030002, VOS_OS232_PM16 = 0x00030002,
VOS_OS232_PM32 = 0x00030003, VOS_OS232_PM32 = 0x00030003
} }
/// <summary> /// <summary>
/// Version file type. /// Version file subtype.
/// </summary>
public enum VersionFileType : uint
{
VFT_APP = 0x00000001,
VFT_DLL = 0x00000002,
VFT_DRV = 0x00000003,
VFT_FONT = 0x00000004,
VFT_STATIC_LIB = 0x00000007,
VFT_UNKNOWN = 0x00000000,
VFT_VXD = 0x00000005,
}
/// <summary>
/// Version file subtype.
/// </summary> /// </summary>
public enum VersionFileSubtype : uint public enum VersionFileSubtype : uint
{ {
VFT2_UNKNOWN = 0x00000000, VFT2_UNKNOWN = 0x00000000,
// Drivers // Drivers
VFT2_DRV_COMM = 0x0000000A, VFT2_DRV_COMM = 0x0000000A,
VFT2_DRV_DISPLAY = 0x00000004, VFT2_DRV_DISPLAY = 0x00000004,
VFT2_DRV_INSTALLABLE = 0x00000008, VFT2_DRV_INSTALLABLE = 0x00000008,
VFT2_DRV_KEYBOARD = 0x00000002, VFT2_DRV_KEYBOARD = 0x00000002,
VFT2_DRV_LANGUAGE = 0x00000003, VFT2_DRV_LANGUAGE = 0x00000003,
VFT2_DRV_MOUSE = 0x00000005, VFT2_DRV_MOUSE = 0x00000005,
VFT2_DRV_NETWORK = 0x00000006, VFT2_DRV_NETWORK = 0x00000006,
VFT2_DRV_PRINTER = 0x00000001, VFT2_DRV_PRINTER = 0x00000001,
VFT2_DRV_SOUND = 0x00000009, VFT2_DRV_SOUND = 0x00000009,
VFT2_DRV_SYSTEM = 0x00000007, VFT2_DRV_SYSTEM = 0x00000007,
VFT2_DRV_VERSIONED_PRINTER = 0x0000000C, VFT2_DRV_VERSIONED_PRINTER = 0x0000000C,
// Fonts // Fonts
VFT2_FONT_RASTER = 0x00000001, VFT2_FONT_RASTER = 0x00000001,
VFT2_FONT_TRUETYPE = 0x00000003, VFT2_FONT_TRUETYPE = 0x00000003,
VFT2_FONT_VECTOR = 0x00000002, VFT2_FONT_VECTOR = 0x00000002
}
/// <summary>
/// Version file type.
/// </summary>
public enum VersionFileType : uint
{
VFT_APP = 0x00000001,
VFT_DLL = 0x00000002,
VFT_DRV = 0x00000003,
VFT_FONT = 0x00000004,
VFT_STATIC_LIB = 0x00000007,
VFT_UNKNOWN = 0x00000000,
VFT_VXD = 0x00000005
} }
} }
} }

View File

@@ -31,140 +31,166 @@ using System.Text;
namespace libexeinfo namespace libexeinfo
{ {
public partial class NE public partial class NE
{ {
public static string GetInfo(NEHeader header) public static string GetInfo(NEHeader header)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.AppendLine("New Executable (NE):"); sb.AppendLine("New Executable (NE):");
sb.AppendFormat("\tFile's CRC: 0x{0:X8}", header.crc).AppendLine(); sb.AppendFormat("\tFile's CRC: 0x{0:X8}", header.crc).AppendLine();
sb.AppendFormat("\tLinker version: {0}.{1}", header.linker_major, header.linker_minor).AppendLine(); sb.AppendFormat("\tLinker version: {0}.{1}", header.linker_major, header.linker_minor).AppendLine();
if (header.program_flags.HasFlag(ProgramFlags.SingleDGroup) && !header.program_flags.HasFlag(ProgramFlags.MultipleDGroup)) if(header.program_flags.HasFlag(ProgramFlags.SingleDGroup) &&
sb.AppendLine("\tApplication uses a single shared DGroup"); !header.program_flags.HasFlag(ProgramFlags.MultipleDGroup))
else if (!header.program_flags.HasFlag(ProgramFlags.SingleDGroup) && header.program_flags.HasFlag(ProgramFlags.MultipleDGroup)) sb.AppendLine("\tApplication uses a single shared DGroup");
sb.AppendLine("\tApplication uses a multiple DGroup"); else if(!header.program_flags.HasFlag(ProgramFlags.SingleDGroup) &&
else if (header.program_flags.HasFlag(ProgramFlags.SingleDGroup) && header.program_flags.HasFlag(ProgramFlags.MultipleDGroup)) header.program_flags.HasFlag(ProgramFlags.MultipleDGroup))
sb.AppendLine("\tApplication indicates an incorrect DGroup value"); sb.AppendLine("\tApplication uses a multiple DGroup");
else if (!header.program_flags.HasFlag(ProgramFlags.SingleDGroup) && !header.program_flags.HasFlag(ProgramFlags.MultipleDGroup)) else if(header.program_flags.HasFlag(ProgramFlags.SingleDGroup) &&
sb.AppendLine("\tApplication does not use DGroup"); header.program_flags.HasFlag(ProgramFlags.MultipleDGroup))
if (header.program_flags.HasFlag(ProgramFlags.GlobalInit)) sb.AppendLine("\tApplication indicates an incorrect DGroup value");
sb.AppendLine("\tApplication uses global initialization"); else if(!header.program_flags.HasFlag(ProgramFlags.SingleDGroup) &&
if (header.program_flags.HasFlag(ProgramFlags.ProtectedMode)) !header.program_flags.HasFlag(ProgramFlags.MultipleDGroup))
sb.AppendLine("\tApplication uses protected mode"); sb.AppendLine("\tApplication does not use DGroup");
if (header.program_flags.HasFlag(ProgramFlags.i86)) if(header.program_flags.HasFlag(ProgramFlags.GlobalInit))
sb.AppendLine("\tApplication uses 8086 instructions"); sb.AppendLine("\tApplication uses global initialization");
if (header.program_flags.HasFlag(ProgramFlags.i286)) if(header.program_flags.HasFlag(ProgramFlags.ProtectedMode))
sb.AppendLine("\tApplication uses 80286 instructions"); sb.AppendLine("\tApplication uses protected mode");
if (header.program_flags.HasFlag(ProgramFlags.i386)) if(header.program_flags.HasFlag(ProgramFlags.i86)) sb.AppendLine("\tApplication uses 8086 instructions");
sb.AppendLine("\tApplication uses 80386 instructions"); if(header.program_flags.HasFlag(ProgramFlags.i286)) sb.AppendLine("\tApplication uses 80286 instructions");
if (header.program_flags.HasFlag(ProgramFlags.i87)) if(header.program_flags.HasFlag(ProgramFlags.i386)) sb.AppendLine("\tApplication uses 80386 instructions");
sb.AppendLine("\tApplication uses floating point instructions"); if(header.program_flags.HasFlag(ProgramFlags.i87))
sb.AppendLine("\tApplication uses floating point instructions");
if (header.target_os == TargetOS.OS2) if(header.target_os == TargetOS.OS2)
{ {
sb.AppendLine("\tOS/2 application"); sb.AppendLine("\tOS/2 application");
if(header.os_major > 0) if(header.os_major > 0)
sb.AppendFormat("\tApplication requires OS/2 {0}.{1} to run", header.os_major, header.os_minor).AppendLine(); sb.AppendFormat("\tApplication requires OS/2 {0}.{1} to run", header.os_major, header.os_minor)
.AppendLine();
else sb.AppendLine("\tApplication requires OS/2 1.0 to run");
if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
!header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendLine("\tApplication is full screen, unaware of Presentation Manager");
else if(!header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendLine("\tApplication is aware of Presentation Manager, but doesn't use it");
else if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendLine("\tApplication uses Presentation Manager");
if(header.os2_flags.HasFlag(OS2Flags.LongFilename))
sb.AppendLine("\tApplication supports long filenames");
if(header.os2_flags.HasFlag(OS2Flags.ProtectedMode2))
sb.AppendLine("\tApplication uses OS/2 2.x protected mode");
if(header.os2_flags.HasFlag(OS2Flags.ProportionalFonts))
sb.AppendLine("\tApplication uses OS/2 2.x proportional fonts");
if(header.os2_flags.HasFlag(OS2Flags.GangloadArea))
sb.AppendFormat("\tGangload area starts at {0} an runs for {1} bytes", header.return_thunks_offset,
header.segment_reference_thunks).AppendLine();
else else
sb.AppendLine("\tApplication requires OS/2 1.0 to run"); {
if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && !header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine();
sb.AppendLine("\tApplication is full screen, unaware of Presentation Manager"); sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks)
else if (!header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) .AppendLine();
sb.AppendLine("\tApplication is aware of Presentation Manager, but doesn't use it"); }
else if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) }
sb.AppendLine("\tApplication uses Presentation Manager"); else if(header.target_os == TargetOS.Windows || header.target_os == TargetOS.Win32 ||
if (header.os2_flags.HasFlag(OS2Flags.LongFilename)) header.target_os == TargetOS.Unknown)
sb.AppendLine("\tApplication supports long filenames"); {
if (header.os2_flags.HasFlag(OS2Flags.ProtectedMode2)) if(header.target_os == TargetOS.Windows || header.target_os == TargetOS.Unknown)
sb.AppendLine("\tApplication uses OS/2 2.x protected mode"); sb.AppendLine("\t16-bit Windows application");
if (header.os2_flags.HasFlag(OS2Flags.ProportionalFonts)) else if(header.target_os == TargetOS.Win32)
sb.AppendLine("\tApplication uses OS/2 2.x proportional fonts"); sb.AppendLine("\t32-bit Windows application");
if (header.os2_flags.HasFlag(OS2Flags.GangloadArea))
sb.AppendFormat("\tGangload area starts at {0} an runs for {1} bytes", header.return_thunks_offset, header.segment_reference_thunks).AppendLine();
else
{
sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine();
sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine();
}
}
else if (header.target_os == TargetOS.Windows || header.target_os == TargetOS.Win32 || header.target_os == TargetOS.Unknown)
{
if (header.target_os == TargetOS.Windows || header.target_os == TargetOS.Unknown)
sb.AppendLine("\t16-bit Windows application");
else if (header.target_os == TargetOS.Win32)
sb.AppendLine("\t32-bit Windows application");
if(header.os_major > 0) if(header.os_major > 0)
sb.AppendFormat("\tApplication requires Windows {0}.{1} to run", header.os_major, header.os_minor).AppendLine(); sb.AppendFormat("\tApplication requires Windows {0}.{1} to run", header.os_major, header.os_minor)
.AppendLine();
else if(header.target_os == TargetOS.Windows) else if(header.target_os == TargetOS.Windows)
sb.AppendLine("\tApplication requires Windows 2.0 to run"); sb.AppendLine("\tApplication requires Windows 2.0 to run");
else if (header.target_os == TargetOS.Unknown) else if(header.target_os == TargetOS.Unknown)
sb.AppendLine("\tApplication requires Windows 1.0 to run"); sb.AppendLine("\tApplication requires Windows 1.0 to run");
if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && !header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
sb.AppendLine("\tApplication is full screen, unaware of Windows"); !header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
else if (!header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) sb.AppendLine("\tApplication is full screen, unaware of Windows");
sb.AppendLine("\tApplication is aware of Windows, but doesn't use it"); else if(!header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
else if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendLine("\tApplication uses Windows"); sb.AppendLine("\tApplication is aware of Windows, but doesn't use it");
sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine(); else if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine(); header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
} sb.AppendLine("\tApplication uses Windows");
else if (header.target_os == TargetOS.DOS) sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine();
{ sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine();
sb.AppendLine("\tDOS application"); }
sb.AppendFormat("\tApplication requires DOS {0}.{1} to run", header.os_major, header.os_minor).AppendLine(); else if(header.target_os == TargetOS.DOS)
if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && !header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) {
sb.AppendLine("\tApplication is full screen, unaware of Windows"); sb.AppendLine("\tDOS application");
else if (!header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) sb.AppendFormat("\tApplication requires DOS {0}.{1} to run", header.os_major, header.os_minor)
sb.AppendLine("\tApplication is aware of Windows, but doesn't use it"); .AppendLine();
else if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
sb.AppendLine("\tApplication uses Windows"); !header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine(); sb.AppendLine("\tApplication is full screen, unaware of Windows");
sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine(); else if(!header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
} header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
else if (header.target_os == TargetOS.Borland) sb.AppendLine("\tApplication is aware of Windows, but doesn't use it");
{ else if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
sb.AppendLine("\tBorland Operating System Services application"); header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendFormat("\tApplication requires DOS {0}.{1} to run", header.os_major, header.os_minor).AppendLine(); sb.AppendLine("\tApplication uses Windows");
if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && !header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine();
sb.AppendLine("\tApplication is full screen, unaware of Windows"); sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine();
else if (!header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) }
sb.AppendLine("\tApplication is aware of Windows, but doesn't use it"); else if(header.target_os == TargetOS.Borland)
else if (header.application_flags.HasFlag(ApplicationFlags.FullScreen) && header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) {
sb.AppendLine("\tApplication uses Windows"); sb.AppendLine("\tBorland Operating System Services application");
sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine(); sb.AppendFormat("\tApplication requires DOS {0}.{1} to run", header.os_major, header.os_minor)
sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine(); .AppendLine();
} if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
else !header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
{ sb.AppendLine("\tApplication is full screen, unaware of Windows");
sb.AppendFormat("\tApplication for unknown OS {0}", (byte)header.target_os).AppendLine(); else if(!header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
sb.AppendFormat("\tApplication requires OS {0}.{1} to run", header.os_major, header.os_minor).AppendLine(); header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine(); sb.AppendLine("\tApplication is aware of Windows, but doesn't use it");
sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine(); else if(header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
} header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
sb.AppendLine("\tApplication uses Windows");
sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine();
sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine();
}
else
{
sb.AppendFormat("\tApplication for unknown OS {0}", (byte)header.target_os).AppendLine();
sb.AppendFormat("\tApplication requires OS {0}.{1} to run", header.os_major, header.os_minor)
.AppendLine();
sb.AppendFormat("\tReturn thunks are at: {0}", header.return_thunks_offset).AppendLine();
sb.AppendFormat("\tSegment reference thunks are at: {0}", header.segment_reference_thunks).AppendLine();
}
if (header.application_flags.HasFlag(ApplicationFlags.Errors)) if(header.application_flags.HasFlag(ApplicationFlags.Errors)) sb.AppendLine("\tExecutable has errors");
sb.AppendLine("\tExecutable has errors"); if(header.application_flags.HasFlag(ApplicationFlags.NonConforming))
if (header.application_flags.HasFlag(ApplicationFlags.NonConforming)) sb.AppendLine("\tExecutable is non conforming");
sb.AppendLine("\tExecutable is non conforming"); if(header.application_flags.HasFlag(ApplicationFlags.DLL))
if (header.application_flags.HasFlag(ApplicationFlags.DLL)) sb.AppendLine("\tExecutable is a dynamic library or a driver");
sb.AppendLine("\tExecutable is a dynamic library or a driver");
sb.AppendFormat("\tMinimum code swap area: {0} bytes", header.minimum_swap_area).AppendLine(); sb.AppendFormat("\tMinimum code swap area: {0} bytes", header.minimum_swap_area).AppendLine();
sb.AppendFormat("\tFile alignment shift: {0}", 512 << header.alignment_shift).AppendLine(); sb.AppendFormat("\tFile alignment shift: {0}", 512 << header.alignment_shift).AppendLine();
sb.AppendFormat("\tInitial local heap should be {0} bytes", header.initial_heap).AppendLine(); sb.AppendFormat("\tInitial local heap should be {0} bytes", header.initial_heap).AppendLine();
sb.AppendFormat("\tInitial stack size should be {0} bytes", header.initial_stack).AppendLine(); sb.AppendFormat("\tInitial stack size should be {0} bytes", header.initial_stack).AppendLine();
sb.AppendFormat("\tCS:IP entry point: {0:X4}:{1:X4}", (header.entry_point & 0xFFFF0000) >> 16, header.entry_point & 0xFFFF).AppendLine(); sb.AppendFormat("\tCS:IP entry point: {0:X4}:{1:X4}", (header.entry_point & 0xFFFF0000) >> 16,
if (!header.application_flags.HasFlag(ApplicationFlags.DLL)) header.entry_point & 0xFFFF).AppendLine();
sb.AppendFormat("\tSS:SP initial stack pointer: {0:X4}:{1:X4}", (header.stack_pointer & 0xFFFF0000) >> 16, header.stack_pointer & 0xFFFF).AppendLine(); if(!header.application_flags.HasFlag(ApplicationFlags.DLL))
sb.AppendFormat("\tEntry table starts at {0} and runs for {1} bytes", header.entry_table_offset, header.entry_table_length).AppendLine(); sb.AppendFormat("\tSS:SP initial stack pointer: {0:X4}:{1:X4}",
sb.AppendFormat("\tSegment table starts at {0} and contain {1} segments", header.segment_table_offset, header.segment_count).AppendLine(); (header.stack_pointer & 0xFFFF0000) >> 16, header.stack_pointer & 0xFFFF).AppendLine();
sb.AppendFormat("\tModule reference table starts at {0} and contain {1} references", header.module_reference_offset, header.reference_count).AppendLine(); sb.AppendFormat("\tEntry table starts at {0} and runs for {1} bytes", header.entry_table_offset,
sb.AppendFormat("\tNon-resident names table starts at {0} and runs for {1} bytes", header.nonresident_names_offset, header.nonresident_table_size).AppendLine(); header.entry_table_length).AppendLine();
sb.AppendFormat("\tResources table starts at {0} and contains {1} entries", header.resource_table_offset, header.resource_entries).AppendLine(); sb.AppendFormat("\tSegment table starts at {0} and contain {1} segments", header.segment_table_offset,
sb.AppendFormat("\tResident names table starts at {0}", header.resident_names_offset).AppendLine(); header.segment_count).AppendLine();
sb.AppendFormat("\tImported names table starts at {0}", header.imported_names_offset).AppendLine(); sb.AppendFormat("\tModule reference table starts at {0} and contain {1} references",
header.module_reference_offset, header.reference_count).AppendLine();
sb.AppendFormat("\tNon-resident names table starts at {0} and runs for {1} bytes",
header.nonresident_names_offset, header.nonresident_table_size).AppendLine();
sb.AppendFormat("\tResources table starts at {0} and contains {1} entries", header.resource_table_offset,
header.resource_entries).AppendLine();
sb.AppendFormat("\tResident names table starts at {0}", header.resident_names_offset).AppendLine();
sb.AppendFormat("\tImported names table starts at {0}", header.imported_names_offset).AppendLine();
return sb.ToString(); return sb.ToString();
} }
public string GetInfo() public string GetInfo()
{ {
@@ -172,92 +198,92 @@ namespace libexeinfo
} }
public static ResourceTable GetResources(FileStream stream, uint neStart, ushort tableOff) 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];
byte[] DD = new byte[4]; byte[] DD = new byte[4];
stream.Position = neStart + tableOff; stream.Position = neStart + tableOff;
ResourceTable table = new ResourceTable(); ResourceTable table = new ResourceTable();
stream.Read(DW, 0, 2); stream.Read(DW, 0, 2);
table.alignment_shift = BitConverter.ToUInt16(DW, 0); table.alignment_shift = BitConverter.ToUInt16(DW, 0);
List<ResourceType> types = new List<ResourceType>(); List<ResourceType> types = new List<ResourceType>();
while (true) while(true)
{ {
ResourceType type = new ResourceType(); ResourceType type = new ResourceType();
stream.Read(DW, 0, 2); stream.Read(DW, 0, 2);
type.id = BitConverter.ToUInt16(DW, 0); type.id = BitConverter.ToUInt16(DW, 0);
if (type.id == 0) if(type.id == 0) break;
break;
stream.Read(DW, 0, 2); stream.Read(DW, 0, 2);
type.count = BitConverter.ToUInt16(DW, 0); type.count = BitConverter.ToUInt16(DW, 0);
stream.Read(DD, 0, 4); stream.Read(DD, 0, 4);
type.reserved = BitConverter.ToUInt32(DD, 0); type.reserved = BitConverter.ToUInt32(DD, 0);
type.resources = new Resource[type.count]; type.resources = new Resource[type.count];
for (int i = 0; i < type.count; i++) for(int i = 0; i < type.count; i++)
{ {
type.resources[i] = new Resource(); type.resources[i] = new Resource();
stream.Read(DW, 0, 2); stream.Read(DW, 0, 2);
type.resources[i].dataOffset = BitConverter.ToUInt16(DW, 0); type.resources[i].dataOffset = BitConverter.ToUInt16(DW, 0);
stream.Read(DW, 0, 2); stream.Read(DW, 0, 2);
type.resources[i].length = BitConverter.ToUInt16(DW, 0); type.resources[i].length = BitConverter.ToUInt16(DW, 0);
stream.Read(DW, 0, 2); stream.Read(DW, 0, 2);
type.resources[i].flags = (ResourceFlags)BitConverter.ToUInt16(DW, 0); type.resources[i].flags = (ResourceFlags)BitConverter.ToUInt16(DW, 0);
stream.Read(DW, 0, 2); stream.Read(DW, 0, 2);
type.resources[i].id = BitConverter.ToUInt16(DW, 0); type.resources[i].id = BitConverter.ToUInt16(DW, 0);
stream.Read(DD, 0, 4); stream.Read(DD, 0, 4);
type.resources[i].reserved = BitConverter.ToUInt32(DD, 0); type.resources[i].reserved = BitConverter.ToUInt32(DD, 0);
} }
types.Add(type); types.Add(type);
System.Console.WriteLine("{0}", stream.Position); Console.WriteLine("{0}", stream.Position);
} }
table.types = types.ToArray(); table.types = types.ToArray();
for (int t = 0; t < table.types.Length; t++) for(int t = 0; t < table.types.Length; t++)
{ {
if ((table.types[t].id & 0x8000) == 0) if((table.types[t].id & 0x8000) == 0)
{ {
byte len; byte len;
byte[] str; byte[] str;
stream.Position = neStart + tableOff + table.types[t].id; stream.Position = neStart + tableOff + table.types[t].id;
len = (byte)stream.ReadByte(); len = (byte)stream.ReadByte();
str = new byte[len]; str = new byte[len];
stream.Read(str, 0, len); stream.Read(str, 0, len);
table.types[t].name = Encoding.ASCII.GetString(str); table.types[t].name = Encoding.ASCII.GetString(str);
} }
else else table.types[t].name = ResourceIdToName(table.types[t].id);
table.types[t].name = ResourceIdToName(table.types[t].id);
for (int r = 0; r < table.types[t].resources.Length; r++) for(int r = 0; r < table.types[t].resources.Length; r++)
{ {
if ((table.types[t].resources[r].id & 0x8000) == 0) if((table.types[t].resources[r].id & 0x8000) == 0)
{ {
byte len; byte len;
byte[] str; byte[] str;
stream.Position = neStart + tableOff + table.types[t].resources[r].id; stream.Position = neStart + tableOff + table.types[t].resources[r].id;
len = (byte)stream.ReadByte(); len = (byte)stream.ReadByte();
str = new byte[len]; str = new byte[len];
stream.Read(str, 0, len); stream.Read(str, 0, len);
table.types[t].resources[r].name = Encoding.ASCII.GetString(str); table.types[t].resources[r].name = Encoding.ASCII.GetString(str);
} }
else else
table.types[t].resources[r].name = string.Format("{0}", table.types[t].resources[r].id & 0x7FFF); table.types[t].resources[r].name =
string.Format("{0}", table.types[t].resources[r].id & 0x7FFF);
table.types[t].resources[r].data = new byte[table.types[t].resources[r].length * (1 << table.alignment_shift)]; table.types[t].resources[r].data =
stream.Position = table.types[t].resources[r].dataOffset * (1 << table.alignment_shift); new byte[table.types[t].resources[r].length * (1 << table.alignment_shift)];
stream.Read(table.types[t].resources[r].data, 0, table.types[t].resources[r].data.Length); stream.Position = table.types[t].resources[r].dataOffset * (1 << table.alignment_shift);
} stream.Read(table.types[t].resources[r].data, 0, table.types[t].resources[r].data.Length);
} }
}
stream.Position = oldPosition; stream.Position = oldPosition;
return table; return table;
} }
} }
} }

View File

@@ -23,6 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -30,144 +31,138 @@ using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
{ {
/// <summary> /// <summary>
/// Represents a Microsoft New Executable /// Represents a Microsoft New Executable
/// </summary> /// </summary>
public partial class NE public partial class NE
{ {
/// <summary> public readonly MZ BaseExecutable;
/// The <see cref="FileStream"/> that contains the executable represented by this instance /// <summary>
/// </summary> /// The <see cref="FileStream" /> that contains the executable represented by this instance
public readonly FileStream BaseStream; /// </summary>
/// <summary> public readonly FileStream BaseStream;
/// Header for this executable /// <summary>
/// </summary> /// Header for this executable
public readonly NEHeader Header; /// </summary>
/// <summary> public readonly NEHeader Header;
/// If true this instance correctly represents a Microsoft New Executable /// <summary>
/// </summary> /// If true this instance correctly represents a Microsoft New Executable
public readonly bool IsNE; /// </summary>
public readonly MZ BaseExecutable; public readonly bool IsNE;
public readonly ResourceTable Resources; public readonly ResourceTable Resources;
public readonly Version[] Versions; 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.
/// </summary> /// </summary>
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public NE(string path) public NE(string path)
{ {
IsNE = false; IsNE = false;
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseExecutable = new MZ(BaseStream); BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ {
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);
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 = (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)
{ {
IsNE = true; IsNE = true;
if (Header.resource_entries > 0) if(Header.resource_entries > 0)
{
Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Header.resource_table_offset);
Versions = GetVersions().ToArray();
}
}
}
}
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE"/> class.
/// </summary>
/// <param name="stream">Stream containing the executable.</param>
public NE(FileStream 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); Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset,
Header.resource_table_offset);
Versions = GetVersions().ToArray(); Versions = GetVersions().ToArray();
} }
} }
} }
} }
}
/// <summary> /// <summary>
/// Identifies if the specified executable is a Microsoft New Executable /// Initializes a new instance of the <see cref="T:libexeinfo.NE" /> class.
/// </summary> /// </summary>
/// <returns><c>true</c> if the specified executable is a Microsoft New Executable, <c>false</c> otherwise.</returns> /// <param name="stream">Stream containing the executable.</param>
/// <param name="path">Executable path.</param> public NE(FileStream stream)
public static bool Identify(string path) {
{ IsNE = false;
FileStream BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = stream;
MZ BaseExecutable = new MZ(BaseStream); BaseExecutable = new MZ(BaseStream);
if (BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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 = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader));
NEHeader Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); Marshal.FreeHGlobal(hdrPtr);
Marshal.FreeHGlobal(hdrPtr); if(Header.signature == Signature)
return 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>
/// Identifies if the specified executable is a Microsoft New Executable
/// </summary>
/// <returns><c>true</c> if the specified executable is a Microsoft New Executable, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param>
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;
}
return false; 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>
/// <returns><c>true</c> if the specified executable is a Microsoft New Executable, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Microsoft New 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(FileStream stream)
{ {
FileStream BaseStream = stream; FileStream BaseStream = stream;
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if (BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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); NEHeader Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader));
NEHeader Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); Marshal.FreeHGlobal(hdrPtr);
Marshal.FreeHGlobal(hdrPtr); return Header.signature == Signature;
return Header.signature == Signature; }
}
}
return false; return false;
} }
} }
} }

View File

@@ -24,7 +24,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
@@ -32,62 +31,62 @@ namespace libexeinfo
public partial class NE public partial class NE
{ {
/// <summary> /// <summary>
/// Header for a Microsoft New Executable /// Header for a Microsoft New Executable
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct NEHeader public struct NEHeader
{ {
public ushort signature; public ushort signature;
public byte linker_major; public byte linker_major;
public byte linker_minor; public byte linker_minor;
public ushort entry_table_offset; public ushort entry_table_offset;
public ushort entry_table_length; public ushort entry_table_length;
public uint crc; public uint crc;
public ProgramFlags program_flags; public ProgramFlags program_flags;
public ApplicationFlags application_flags; public ApplicationFlags application_flags;
public byte auto_data_segment_index; public byte auto_data_segment_index;
public ushort initial_heap; public ushort initial_heap;
public ushort initial_stack; public ushort initial_stack;
public uint entry_point; public uint entry_point;
public uint stack_pointer; public uint stack_pointer;
public ushort segment_count; public ushort segment_count;
public ushort reference_count; public ushort reference_count;
public ushort nonresident_table_size; public ushort nonresident_table_size;
public ushort segment_table_offset; public ushort segment_table_offset;
public ushort resource_table_offset; public ushort resource_table_offset;
public ushort resident_names_offset; public ushort resident_names_offset;
public ushort module_reference_offset; public ushort module_reference_offset;
public ushort imported_names_offset; public ushort imported_names_offset;
public uint nonresident_names_offset; public uint nonresident_names_offset;
public ushort movable_entries; public ushort movable_entries;
public ushort alignment_shift; public ushort alignment_shift;
public ushort resource_entries; public ushort resource_entries;
public TargetOS target_os; public TargetOS target_os;
public OS2Flags os2_flags; public OS2Flags os2_flags;
public ushort return_thunks_offset; public ushort return_thunks_offset;
public ushort segment_reference_thunks; public ushort segment_reference_thunks;
public ushort minimum_swap_area; public ushort minimum_swap_area;
public byte os_minor; public byte os_minor;
public byte os_major; public byte os_major;
} }
/// <summary> /// <summary>
/// Resource table /// Resource table
/// </summary> /// </summary>
public struct ResourceTable public struct ResourceTable
{ {
public ushort alignment_shift; public ushort alignment_shift;
public ResourceType[] types; public ResourceType[] types;
} }
/// <summary> /// <summary>
/// Resource type /// Resource type
/// </summary> /// </summary>
public struct ResourceType public struct ResourceType
{ {
public ushort id; public ushort id;
public ushort count; public ushort count;
public uint reserved; public uint reserved;
public Resource[] resources; public Resource[] resources;
// Not sequentially stored // Not sequentially stored
@@ -95,15 +94,15 @@ namespace libexeinfo
} }
/// <summary> /// <summary>
/// Resource /// Resource
/// </summary> /// </summary>
public struct Resource public struct Resource
{ {
public ushort dataOffset; public ushort dataOffset;
public ushort length; public ushort length;
public ResourceFlags flags; public ResourceFlags flags;
public ushort id; public ushort id;
public uint reserved; public uint reserved;
// Not sequentially stored // Not sequentially stored
public string name; public string name;
@@ -111,36 +110,36 @@ namespace libexeinfo
} }
/// <summary> /// <summary>
/// Node in a version resource /// Node in a version resource
/// </summary> /// </summary>
class VersionNode class VersionNode
{ {
public ushort cbNode; public ushort cbData;
public ushort cbData; public ushort cbNode;
public string szName;
public byte[] rgbData;
public VersionNode[] children; public VersionNode[] children;
public byte[] rgbData;
public string szName;
} }
/// <summary> /// <summary>
/// Fixed file version info /// Fixed file version info
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public class FixedFileInfo public class FixedFileInfo
{ {
public uint dwFileDateLS;
public uint dwFileDateMS;
public uint dwFileFlags;
public uint dwFileFlagsMask;
public uint dwFileOS;
public uint dwFileSubtype;
public uint dwFileType;
public uint dwFileVersionLS;
public uint dwFileVersionMS;
public uint dwProductVersionLS;
public uint dwProductVersionMS;
public uint dwSignature; public uint dwSignature;
public uint dwStrucVersion; public uint dwStrucVersion;
public uint dwFileVersionMS;
public uint dwFileVersionLS;
public uint dwProductVersionMS;
public uint dwProductVersionLS;
public uint dwFileFlagsMask;
public uint dwFileFlags;
public uint dwFileOS;
public uint dwFileType;
public uint dwFileSubtype;
public uint dwFileDateMS;
public uint dwFileDateLS;
} }
} }
} }

View File

@@ -35,152 +35,39 @@ namespace libexeinfo
public partial class NE public partial class NE
{ {
/// <summary> /// <summary>
/// Gets all the version resources from this instance /// Gets all the version resources from this instance
/// </summary> /// </summary>
/// <returns>The decoded version resources.</returns> /// <returns>The decoded version resources.</returns>
public List<Version> GetVersions() public List<Version> GetVersions()
{ {
List<Version> versions = new List<Version>(); List<Version> versions = new List<Version>();
foreach (ResourceType type in Resources.types) foreach(ResourceType type in Resources.types)
{ if((type.id & 0x7FFF) == (int)ResourceTypes.RT_VERSION)
if ((type.id & 0x7FFF) == (int)ResourceTypes.RT_VERSION) foreach(Resource resource in type.resources)
{
foreach (Resource resource in type.resources)
{ {
Version vers = new Version(resource.data, resource.name); Version vers = new Version(resource.data, resource.name);
versions.Add(vers); versions.Add(vers);
} }
}
}
return versions; return versions;
} }
/// <summary> /// <summary>
/// Represents a version ("RT_VERSION") resource /// Represents a version ("RT_VERSION") resource
/// </summary> /// </summary>
public class Version public class Version
{ {
/// <summary>
/// This contains a list of all name=value strings pairs sorted by language
/// </summary>
/// <value>List of all name=value strings pairs sorted by language.</value>
public Dictionary<string, Dictionary<string, string>> StringsByLanguage { get; }
string fileVersion;
string productVersion;
VersionFileFlags fileFlags;
VersionFileOS fileOS;
VersionFileType fileType;
VersionFileSubtype fileSubtype;
DateTime fileDate;
string name;
/// <summary> /// <summary>
/// File version. /// Initializes a new instance of the <see cref="T:libexeinfo.NE.Version" /> class.
/// </summary>
/// <value>The file version.</value>
public string FileVersion
{
get
{
return fileVersion;
}
}
/// <summary>
/// Product version.
/// </summary>
/// <value>The product version.</value>
public string ProductVersion
{
get
{
return productVersion;
}
}
/// <summary>
/// File flags.
/// </summary>
/// <value>The file flags.</value>
public VersionFileFlags FileFlags
{
get
{
return fileFlags;
}
}
/// <summary>
/// File operating system.
/// </summary>
/// <value>The file operating system.</value>
public VersionFileOS FileOS
{
get
{
return fileOS;
}
}
/// <summary>
/// File type.
/// </summary>
/// <value>The type of the file.</value>
public VersionFileType FileType
{
get
{
return fileType;
}
}
/// <summary>
/// File subtype.
/// </summary>
/// <value>The file subtype.</value>
public VersionFileSubtype FileSubtype
{
get
{
return fileSubtype;
}
}
/// <summary>
/// File date.
/// </summary>
/// <value>The file date.</value>
public DateTime FileDate
{
get
{
return fileDate;
}
}
/// <summary>
/// Resource name
/// </summary>
/// <value>The resource name.</value>
public string Name
{
get { return name; }
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.NE.Version"/> class.
/// </summary> /// </summary>
/// <param name="data">Resource data.</param> /// <param name="data">Resource data.</param>
/// <param name="resourceName">Resource name.</param> /// <param name="resourceName">Resource name.</param>
public Version(byte[] data, string resourceName = null) public Version(byte[] data, string resourceName = null)
{ {
if (data == null || data.Length < 5) if(data == null || data.Length < 5) return;
return;
name = resourceName; Name = resourceName;
StringsByLanguage = new Dictionary<string, Dictionary<string, string>>(); StringsByLanguage = new Dictionary<string, Dictionary<string, string>>();
@@ -188,6 +75,60 @@ namespace libexeinfo
DecodeNode(root, null, null); DecodeNode(root, null, null);
} }
/// <summary>
/// This contains a list of all name=value strings pairs sorted by language
/// </summary>
/// <value>List of all name=value strings pairs sorted by language.</value>
public Dictionary<string, Dictionary<string, string>> StringsByLanguage { get; }
/// <summary>
/// File version.
/// </summary>
/// <value>The file version.</value>
public string FileVersion { get; set; }
/// <summary>
/// Product version.
/// </summary>
/// <value>The product version.</value>
public string ProductVersion { get; set; }
/// <summary>
/// File flags.
/// </summary>
/// <value>The file flags.</value>
public VersionFileFlags FileFlags { get; set; }
/// <summary>
/// File operating system.
/// </summary>
/// <value>The file operating system.</value>
public VersionFileOS FileOS { get; set; }
/// <summary>
/// File type.
/// </summary>
/// <value>The type of the file.</value>
public VersionFileType FileType { get; set; }
/// <summary>
/// File subtype.
/// </summary>
/// <value>The file subtype.</value>
public VersionFileSubtype FileSubtype { get; set; }
/// <summary>
/// File date.
/// </summary>
/// <value>The file date.</value>
public DateTime FileDate { get; set; }
/// <summary>
/// Resource name
/// </summary>
/// <value>The resource name.</value>
public string Name { get; }
VersionNode GetNode(byte[] data, int startPosition, out int nodeLength) VersionNode GetNode(byte[] data, int startPosition, out int nodeLength)
{ {
nodeLength = 0; nodeLength = 0;
@@ -200,240 +141,196 @@ namespace libexeinfo
nodeLength += 4; nodeLength += 4;
MemoryStream nameMs = new MemoryStream(); MemoryStream nameMs = new MemoryStream();
while (data[startPosition + nodeLength] > 0) while(data[startPosition + nodeLength] > 0)
{ {
nameMs.WriteByte(data[startPosition + nodeLength]); nameMs.WriteByte(data[startPosition + nodeLength]);
nodeLength++; nodeLength++;
} }
node.szName = Encoding.ASCII.GetString(nameMs.ToArray()); node.szName = Encoding.ASCII.GetString(nameMs.ToArray());
nodeLength++; nodeLength++;
if (nodeLength % 4 > 0) if(nodeLength % 4 > 0) nodeLength += 4 - nodeLength % 4;
nodeLength += 4 - (nodeLength % 4);
node.rgbData = new byte[node.cbData]; node.rgbData = new byte[node.cbData];
Array.Copy(data, startPosition + nodeLength, node.rgbData, 0, node.cbData); Array.Copy(data, startPosition + nodeLength, node.rgbData, 0, node.cbData);
nodeLength += node.cbData; nodeLength += node.cbData;
if (nodeLength % 4 > 0) if(nodeLength % 4 > 0) nodeLength += 4 - nodeLength % 4;
nodeLength += 4 - (nodeLength % 4);
List<VersionNode> children = new List<VersionNode>(); List<VersionNode> children = new List<VersionNode>();
while (nodeLength < node.cbNode) while(nodeLength < node.cbNode)
{ {
children.Add(GetNode(data, startPosition + nodeLength, out int childLength)); children.Add(GetNode(data, startPosition + nodeLength, out int childLength));
nodeLength += childLength; nodeLength += childLength;
} }
if (children.Count > 0) if(children.Count > 0) node.children = children.ToArray();
node.children = children.ToArray();
return node; return node;
} }
void DecodeNode(VersionNode node, string parent, string grandparent) void DecodeNode(VersionNode node, string parent, string grandparent)
{ {
if (node.szName == FixedFileInfoSig) if(node.szName == FixedFileInfoSig)
{ {
IntPtr infoPtr = Marshal.AllocHGlobal(node.cbData); IntPtr infoPtr = Marshal.AllocHGlobal(node.cbData);
Marshal.Copy(node.rgbData, 0, infoPtr, node.cbData); Marshal.Copy(node.rgbData, 0, infoPtr, node.cbData);
FixedFileInfo info = (FixedFileInfo)Marshal.PtrToStructure(infoPtr, typeof(FixedFileInfo)); FixedFileInfo info = (FixedFileInfo)Marshal.PtrToStructure(infoPtr, typeof(FixedFileInfo));
Marshal.FreeHGlobal(infoPtr); Marshal.FreeHGlobal(infoPtr);
fileVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwFileVersionMS & 0xFFFF0000) >> 16, info.dwFileVersionMS & 0xFFFF, FileVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwFileVersionMS & 0xFFFF0000) >> 16,
(info.dwFileVersionLS & 0xFFFF0000) >> 16, info.dwFileVersionLS & 0xFFFF); info.dwFileVersionMS & 0xFFFF,
productVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwProductVersionMS & 0xFFFF0000) >> 16, info.dwProductVersionMS & 0xFFFF, (info.dwFileVersionLS & 0xFFFF0000) >> 16,
(info.dwProductVersionLS & 0xFFFF0000) >> 16, info.dwProductVersionLS & 0xFFFF); info.dwFileVersionLS & 0xFFFF);
fileFlags = (VersionFileFlags)(info.dwFileFlags & info.dwFileFlagsMask); ProductVersion = string.Format("{0}.{1:D2}.{2}.{3}", (info.dwProductVersionMS & 0xFFFF0000) >> 16,
fileOS = (VersionFileOS)info.dwFileOS; info.dwProductVersionMS & 0xFFFF,
fileType = (VersionFileType)info.dwFileType; (info.dwProductVersionLS & 0xFFFF0000) >> 16,
fileSubtype = (VersionFileSubtype)info.dwFileSubtype; info.dwProductVersionLS & 0xFFFF);
fileDate = DateTime.FromFileTime(info.dwFileDateMS * 0x100000000 + info.dwFileDateLS); FileFlags =
(VersionFileFlags)(info.dwFileFlags & info.dwFileFlagsMask);
FileOS = (VersionFileOS)info.dwFileOS;
FileType = (VersionFileType)info.dwFileType;
FileSubtype = (VersionFileSubtype)info.dwFileSubtype;
FileDate = DateTime.FromFileTime(info.dwFileDateMS * 0x100000000 + info.dwFileDateLS);
} }
if (parent == StringFileInfo) if(parent == StringFileInfo)
{ {
Dictionary<string, string> strings = new Dictionary<string, string>(); Dictionary<string, string> strings = new Dictionary<string, string>();
StringsByLanguage.Add(node.szName, strings); StringsByLanguage.Add(node.szName, strings);
} }
if (grandparent == StringFileInfo) if(grandparent == StringFileInfo)
{ if(StringsByLanguage.TryGetValue(parent, out Dictionary<string, string> strings))
if (StringsByLanguage.TryGetValue(parent, out Dictionary<string, string> strings))
{ {
Encoding encoding; Encoding encoding;
try try { encoding = Encoding.GetEncoding(Convert.ToInt32(parent.Substring(4), 16)); }
{ catch { encoding = Encoding.ASCII; }
encoding = Encoding.GetEncoding(Convert.ToInt32(parent.Substring(4), 16));
}
catch
{
encoding = Encoding.ASCII;
}
strings.Add(node.szName, encoding.GetString(node.rgbData)); strings.Add(node.szName, encoding.GetString(node.rgbData));
} }
}
if (node.children != null) if(node.children != null)
{ for(int i = 0; i < node.children.Length; i++)
for (int i = 0; i < node.children.Length; i++)
DecodeNode(node.children[i], node.szName, parent); DecodeNode(node.children[i], node.szName, parent);
}
/// <summary>
/// Converts a <see cref="VersionFileType" /> to string
/// </summary>
/// <returns>The string.</returns>
/// <param name="type">
/// <see cref="VersionFileType" />
/// </param>
public static string TypeToString(VersionFileType type)
{
switch(type)
{
case VersionFileType.VFT_APP: return "Application";
case VersionFileType.VFT_DLL: return "Dynamic-link library";
case VersionFileType.VFT_DRV: return "Device driver";
case VersionFileType.VFT_FONT: return "Font";
case VersionFileType.VFT_STATIC_LIB: return "Static-link library";
case VersionFileType.VFT_UNKNOWN: return "Unknown";
case VersionFileType.VFT_VXD: return "Virtual device";
default: return string.Format("Unknown type code {0}", (uint)type);
} }
} }
/// <summary> /// <summary>
/// Converts a <see cref="VersionFileType"/> to string /// Converts a <see cref="VersionFileSubtype" /> to string, considering file type to be a driver
/// </summary> /// </summary>
/// <returns>The string.</returns> /// <returns>The string.</returns>
/// <param name="type"><see cref="VersionFileType"/></param> /// <param name="subtype">
public static string TypeToString(VersionFileType type) /// <see cref="VersionFileSubtype" />
/// </param>
public static string DriverToString(VersionFileSubtype subtype)
{ {
switch (type) switch(subtype)
{ {
case VersionFileType.VFT_APP: case VersionFileSubtype.VFT2_DRV_COMM: return "Communications";
return "Application"; case VersionFileSubtype.VFT2_DRV_DISPLAY: return "Display";
case VersionFileType.VFT_DLL: case VersionFileSubtype.VFT2_DRV_INSTALLABLE: return "Installable";
return "Dynamic-link library"; case VersionFileSubtype.VFT2_DRV_KEYBOARD: return "Keyboard";
case VersionFileType.VFT_DRV: case VersionFileSubtype.VFT2_DRV_LANGUAGE: return "Language";
return "Device driver"; case VersionFileSubtype.VFT2_DRV_MOUSE: return "Mouse";
case VersionFileType.VFT_FONT: case VersionFileSubtype.VFT2_DRV_NETWORK: return "Network";
return "Font"; case VersionFileSubtype.VFT2_DRV_PRINTER: return "Printer";
case VersionFileType.VFT_STATIC_LIB: case VersionFileSubtype.VFT2_DRV_SOUND: return "Sound";
return "Static-link library"; case VersionFileSubtype.VFT2_DRV_SYSTEM: return "System";
case VersionFileType.VFT_UNKNOWN: case VersionFileSubtype.VFT2_DRV_VERSIONED_PRINTER: return "Versioned";
return "Unknown"; case VersionFileSubtype.VFT2_UNKNOWN: return "Unknown";
case VersionFileType.VFT_VXD:
return "Virtual device";
default:
return string.Format("Unknown type code {0}", (uint)type);
}
}
/// <summary>
/// Converts a <see cref="VersionFileSubtype"/> to string, considering file type to be a driver
/// </summary>
/// <returns>The string.</returns>
/// <param name="subtype"><see cref="VersionFileSubtype"/></param>
public static string DriverToString(VersionFileSubtype subtype)
{
switch (subtype)
{
case VersionFileSubtype.VFT2_DRV_COMM:
return "Communications";
case VersionFileSubtype.VFT2_DRV_DISPLAY:
return "Display";
case VersionFileSubtype.VFT2_DRV_INSTALLABLE:
return "Installable";
case VersionFileSubtype.VFT2_DRV_KEYBOARD:
return "Keyboard";
case VersionFileSubtype.VFT2_DRV_LANGUAGE:
return "Language";
case VersionFileSubtype.VFT2_DRV_MOUSE:
return "Mouse";
case VersionFileSubtype.VFT2_DRV_NETWORK:
return "Network";
case VersionFileSubtype.VFT2_DRV_PRINTER:
return "Printer";
case VersionFileSubtype.VFT2_DRV_SOUND:
return "Sound";
case VersionFileSubtype.VFT2_DRV_SYSTEM:
return "System";
case VersionFileSubtype.VFT2_DRV_VERSIONED_PRINTER:
return "Versioned";
case VersionFileSubtype.VFT2_UNKNOWN:
return "Unknown";
default: default:
return string.Format("Unknown type code {0}", (uint)subtype); return string.Format("Unknown type code {0}", (uint)subtype);
} }
} }
/// <summary> /// <summary>
/// Converts a <see cref="VersionFileSubtype"/> to string, considering file type to be a font /// Converts a <see cref="VersionFileSubtype" /> to string, considering file type to be a font
/// </summary> /// </summary>
/// <returns>The string.</returns> /// <returns>The string.</returns>
/// <param name="subtype"><see cref="VersionFileSubtype"/></param> /// <param name="subtype">
public static string FontToString(VersionFileSubtype subtype) /// <see cref="VersionFileSubtype" />
/// </param>
public static string FontToString(VersionFileSubtype subtype)
{ {
switch (subtype) switch(subtype)
{ {
case VersionFileSubtype.VFT2_FONT_RASTER: case VersionFileSubtype.VFT2_FONT_RASTER: return "Raster";
return "Raster"; case VersionFileSubtype.VFT2_FONT_TRUETYPE: return "TrueType";
case VersionFileSubtype.VFT2_FONT_TRUETYPE: case VersionFileSubtype.VFT2_FONT_VECTOR: return "Vector";
return "TrueType"; case VersionFileSubtype.VFT2_UNKNOWN: return "Unknown";
case VersionFileSubtype.VFT2_FONT_VECTOR:
return "Vector";
case VersionFileSubtype.VFT2_UNKNOWN:
return "Unknown";
default: default:
return string.Format("Unknown type code {0}", (uint)subtype); return string.Format("Unknown type code {0}", (uint)subtype);
} }
} }
/// <summary> /// <summary>
/// Converts a <see cref="VersionFileOS"/> to string /// Converts a <see cref="VersionFileOS" /> to string
/// </summary> /// </summary>
/// <returns>The string.</returns> /// <returns>The string.</returns>
/// <param name="os"><see cref="VersionFileOS"/></param> /// <param name="os">
public static string OsToString(VersionFileOS os) /// <see cref="VersionFileOS" />
/// </param>
public static string OsToString(VersionFileOS os)
{ {
switch (os) switch(os)
{ {
case VersionFileOS.VOS_DOS: case VersionFileOS.VOS_DOS: return "DOS";
return "DOS"; case VersionFileOS.VOS_NT: return "Windows NT";
case VersionFileOS.VOS_NT: case VersionFileOS.VOS_WINDOWS16: return "16-bit Windows";
return "Windows NT"; case VersionFileOS.VOS_WINDOWS32: return "32-bit Windows";
case VersionFileOS.VOS_WINDOWS16: case VersionFileOS.VOS_OS216: return "16-bit OS/2";
return "16-bit Windows"; case VersionFileOS.VOS_OS232: return "32-bit OS/2";
case VersionFileOS.VOS_WINDOWS32: case VersionFileOS.VOS_PM16: return "16-bit Presentation Manager";
return "32-bit Windows"; case VersionFileOS.VOS_PM32: return "32-bit Presentation Manager";
case VersionFileOS.VOS_OS216: case VersionFileOS.VOS_UNKNOWN: return "Unknown";
return "16-bit OS/2"; case VersionFileOS.VOS_DOS_NT: return "DOS running under Windows NT";
case VersionFileOS.VOS_OS232: case VersionFileOS.VOS_DOS_WINDOWS16: return "16-bit Windows running under DOS";
return "32-bit OS/2"; case VersionFileOS.VOS_DOS_WINDOWS32: return "32-bit Windows running under DOS";
case VersionFileOS.VOS_PM16: case VersionFileOS.VOS_DOS_PM16: return "16-bit Presentation Manager running under DOS";
return "16-bit Presentation Manager"; case VersionFileOS.VOS_DOS_PM32: return "32-bit Presentation Manager running under DOS";
case VersionFileOS.VOS_PM32: case VersionFileOS.VOS_NT_WINDOWS16: return "16-bit Windows running under Windows NT";
return "32-bit Presentation Manager"; case VersionFileOS.VOS_NT_WINDOWS32: return "32-bit Windows running under Windows NT";
case VersionFileOS.VOS_UNKNOWN:
return "Unknown";
case VersionFileOS.VOS_DOS_NT:
return "DOS running under Windows NT";
case VersionFileOS.VOS_DOS_WINDOWS16:
return "16-bit Windows running under DOS";
case VersionFileOS.VOS_DOS_WINDOWS32:
return "32-bit Windows running under DOS";
case VersionFileOS.VOS_DOS_PM16:
return "16-bit Presentation Manager running under DOS";
case VersionFileOS.VOS_DOS_PM32:
return "32-bit Presentation Manager running under DOS";
case VersionFileOS.VOS_NT_WINDOWS16:
return "16-bit Windows running under Windows NT";
case VersionFileOS.VOS_NT_WINDOWS32:
return "32-bit Windows running under Windows NT";
case VersionFileOS.VOS_NT_PM16: case VersionFileOS.VOS_NT_PM16:
return "16-bit Presentation Manager running under Windows NT"; return "16-bit Presentation Manager running under Windows NT";
case VersionFileOS.VOS_NT_PM32: case VersionFileOS.VOS_NT_PM32:
return "32-bit Presentation Manager running under Windows NT"; return "32-bit Presentation Manager running under Windows NT";
case VersionFileOS.VOS_OS216_WINDOWS16: case VersionFileOS.VOS_OS216_WINDOWS16: return "16-bit Windows running under 16-bit OS/2";
return "16-bit Windows running under 16-bit OS/2"; case VersionFileOS.VOS_OS216_WINDOWS32: return "32-bit Windows running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_WINDOWS32:
return "32-bit Windows running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_PM16: case VersionFileOS.VOS_OS216_PM16:
return "16-bit Presentation Manager running under 16-bit OS/2"; return "16-bit Presentation Manager running under 16-bit OS/2";
case VersionFileOS.VOS_OS216_PM32: case VersionFileOS.VOS_OS216_PM32:
return "32-bit Presentation Manager running under 16-bit OS/2"; return "32-bit Presentation Manager running under 16-bit OS/2";
case VersionFileOS.VOS_OS232_WINDOWS16: case VersionFileOS.VOS_OS232_WINDOWS16: return "16-bit Windows running under 32-bit OS/2";
return "16-bit Windows running under 32-bit OS/2"; case VersionFileOS.VOS_OS232_WINDOWS32: return "32-bit Windows running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_WINDOWS32:
return "32-bit Windows running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_PM16: case VersionFileOS.VOS_OS232_PM16:
return "16-bit Presentation Manager running under 32-bit OS/2"; return "16-bit Presentation Manager running under 32-bit OS/2";
case VersionFileOS.VOS_OS232_PM32: case VersionFileOS.VOS_OS232_PM32:
return "32-bit Presentation Manager running under 32-bit OS/2"; return "32-bit Presentation Manager running under 32-bit OS/2";
default: default: return string.Format("Unknown OS code {0}", (uint)os);
return string.Format("Unknown OS code {0}", (uint)os);
} }
} }
} }

View File

@@ -28,11 +28,11 @@ namespace libexeinfo
{ {
public partial class PE public partial class PE
{ {
/// <summary> /// <summary>
/// Portable Executable signature, "PE\0\0" /// Portable Executable signature, "PE\0\0"
/// </summary> /// </summary>
public const ushort Signature = 0x00004550; public const ushort Signature = 0x00004550;
public const ushort PE32 = COFF.ZMAGIC; public const ushort PE32 = COFF.ZMAGIC;
public const ushort PE32Plus = 0x20b; public const ushort PE32Plus = 0x20b;
} }
} }

View File

@@ -25,153 +25,155 @@
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class PE public partial class PE
{ {
/// <summary>
/// The following values defined for the Subsystem field of the optional header determine which Windows subsystem (if any) is required to run the image.
/// </summary>
public enum Subsystems : ushort
{
/// <summary>
/// An unknown subsystem
/// </summary>
IMAGE_SUBSYSTEM_UNKNOWN = 0,
/// <summary>
/// Device drivers and native Windows processes
/// </summary>
IMAGE_SUBSYSTEM_NATIVE = 1,
/// <summary>
/// The Windows graphical user interface (GUI) subsystem
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
/// <summary>
/// The Windows character subsystem
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
/// <summary>
/// The OS/2 character subsystem
/// </summary>
IMAGE_SUBSYSTEM_OS2_CUI = 5,
/// <summary>
/// The Posix character subsystem
/// </summary>
IMAGE_SUBSYSTEM_POSIX_CUI = 7,
/// <summary>
/// Native Win9x driver
/// </summary>
IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8,
/// <summary>
/// Windows CE
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
/// <summary>
/// An Extensible Firmware Interface (EFI) application
/// </summary>
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
/// <summary>
/// An EFI driver with boot services
/// </summary>
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
/// <summary>
/// An EFI driver with run-time services
/// </summary>
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
/// <summary>
/// An EFI ROM image
/// </summary>
IMAGE_SUBSYSTEM_EFI_ROM = 13,
/// <summary>
/// XBOX
/// </summary>
IMAGE_SUBSYSTEM_XBOX = 14,
/// <summary>
/// Windows boot application
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16
}
/// <summary>
/// The following values are defined for the DllCharacteristics field of the optional header.
/// </summary>
[Flags]
public enum DllCharacteristics : ushort
{
/// <summary>
/// Image can handle a high entropy 64-bit virtual address space.
/// </summary>
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
/// <summary>
/// DLL can be relocated at load time.
/// </summary>
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040,
/// <summary>
/// Code Integrity checks are enforced.
/// </summary>
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
/// <summary>
/// Image is NX compatible.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100,
/// <summary>
/// Isolation aware, but do not isolate the image.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
/// <summary>
/// Does not use structured exception (SE) handling. No SE handler may be called in this image.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
/// <summary>
/// Do not bind the image.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
/// <summary>
/// Image must execute in an AppContainer.
/// </summary>
IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000,
/// <summary>
/// A WDM driver.
/// </summary>
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
/// <summary>
/// Image supports Control Flow Guard.
/// </summary>
IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000,
/// <summary>
/// Terminal Server aware.
/// </summary>
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
}
public enum DebugTypes : uint public enum DebugTypes : uint
{ {
/// <summary> /// <summary>
/// Unknown value, ignored by all tools. /// Unknown value, ignored by all tools.
/// </summary> /// </summary>
IMAGE_DEBUG_TYPE_UNKNOWN = 0, IMAGE_DEBUG_TYPE_UNKNOWN = 0,
/// <summary> /// <summary>
/// COFF debug information (line numbers, symbol table, and string table). /// 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. /// This type of debug information is also pointed to by fields in the file headers.
/// </summary> /// </summary>
IMAGE_DEBUG_TYPE_COFF = 1, IMAGE_DEBUG_TYPE_COFF = 1,
/// <summary> /// <summary>
/// CodeView debug information. The format of the data block is described /// CodeView debug information. The format of the data block is described
/// by the CV4 specification. /// by the CV4 specification.
/// </summary> /// </summary>
IMAGE_DEBUG_TYPE_CODEVIEW = 2, IMAGE_DEBUG_TYPE_CODEVIEW = 2,
/// <summary> /// <summary>
/// Frame Pointer Omission (FPO) information. This information tells the /// Frame Pointer Omission (FPO) information. This information tells the
/// debugger how to interpret non-standard stack frames, which use the /// debugger how to interpret non-standard stack frames, which use the
/// EBP register for a purpose other than as a frame pointer. /// EBP register for a purpose other than as a frame pointer.
/// </summary> /// </summary>
IMAGE_DEBUG_TYPE_FPO = 3, IMAGE_DEBUG_TYPE_FPO = 3,
IMAGE_DEBUG_TYPE_MISC = 4, IMAGE_DEBUG_TYPE_MISC = 4,
IMAGE_DEBUG_TYPE_EXCEPTION = 5, IMAGE_DEBUG_TYPE_EXCEPTION = 5,
IMAGE_DEBUG_TYPE_FIXUP = 6, IMAGE_DEBUG_TYPE_FIXUP = 6,
IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7, IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8, IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
IMAGE_DEBUG_TYPE_BORLAND = 9 IMAGE_DEBUG_TYPE_BORLAND = 9
}
/// <summary>
/// The following values are defined for the DllCharacteristics field of the optional header.
/// </summary>
[Flags]
public enum DllCharacteristics : ushort
{
/// <summary>
/// Image can handle a high entropy 64-bit virtual address space.
/// </summary>
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
/// <summary>
/// DLL can be relocated at load time.
/// </summary>
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040,
/// <summary>
/// Code Integrity checks are enforced.
/// </summary>
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
/// <summary>
/// Image is NX compatible.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100,
/// <summary>
/// Isolation aware, but do not isolate the image.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
/// <summary>
/// Does not use structured exception (SE) handling. No SE handler may be called in this image.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
/// <summary>
/// Do not bind the image.
/// </summary>
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
/// <summary>
/// Image must execute in an AppContainer.
/// </summary>
IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000,
/// <summary>
/// A WDM driver.
/// </summary>
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
/// <summary>
/// Image supports Control Flow Guard.
/// </summary>
IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000,
/// <summary>
/// Terminal Server aware.
/// </summary>
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
}
/// <summary>
/// The following values defined for the Subsystem field of the optional header determine which Windows subsystem (if
/// any) is required to run the image.
/// </summary>
public enum Subsystems : ushort
{
/// <summary>
/// An unknown subsystem
/// </summary>
IMAGE_SUBSYSTEM_UNKNOWN = 0,
/// <summary>
/// Device drivers and native Windows processes
/// </summary>
IMAGE_SUBSYSTEM_NATIVE = 1,
/// <summary>
/// The Windows graphical user interface (GUI) subsystem
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
/// <summary>
/// The Windows character subsystem
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
/// <summary>
/// The OS/2 character subsystem
/// </summary>
IMAGE_SUBSYSTEM_OS2_CUI = 5,
/// <summary>
/// The Posix character subsystem
/// </summary>
IMAGE_SUBSYSTEM_POSIX_CUI = 7,
/// <summary>
/// Native Win9x driver
/// </summary>
IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8,
/// <summary>
/// Windows CE
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
/// <summary>
/// An Extensible Firmware Interface (EFI) application
/// </summary>
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
/// <summary>
/// An EFI driver with boot services
/// </summary>
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
/// <summary>
/// An EFI driver with run-time services
/// </summary>
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
/// <summary>
/// An EFI ROM image
/// </summary>
IMAGE_SUBSYSTEM_EFI_ROM = 13,
/// <summary>
/// XBOX
/// </summary>
IMAGE_SUBSYSTEM_XBOX = 14,
/// <summary>
/// Windows boot application
/// </summary>
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16
} }
} }
} }

View File

@@ -24,77 +24,83 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
namespace libexeinfo namespace libexeinfo
{ {
public partial class PE public partial class PE
{ {
public static string GetInfo(PEHeader header, WindowsHeader64 winheader) public static string GetInfo(PEHeader header, WindowsHeader64 winheader)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.Append(COFF.GetInfo(header.coff)); sb.Append(COFF.GetInfo(header.coff));
sb.AppendLine("Portable Executable (PE):"); sb.AppendLine("Portable Executable (PE):");
if(header.coff.optionalHeader.magic == PE32Plus) if(header.coff.optionalHeader.magic == PE32Plus)
sb.AppendFormat("\tExecutable base address: 0x{0:X16}", winheader.imageBase).AppendLine(); sb.AppendFormat("\tExecutable base address: 0x{0:X16}", winheader.imageBase).AppendLine();
else else sb.AppendFormat("\tExecutable base address: 0x{0:X8}", winheader.imageBase).AppendLine();
sb.AppendFormat("\tExecutable base address: 0x{0:X8}", winheader.imageBase).AppendLine(); sb.AppendFormat("\tSections are aligned to {0} bytes", winheader.sectionAlignment).AppendLine();
sb.AppendFormat("\tSections are aligned to {0} bytes", winheader.sectionAlignment).AppendLine(); sb.AppendFormat("\tFile is aligned to {0} bytes", winheader.fileAlignment).AppendLine();
sb.AppendFormat("\tFile is aligned to {0} bytes", winheader.fileAlignment).AppendLine();
if(winheader.majorOperatingSystemVersion > 0 || winheader.minorOperatingSystemVersion > 0) if(winheader.majorOperatingSystemVersion > 0 || winheader.minorOperatingSystemVersion > 0)
sb.AppendFormat("\tExecutable requires at least operating system version {0}.{1} to run", winheader.majorOperatingSystemVersion, winheader.minorOperatingSystemVersion).AppendLine(); sb.AppendFormat("\tExecutable requires at least operating system version {0}.{1} to run",
if (winheader.majorImageVersion > 0 || winheader.minorImageVersion > 0) winheader.majorOperatingSystemVersion, winheader.minorOperatingSystemVersion)
sb.AppendFormat("\tExecutable version: {0}.{1}", winheader.majorImageVersion, winheader.minorImageVersion).AppendLine(); .AppendLine();
sb.AppendFormat("\tAccording to subsystem, executable is {0}", SubsystemToString(winheader.subsystem)).AppendLine(); if(winheader.majorImageVersion > 0 || winheader.minorImageVersion > 0)
if (winheader.majorSubsystemVersion > 0 || winheader.minorSubsystemVersion > 0) sb.AppendFormat("\tExecutable version: {0}.{1}", winheader.majorImageVersion,
sb.AppendFormat("\tExecutable requires at least subsystem version {0}.{1} to run", winheader.majorSubsystemVersion, winheader.minorSubsystemVersion).AppendLine(); winheader.minorImageVersion).AppendLine();
sb.AppendFormat("\tAccording to subsystem, executable is {0}", SubsystemToString(winheader.subsystem))
.AppendLine();
if(winheader.majorSubsystemVersion > 0 || winheader.minorSubsystemVersion > 0)
sb.AppendFormat("\tExecutable requires at least subsystem version {0}.{1} to run",
winheader.majorSubsystemVersion, winheader.minorSubsystemVersion).AppendLine();
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA))
sb.AppendLine("\tExecutable can handle a high entropy 64-bit virtual address space"); sb.AppendLine("\tExecutable can handle a high entropy 64-bit virtual address space");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE))
sb.AppendLine("\tExecutable can be relocated at load time"); sb.AppendLine("\tExecutable can be relocated at load time");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY))
sb.AppendLine("\tCode Integrity checks are enforced"); sb.AppendLine("\tCode Integrity checks are enforced");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NX_COMPAT)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NX_COMPAT))
sb.AppendLine("\tExecutable is NX compatible"); sb.AppendLine("\tExecutable is NX compatible");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_ISOLATION)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_ISOLATION))
sb.AppendLine("\tExecutable is isolation aware, but should not be isolated"); sb.AppendLine("\tExecutable is isolation aware, but should not be isolated");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_SEH)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_SEH))
sb.AppendLine("\tExecutable does not use structured exception handling"); sb.AppendLine("\tExecutable does not use structured exception handling");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_BIND)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_BIND))
sb.AppendLine("\tExecutable should not be binded"); sb.AppendLine("\tExecutable should not be binded");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_APPCONTAINER)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_APPCONTAINER))
sb.AppendLine("\tExecutable must be run inside an AppContainer"); sb.AppendLine("\tExecutable must be run inside an AppContainer");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_WDM_DRIVER))
sb.AppendLine("\tExecutable contains a WDM driver"); sb.AppendLine("\tExecutable contains a WDM driver");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_GUARD_CF)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_GUARD_CF))
sb.AppendLine("\tExecutable supports Control Flow Guard"); sb.AppendLine("\tExecutable supports Control Flow Guard");
if (winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE)) if(winheader.dllCharacteristics.HasFlag(DllCharacteristics.IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
sb.AppendLine("\tExecutable is Terminal Server aware"); sb.AppendLine("\tExecutable is Terminal Server aware");
if (winheader.win32VersionValue > 0) if(winheader.win32VersionValue > 0)
sb.AppendFormat("\tWin32 version value: {0}", winheader.win32VersionValue).AppendLine(); sb.AppendFormat("\tWin32 version value: {0}", winheader.win32VersionValue)
sb.AppendFormat("\tExecutable is {0} bytes", winheader.sizeOfImage).AppendLine(); .AppendLine();
sb.AppendFormat("\tHeaders are {0} bytes", winheader.sizeOfHeaders).AppendLine(); sb.AppendFormat("\tExecutable is {0} bytes", winheader.sizeOfImage).AppendLine();
sb.AppendFormat("\tChecksum: 0x{0:X8}", winheader.checksum).AppendLine(); sb.AppendFormat("\tHeaders are {0} bytes", winheader.sizeOfHeaders).AppendLine();
sb.AppendFormat("\t{0} bytes of stack should be reserved", winheader.sizeOfStackReserve).AppendLine(); sb.AppendFormat("\tChecksum: 0x{0:X8}", winheader.checksum).AppendLine();
sb.AppendFormat("\t{0} bytes of stack should be committed", winheader.sizeOfStackCommit).AppendLine(); sb.AppendFormat("\t{0} bytes of stack should be reserved", winheader.sizeOfStackReserve)
sb.AppendFormat("\t{0} bytes of heap should be reserved", winheader.sizeOfHeapReserve).AppendLine(); .AppendLine();
sb.AppendFormat("\t{0} bytes of heap should be committed", winheader.sizeOfHeapCommit).AppendLine(); sb.AppendFormat("\t{0} bytes of stack should be committed", winheader.sizeOfStackCommit)
if (winheader.loaderFlags > 0) .AppendLine();
sb.AppendFormat("\tLoader flags: {0}", winheader.loaderFlags).AppendLine(); sb.AppendFormat("\t{0} bytes of heap should be reserved", winheader.sizeOfHeapReserve)
sb.AppendFormat("\t{0} RVA entries follow the header", winheader.numberOfRvaAndSizes).AppendLine(); .AppendLine();
sb.AppendFormat("\t{0} bytes of heap should be committed", winheader.sizeOfHeapCommit)
.AppendLine();
if(winheader.loaderFlags > 0) sb.AppendFormat("\tLoader flags: {0}", winheader.loaderFlags).AppendLine();
sb.AppendFormat("\t{0} RVA entries follow the header", winheader.numberOfRvaAndSizes)
.AppendLine();
return sb.ToString(); return sb.ToString();
} }
public string GetInfo() public string GetInfo()
{ {
return GetInfo(Header, WinHeader); return GetInfo(Header, WinHeader);
} }
} }
} }

View File

@@ -23,6 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONPECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONPECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -30,203 +31,191 @@ using System.Runtime.InteropServices;
namespace libexeinfo namespace libexeinfo
{ {
/// <summary> /// <summary>
/// Represents a Microsoft Portable Executable /// Represents a Microsoft Portable Executable
/// </summary> /// </summary>
public partial class PE public partial class PE
{ {
/// <summary> public readonly MZ BaseExecutable;
/// The <see cref="FileStream"/> that contains the executable represented by this instance /// <summary>
/// </summary> /// The <see cref="FileStream" /> that contains the executable represented by this instance
public readonly FileStream BaseStream; /// </summary>
/// <summary> public readonly FileStream BaseStream;
/// Header for this executable /// <summary>
/// </summary> /// Header for this executable
public readonly PEHeader Header; /// </summary>
/// <summary> public readonly PEHeader Header;
/// If true this instance correctly represents a Microsoft Portable Executable /// <summary>
/// </summary> /// If true this instance correctly represents a Microsoft Portable Executable
public readonly bool IsPE; /// </summary>
public readonly MZ BaseExecutable; public readonly bool IsPE;
public readonly WindowsHeader64 WinHeader; 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.
/// </summary> /// </summary>
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public PE(string path) public PE(string path)
{ {
IsPE = false; IsPE = false;
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read); BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
BaseExecutable = new MZ(BaseStream); BaseExecutable = new MZ(BaseStream);
if(BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if(BaseExecutable.Header.new_offset < BaseStream.Length)
{ {
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);
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 = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
IsPE = Header.signature == Signature; IsPE = Header.signature == Signature;
if(IsPE) if(IsPE)
{
if(Header.coff.optionalHeader.magic == PE32Plus) if(Header.coff.optionalHeader.magic == PE32Plus)
{ {
BaseStream.Position -= 4; BaseStream.Position -= 4;
buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader64))]; buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader64))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
hdrPtr = Marshal.AllocHGlobal(buffer.Length); hdrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
WinHeader = (WindowsHeader64)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader64)); WinHeader = (WindowsHeader64)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader64));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
} }
else else
{ {
buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader))]; buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader))];
BaseStream.Read(buffer, 0, buffer.Length); BaseStream.Read(buffer, 0, buffer.Length);
hdrPtr = Marshal.AllocHGlobal(buffer.Length); hdrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
WindowsHeader hdr32 = (WindowsHeader)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader)); WindowsHeader hdr32 = (WindowsHeader)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
WinHeader = ToPlus(hdr32); 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(FileStream stream)
{ {
IsPE = false; IsPE = false;
BaseStream = stream; BaseStream = stream;
BaseExecutable = new MZ(BaseStream); BaseExecutable = new MZ(BaseStream);
if (BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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 = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader));
Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); Marshal.FreeHGlobal(hdrPtr);
Marshal.FreeHGlobal(hdrPtr); IsPE = Header.signature == Signature;
IsPE = Header.signature == Signature;
if (IsPE) if(IsPE)
{ if(Header.coff.optionalHeader.magic == PE32Plus)
if (Header.coff.optionalHeader.magic == PE32Plus) {
{ BaseStream.Position -= 4;
BaseStream.Position -= 4; buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader64))];
buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader64))]; BaseStream.Read(buffer, 0, buffer.Length);
BaseStream.Read(buffer, 0, buffer.Length); hdrPtr = Marshal.AllocHGlobal(buffer.Length);
hdrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); WinHeader = (WindowsHeader64)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader64));
WinHeader = (WindowsHeader64)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader64)); Marshal.FreeHGlobal(hdrPtr);
Marshal.FreeHGlobal(hdrPtr); }
} else
else {
{ buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader))];
buffer = new byte[Marshal.SizeOf(typeof(WindowsHeader))]; BaseStream.Read(buffer, 0, buffer.Length);
BaseStream.Read(buffer, 0, buffer.Length); hdrPtr = Marshal.AllocHGlobal(buffer.Length);
hdrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); WindowsHeader hdr32 = (WindowsHeader)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader));
WindowsHeader hdr32 = (WindowsHeader)Marshal.PtrToStructure(hdrPtr, typeof(WindowsHeader)); Marshal.FreeHGlobal(hdrPtr);
Marshal.FreeHGlobal(hdrPtr); 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
/// </summary> /// </summary>
/// <returns><c>true</c> if the specified executable is a Microsoft Portable Executable, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Microsoft Portable Executable, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param> /// <param name="path">Executable path.</param>
public static bool Identify(string path) public static bool Identify(string path)
{ {
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.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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); PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader));
PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); Marshal.FreeHGlobal(hdrPtr);
Marshal.FreeHGlobal(hdrPtr); return Header.signature == Signature;
return Header.signature == Signature; }
}
}
return false; 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>
/// <returns><c>true</c> if the specified executable is a Microsoft Portable Executable, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the specified executable is a Microsoft Portable 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(FileStream stream)
{ {
FileStream BaseStream = stream; FileStream BaseStream = stream;
MZ BaseExecutable = new MZ(BaseStream); MZ BaseExecutable = new MZ(BaseStream);
if (BaseExecutable.IsMZ) if(BaseExecutable.IsMZ)
{ if(BaseExecutable.Header.new_offset < BaseStream.Length)
if (BaseExecutable.Header.new_offset < BaseStream.Length) {
{ 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); 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); PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader));
PEHeader Header = (PEHeader)Marshal.PtrToStructure(hdrPtr, typeof(PEHeader)); Marshal.FreeHGlobal(hdrPtr);
Marshal.FreeHGlobal(hdrPtr); return Header.signature == Signature;
return Header.signature == Signature; }
}
}
return false; return false;
} }
static WindowsHeader64 ToPlus(WindowsHeader header) static WindowsHeader64 ToPlus(WindowsHeader header)
{ {
return new WindowsHeader64 return new WindowsHeader64
{ {
imageBase = header.imageBase, imageBase = header.imageBase,
sectionAlignment = header.sectionAlignment, sectionAlignment = header.sectionAlignment,
fileAlignment = header.fileAlignment, fileAlignment = header.fileAlignment,
majorOperatingSystemVersion = header.majorOperatingSystemVersion, majorOperatingSystemVersion = header.majorOperatingSystemVersion,
minorOperatingSystemVersion = header.minorOperatingSystemVersion, minorOperatingSystemVersion = header.minorOperatingSystemVersion,
majorImageVersion = header.majorImageVersion, majorImageVersion = header.majorImageVersion,
minorImageVersion = header.minorImageVersion, minorImageVersion = header.minorImageVersion,
majorSubsystemVersion = header.majorSubsystemVersion, majorSubsystemVersion = header.majorSubsystemVersion,
minorSubsystemVersion = header.minorSubsystemVersion, minorSubsystemVersion = header.minorSubsystemVersion,
win32VersionValue = header.win32VersionValue, win32VersionValue = header.win32VersionValue,
sizeOfImage = header.sizeOfImage, sizeOfImage = header.sizeOfImage,
sizeOfHeaders = header.sizeOfHeaders, sizeOfHeaders = header.sizeOfHeaders,
checksum = header.checksum, checksum = header.checksum,
subsystem = header.subsystem, subsystem = header.subsystem,
dllCharacteristics = header.dllCharacteristics, dllCharacteristics = header.dllCharacteristics,
sizeOfStackReserve = header.sizeOfStackReserve, sizeOfStackReserve = header.sizeOfStackReserve,
sizeOfStackCommit = header.sizeOfStackCommit, sizeOfStackCommit = header.sizeOfStackCommit,
sizeOfHeapReserve = header.sizeOfHeapReserve, sizeOfHeapReserve = header.sizeOfHeapReserve,
sizeOfHeapCommit = header.sizeOfHeapCommit, sizeOfHeapCommit = header.sizeOfHeapCommit,
loaderFlags = header.loaderFlags, loaderFlags = header.loaderFlags,
numberOfRvaAndSizes = header.numberOfRvaAndSizes numberOfRvaAndSizes = header.numberOfRvaAndSizes
}; };
} }
} }
} }

View File

@@ -24,7 +24,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using static libexeinfo.COFF; using static libexeinfo.COFF;
@@ -32,320 +31,345 @@ namespace libexeinfo
{ {
public partial class PE public partial class PE
{ {
/// <summary> /// <summary>
/// Header for a Microsoft New Executable /// Header for a Microsoft New Executable
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct PEHeader public struct PEHeader
{ {
/// <summary> /// <summary>
/// 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). /// After the MS-DOS stub, at the file offset specified at offset 0x3c, is a 4-byte signature that identifies the file
/// </summary> /// 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; /// </summary>
public uint signature;
public COFFHeader coff; public COFFHeader coff;
} }
/// <summary> /// <summary>
/// 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. /// The next 21 fields are an extension to the COFF optional header format. They contain additional information that is
/// </summary> /// required by the linker and loader in Windows.
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] /// </summary>
[StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct WindowsHeader public struct WindowsHeader
{ {
/// <summary> /// <summary>
/// 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. /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. The default
/// </summary> /// for DLLs is 0x10000000. The default for Windows CE EXEs is 0x00010000. The default for Windows NT, Windows 2000,
public uint imageBase; /// Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000.
/// <summary> /// </summary>
/// 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 imageBase;
/// </summary> /// <summary>
public uint sectionAlignment; /// The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to
/// <summary> /// FileAlignment. The default is the page size for the architecture.
/// 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. /// </summary>
/// </summary> public uint sectionAlignment;
public uint fileAlignment; /// <summary>
/// <summary> /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file. The value should
/// The major version number of the required operating system. /// be a power of 2 between 512 and 64 K, inclusive. The default is 512. If the SectionAlignment is less than the
/// </summary> /// architecture's page size, then FileAlignment must match SectionAlignment.
public ushort majorOperatingSystemVersion; /// </summary>
/// <summary> public uint fileAlignment;
/// The minor version number of the required operating system. /// <summary>
/// </summary> /// The major version number of the required operating system.
public ushort minorOperatingSystemVersion; /// </summary>
/// <summary> public ushort majorOperatingSystemVersion;
/// The major version number of the image. /// <summary>
/// </summary> /// The minor version number of the required operating system.
public ushort majorImageVersion; /// </summary>
/// <summary> public ushort minorOperatingSystemVersion;
/// The minor version number of the image. /// <summary>
/// </summary> /// The major version number of the image.
public ushort minorImageVersion; /// </summary>
/// <summary> public ushort majorImageVersion;
/// The major version number of the subsystem. /// <summary>
/// </summary> /// The minor version number of the image.
public ushort majorSubsystemVersion; /// </summary>
/// <summary> public ushort minorImageVersion;
/// The minor version number of the subsystem. /// <summary>
/// </summary> /// The major version number of the subsystem.
public ushort minorSubsystemVersion; /// </summary>
/// <summary> public ushort majorSubsystemVersion;
/// Reserved, must be zero. /// <summary>
/// </summary> /// The minor version number of the subsystem.
public uint win32VersionValue; /// </summary>
/// <summary> public ushort minorSubsystemVersion;
/// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of SectionAlignment. /// <summary>
/// </summary> /// Reserved, must be zero.
public uint sizeOfImage; /// </summary>
/// <summary> public uint win32VersionValue;
/// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. /// <summary>
/// </summary> /// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of
public uint sizeOfHeaders; /// SectionAlignment.
/// <summary> /// </summary>
/// 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 sizeOfImage;
/// </summary> /// <summary>
public uint checksum; /// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment.
/// <summary> /// </summary>
/// The subsystem that is required to run this image. For more information, <see cref="Subsystems"/>. public uint sizeOfHeaders;
/// </summary> /// <summary>
public Subsystems subsystem; /// The image file checksum. The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. The following
/// <summary> /// are checked for validation at load time: all drivers, any DLL loaded at boot time, and any DLL that is loaded into
/// For more information, <see cref="DllCharacteristics"/>. /// a critical Windows process.
/// </summary> /// </summary>
public DllCharacteristics dllCharacteristics; public uint checksum;
/// <summary> /// <summary>
/// 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. /// The subsystem that is required to run this image. For more information, <see cref="Subsystems" />.
/// </summary> /// </summary>
public uint sizeOfStackReserve; public Subsystems subsystem;
/// <summary> /// <summary>
/// The size of the stack to commit. /// For more information, <see cref="DllCharacteristics" />.
/// </summary> /// </summary>
public uint sizeOfStackCommit; public DllCharacteristics dllCharacteristics;
/// <summary> /// <summary>
/// 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. /// The size of the stack to reserve. Only SizeOfStackCommit is committed; the rest is made available one page at a
/// </summary> /// time until the reserve size is reached.
public uint sizeOfHeapReserve; /// </summary>
/// <summary> public uint sizeOfStackReserve;
/// The size of the local heap space to commit. /// <summary>
/// </summary> /// The size of the stack to commit.
public uint sizeOfHeapCommit; /// </summary>
/// <summary> public uint sizeOfStackCommit;
/// Reserved, must be zero. /// <summary>
/// </summary> /// The size of the local heap space to reserve. Only SizeOfHeapCommit is committed; the rest is made available one
public uint loaderFlags; /// page at a time until the reserve size is reached.
/// <summary> /// </summary>
/// The number of data-directory entries in the remainder of the optional header. Each describes a location and size. public uint sizeOfHeapReserve;
/// </summary> /// <summary>
public uint numberOfRvaAndSizes; /// The size of the local heap space to commit.
/// </summary>
public uint sizeOfHeapCommit;
/// <summary>
/// Reserved, must be zero.
/// </summary>
public uint loaderFlags;
/// <summary>
/// The number of data-directory entries in the remainder of the optional header. Each describes a location and size.
/// </summary>
public uint numberOfRvaAndSizes;
} }
/// <summary> /// <summary>
/// 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. /// The next 21 fields are an extension to the COFF optional header format. They contain additional information that is
/// </summary> /// required by the linker and loader in Windows.
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] /// </summary>
[StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct WindowsHeader64 public struct WindowsHeader64
{ {
/// <summary> /// <summary>
/// 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. /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. The default
/// </summary> /// for DLLs is 0x10000000. The default for Windows CE EXEs is 0x00010000. The default for Windows NT, Windows 2000,
public ulong imageBase; /// Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000.
/// <summary> /// </summary>
/// 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 ulong imageBase;
/// </summary> /// <summary>
public uint sectionAlignment; /// The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to
/// <summary> /// FileAlignment. The default is the page size for the architecture.
/// 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. /// </summary>
/// </summary> public uint sectionAlignment;
public uint fileAlignment; /// <summary>
/// <summary> /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file. The value should
/// The major version number of the required operating system. /// be a power of 2 between 512 and 64 K, inclusive. The default is 512. If the SectionAlignment is less than the
/// </summary> /// architecture's page size, then FileAlignment must match SectionAlignment.
public ushort majorOperatingSystemVersion; /// </summary>
/// <summary> public uint fileAlignment;
/// The minor version number of the required operating system. /// <summary>
/// </summary> /// The major version number of the required operating system.
public ushort minorOperatingSystemVersion; /// </summary>
/// <summary> public ushort majorOperatingSystemVersion;
/// The major version number of the image. /// <summary>
/// </summary> /// The minor version number of the required operating system.
public ushort majorImageVersion; /// </summary>
/// <summary> public ushort minorOperatingSystemVersion;
/// The minor version number of the image. /// <summary>
/// </summary> /// The major version number of the image.
public ushort minorImageVersion; /// </summary>
/// <summary> public ushort majorImageVersion;
/// The major version number of the subsystem. /// <summary>
/// </summary> /// The minor version number of the image.
public ushort majorSubsystemVersion; /// </summary>
/// <summary> public ushort minorImageVersion;
/// The minor version number of the subsystem. /// <summary>
/// </summary> /// The major version number of the subsystem.
public ushort minorSubsystemVersion; /// </summary>
/// <summary> public ushort majorSubsystemVersion;
/// Reserved, must be zero. /// <summary>
/// </summary> /// The minor version number of the subsystem.
public uint win32VersionValue; /// </summary>
/// <summary> public ushort minorSubsystemVersion;
/// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of SectionAlignment. /// <summary>
/// </summary> /// Reserved, must be zero.
public uint sizeOfImage; /// </summary>
/// <summary> public uint win32VersionValue;
/// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. /// <summary>
/// </summary> /// The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of
public uint sizeOfHeaders; /// SectionAlignment.
/// <summary> /// </summary>
/// 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 sizeOfImage;
/// </summary> /// <summary>
public uint checksum; /// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment.
/// <summary> /// </summary>
/// The subsystem that is required to run this image. For more information, <see cref="Subsystems"/>. public uint sizeOfHeaders;
/// </summary> /// <summary>
public Subsystems subsystem; /// The image file checksum. The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. The following
/// <summary> /// are checked for validation at load time: all drivers, any DLL loaded at boot time, and any DLL that is loaded into
/// For more information, <see cref="DllCharacteristics"/>. /// a critical Windows process.
/// </summary> /// </summary>
public DllCharacteristics dllCharacteristics; public uint checksum;
/// <summary> /// <summary>
/// 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. /// The subsystem that is required to run this image. For more information, <see cref="Subsystems" />.
/// </summary> /// </summary>
public ulong sizeOfStackReserve; public Subsystems subsystem;
/// <summary> /// <summary>
/// The size of the stack to commit. /// For more information, <see cref="DllCharacteristics" />.
/// </summary> /// </summary>
public ulong sizeOfStackCommit; public DllCharacteristics dllCharacteristics;
/// <summary> /// <summary>
/// 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. /// The size of the stack to reserve. Only SizeOfStackCommit is committed; the rest is made available one page at a
/// </summary> /// time until the reserve size is reached.
public ulong sizeOfHeapReserve; /// </summary>
/// <summary> public ulong sizeOfStackReserve;
/// The size of the local heap space to commit. /// <summary>
/// </summary> /// The size of the stack to commit.
public ulong sizeOfHeapCommit; /// </summary>
/// <summary> public ulong sizeOfStackCommit;
/// Reserved, must be zero. /// <summary>
/// </summary> /// The size of the local heap space to reserve. Only SizeOfHeapCommit is committed; the rest is made available one
public uint loaderFlags; /// page at a time until the reserve size is reached.
/// <summary> /// </summary>
/// The number of data-directory entries in the remainder of the optional header. Each describes a location and size. public ulong sizeOfHeapReserve;
/// </summary> /// <summary>
public uint numberOfRvaAndSizes; /// The size of the local heap space to commit.
/// </summary>
public ulong sizeOfHeapCommit;
/// <summary>
/// Reserved, must be zero.
/// </summary>
public uint loaderFlags;
/// <summary>
/// The number of data-directory entries in the remainder of the optional header. Each describes a location and size.
/// </summary>
public uint numberOfRvaAndSizes;
} }
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct ImageDataDirectory public struct ImageDataDirectory
{ {
/// <summary> /// <summary>
/// Relative virtual address of the table /// Relative virtual address of the table
/// </summary> /// </summary>
uint rva; uint rva;
/// <summary> /// <summary>
/// The size in bytes /// The size in bytes
/// </summary> /// </summary>
uint size; uint size;
} }
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct DebugDirectory public struct DebugDirectory
{ {
/// <summary> /// <summary>
/// A reserved field intended to be used for flags, set to zero for now. /// A reserved field intended to be used for flags, set to zero for now.
/// </summary> /// </summary>
public uint characteristics; public uint characteristics;
/// <summary> /// <summary>
/// Time and date the debug data was created. /// Time and date the debug data was created.
/// </summary> /// </summary>
public uint timeDateStamp; public uint timeDateStamp;
/// <summary> /// <summary>
/// Major version number of the debug data format. /// Major version number of the debug data format.
/// </summary> /// </summary>
public ushort majorVersion; public ushort majorVersion;
/// <summary> /// <summary>
/// Minor version number of the debug data format. /// Minor version number of the debug data format.
/// </summary> /// </summary>
public ushort minorVersion; public ushort minorVersion;
/// <summary> /// <summary>
/// Format of debugging information: this field enables support of multiple debuggers. <see cref="DebugTypes"/> for more information. /// Format of debugging information: this field enables support of multiple debuggers. <see cref="DebugTypes" /> for
/// </summary> /// more information.
public DebugTypes type; /// </summary>
/// <summary> public DebugTypes type;
/// Size of the debug data (not including the debug directory itself). /// <summary>
/// </summary> /// Size of the debug data (not including the debug directory itself).
public uint sizeOfData; /// </summary>
/// <summary> public uint sizeOfData;
/// Address of the debug data when loaded, relative to the image base. /// <summary>
/// </summary> /// Address of the debug data when loaded, relative to the image base.
public uint addressOfRawData; /// </summary>
/// <summary> public uint addressOfRawData;
/// File pointer to the debug data. /// <summary>
/// </summary> /// File pointer to the debug data.
public uint pointerToRawData; /// </summary>
public uint pointerToRawData;
} }
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct ResourceDirectoryTable public struct ResourceDirectoryTable
{ {
/// <summary> /// <summary>
/// Resource flags, reserved for future use; currently set to zero. /// Resource flags, reserved for future use; currently set to zero.
/// </summary> /// </summary>
public uint characteristics; public uint characteristics;
/// <summary> /// <summary>
/// Time the resource data was created by the resource compiler. /// Time the resource data was created by the resource compiler.
/// </summary> /// </summary>
public uint timeDateStamp; public uint timeDateStamp;
/// <summary> /// <summary>
/// Major version number, set by the user. /// Major version number, set by the user.
/// </summary> /// </summary>
public ushort majorVersion; public ushort majorVersion;
/// <summary> /// <summary>
/// Minor version number. /// Minor version number.
/// </summary> /// </summary>
public ushort minorVersion; public ushort minorVersion;
/// <summary> /// <summary>
/// Number of directory entries, immediately following the table, /// Number of directory entries, immediately following the table,
/// that use strings to identify Type, Name, or Language /// that use strings to identify Type, Name, or Language
/// (depending on the level of the table). /// (depending on the level of the table).
/// </summary> /// </summary>
public ushort nameEntries; public ushort nameEntries;
/// <summary> /// <summary>
/// Number of directory entries, immediately following the Name /// Number of directory entries, immediately following the Name
/// entries, that use numeric identifiers for Type, Name, or Language. /// entries, that use numeric identifiers for Type, Name, or Language.
/// </summary> /// </summary>
public ushort idEntries; public ushort idEntries;
} }
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct ResourceDirectoryEntries public struct ResourceDirectoryEntries
{ {
/// <summary> /// <summary>
/// Address of string that gives the Type, Name, or Language identifier, depending on level of table. /// Address of string that gives the Type, Name, or Language identifier, depending on level of table.
/// or /// or
/// 32-bit integer that identifies Type, Name, or Language. /// 32-bit integer that identifies Type, Name, or Language.
/// </summary> /// </summary>
public uint nameOrID; public uint nameOrID;
/// <summary> /// <summary>
/// High bit 0: Address of a Resource Data Entry(a leaf). /// 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). /// High bit 1: Lower 31 bits are the address of another Resource Directory Table(the next level down).
/// </summary> /// </summary>
public uint rva; public uint rva;
} }
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)] [StructLayout(LayoutKind.Sequential /*, Pack = 2*/)]
public struct ResourceDataEntry public struct ResourceDataEntry
{ {
/// <summary> /// <summary>
/// Address of a unit of resource data in the Resource Data area. /// Address of a unit of resource data in the Resource Data area.
/// </summary> /// </summary>
public uint rva; public uint rva;
/// <summary> /// <summary>
/// Size, in bytes, of the resource data pointed to by the Data RVA field. /// Size, in bytes, of the resource data pointed to by the Data RVA field.
/// </summary> /// </summary>
public uint size; public uint size;
/// <summary> /// <summary>
/// Code page used to decode code point values within the resource data.Typically, the code page would be the Unicode code page. /// Code page used to decode code point values within the resource data.Typically, the code page would be the Unicode
/// </summary> /// code page.
public uint codepage; /// </summary>
/// <summary> public uint codepage;
/// Reserved (must be set to 0) /// <summary>
/// </summary> /// Reserved (must be set to 0)
public uint reserved; /// </summary>
public uint reserved;
} }
} }
} }

View File

@@ -23,7 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
namespace libexeinfo namespace libexeinfo
{ {
public partial class PE public partial class PE
@@ -32,40 +32,24 @@ namespace libexeinfo
{ {
switch(subsystem) switch(subsystem)
{ {
/// <summary> case Subsystems.IMAGE_SUBSYSTEM_UNKNOWN: return "for an unknown subsystem with no code";
/// An unknown subsystem case Subsystems.IMAGE_SUBSYSTEM_NATIVE: return "an application for native Windows API";
/// </summary> case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_GUI: return "an application for Windows GUI";
case Subsystems.IMAGE_SUBSYSTEM_UNKNOWN:
return "for an unknown subsystem with no code";
case Subsystems.IMAGE_SUBSYSTEM_NATIVE:
return "an application for native Windows API";
case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_GUI:
return "an application for Windows GUI";
case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_CUI: case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_CUI:
return "an application for Windows command-line"; return "an application for Windows command-line";
case Subsystems.IMAGE_SUBSYSTEM_OS2_CUI: case Subsystems.IMAGE_SUBSYSTEM_OS2_CUI: return "an application for OS/2 command-line";
return "an application for OS/2 command-line"; case Subsystems.IMAGE_SUBSYSTEM_POSIX_CUI: return "an application for POSIX command-line";
case Subsystems.IMAGE_SUBSYSTEM_POSIX_CUI: case Subsystems.IMAGE_SUBSYSTEM_NATIVE_WINDOWS: return "a driver for Windows 9x";
return "an application for POSIX command-line"; case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: return "an application for Windows CE";
case Subsystems.IMAGE_SUBSYSTEM_NATIVE_WINDOWS: case Subsystems.IMAGE_SUBSYSTEM_EFI_APPLICATION: return "an EFI application";
return "a driver for Windows 9x"; case Subsystems.IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: return "an EFI boot services driver";
case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: case Subsystems.IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: return "an EFI run-time services driver";
return "an application for Windows CE"; case Subsystems.IMAGE_SUBSYSTEM_EFI_ROM: return "an EFI ROM image";
case Subsystems.IMAGE_SUBSYSTEM_EFI_APPLICATION: case Subsystems.IMAGE_SUBSYSTEM_XBOX: return "a Xbox executable";
return "an EFI application";
case Subsystems.IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
return "an EFI boot services driver";
case Subsystems.IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
return "an EFI run-time services driver";
case Subsystems.IMAGE_SUBSYSTEM_EFI_ROM:
return "an EFI ROM image";
case Subsystems.IMAGE_SUBSYSTEM_XBOX:
return "a Xbox executable";
case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION: case Subsystems.IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION:
return "an application for Windows Boot environment"; return "an application for Windows Boot environment";
default: default: return $"for an unknown subsystem with code {(ushort)subsystem}";
return string.Format("for an unknown subsystem with code {0}", (ushort)subsystem);
} }
} }
} }
} }

View File

@@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes. // Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project. // Change them to the values specific to your project.
@@ -23,4 +22,4 @@ using System.Runtime.CompilerServices;
// if desired. See the Mono documentation for more information about signing. // if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)] //[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")] //[assembly: AssemblyKeyFile("")]

View File

@@ -23,112 +23,113 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Linq; using System.Linq;
namespace libexeinfo namespace libexeinfo
{ {
public static class Swapping public static class Swapping
{ {
public static byte[] SwapTenBytes(byte[] source) public static byte[] SwapTenBytes(byte[] source)
{ {
byte[] destination = new byte[8]; byte[] destination = new byte[8];
destination[0] = source[9]; destination[0] = source[9];
destination[1] = source[8]; destination[1] = source[8];
destination[2] = source[7]; destination[2] = source[7];
destination[3] = source[6]; destination[3] = source[6];
destination[4] = source[5]; destination[4] = source[5];
destination[5] = source[4]; destination[5] = source[4];
destination[6] = source[3]; destination[6] = source[3];
destination[7] = source[2]; destination[7] = source[2];
destination[8] = source[1]; destination[8] = source[1];
destination[9] = source[0]; destination[9] = source[0];
return destination; return destination;
} }
public static byte[] SwapEightBytes(byte[] source) public static byte[] SwapEightBytes(byte[] source)
{ {
byte[] destination = new byte[8]; byte[] destination = new byte[8];
destination[0] = source[7]; destination[0] = source[7];
destination[1] = source[6]; destination[1] = source[6];
destination[2] = source[5]; destination[2] = source[5];
destination[3] = source[4]; destination[3] = source[4];
destination[4] = source[3]; destination[4] = source[3];
destination[5] = source[2]; destination[5] = source[2];
destination[6] = source[1]; destination[6] = source[1];
destination[7] = source[0]; destination[7] = source[0];
return destination; return destination;
} }
public static byte[] SwapFourBytes(byte[] source) public static byte[] SwapFourBytes(byte[] source)
{ {
byte[] destination = new byte[4]; byte[] destination = new byte[4];
destination[0] = source[3]; destination[0] = source[3];
destination[1] = source[2]; destination[1] = source[2];
destination[2] = source[1]; destination[2] = source[1];
destination[3] = source[0]; destination[3] = source[0];
return destination; return destination;
} }
public static byte[] SwapTwoBytes(byte[] source) public static byte[] SwapTwoBytes(byte[] source)
{ {
byte[] destination = new byte[2]; byte[] destination = new byte[2];
destination[0] = source[1]; destination[0] = source[1];
destination[1] = source[0]; destination[1] = source[0];
return destination; return destination;
} }
public static uint PDPFromLittleEndian(uint x) public static uint PDPFromLittleEndian(uint x)
{ {
return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16); return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16);
} }
public static uint PDPFromBigEndian(uint x) public static uint PDPFromBigEndian(uint x)
{ {
return ((x & 0xff00ff) << 8) | ((x & 0xff00ff00) >> 8); return ((x & 0xff00ff) << 8) | ((x & 0xff00ff00) >> 8);
} }
public static ulong Swap(ulong x) public static ulong Swap(ulong x)
{ {
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32; x = ((x & 0x00000000FFFFFFFF) << 32) | ((x & 0xFFFFFFFF00000000) >> 32);
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16; x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x & 0xFFFF0000FFFF0000) >> 16);
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8; x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x & 0xFF00FF00FF00FF00) >> 8);
return x; return x;
} }
public static long Swap(long x) public static long Swap(long x)
{ {
return BitConverter.ToInt64(BitConverter.GetBytes(x).Reverse().ToArray(), 0); return BitConverter.ToInt64(BitConverter.GetBytes(x).Reverse().ToArray(), 0);
} }
public static ushort Swap(ushort x) public static ushort Swap(ushort x)
{ {
return (ushort)((x << 8) | (x >> 8)); return (ushort)((x << 8) | (x >> 8));
} }
public static short Swap(short x) public static short Swap(short x)
{ {
return (short)((x << 8) | ((x >> 8) & 0xFF)); return (short)((x << 8) | ((x >> 8) & 0xFF));
} }
public static uint Swap(uint x) public static uint Swap(uint x)
{ {
x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF); x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF);
return (x << 16) | (x >> 16); return (x << 16) | (x >> 16);
} }
public static int Swap(int x) public static int Swap(int x)
{ {
x = (int)(((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF)); x = (int)(((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF));
return (x << 16) | ((x >> 16) & 0xFFFF); return (x << 16) | ((x >> 16) & 0xFFFF);
} }
} }
} }