mirror of
https://github.com/claunia/libexeinfo.git
synced 2025-12-16 19:14:24 +00:00
Added support for LE/LX executables.
This commit is contained in:
@@ -11,3 +11,5 @@ Supported executable formats
|
||||
* Atari ST executable
|
||||
* MZ (aka DOS relocatable executable)
|
||||
* NE (Microsoft New Executable)
|
||||
* LE (Microsoft Linear Executable)
|
||||
* LX (IBM Linear eXecutable)
|
||||
@@ -52,6 +52,7 @@ namespace exeinfo
|
||||
MZ mzExe = new MZ(exeFs);
|
||||
NE neExe = new NE(exeFs);
|
||||
AtariST stExe = new AtariST(exeFs);
|
||||
LX lxExe = new LX(exeFs);
|
||||
|
||||
if (mzExe.IsMZ)
|
||||
{
|
||||
@@ -117,6 +118,12 @@ namespace exeinfo
|
||||
Console.Write(stExe.GetInfo());
|
||||
}
|
||||
|
||||
if (lxExe.IsLX)
|
||||
{
|
||||
recognized = true;
|
||||
Console.Write(lxExe.GetInfo());
|
||||
}
|
||||
|
||||
if (!recognized)
|
||||
Console.WriteLine("Executable format not recognized");
|
||||
}
|
||||
|
||||
41
libexeinfo/LX/Consts.cs
Normal file
41
libexeinfo/LX/Consts.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Consts.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;
|
||||
namespace libexeinfo
|
||||
{
|
||||
public partial class LX
|
||||
{
|
||||
/// <summary>
|
||||
/// Linear Executable signature, "LE"
|
||||
/// </summary>
|
||||
public const ushort Signature16 = 0x454C;
|
||||
/// <summary>
|
||||
/// Linear eXecutable signature, "LX"
|
||||
/// </summary>
|
||||
public const ushort Signature = 0x584C;
|
||||
}
|
||||
}
|
||||
114
libexeinfo/LX/Enums.cs
Normal file
114
libexeinfo/LX/Enums.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// Enums.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;
|
||||
namespace libexeinfo
|
||||
{
|
||||
public partial class LX
|
||||
{
|
||||
/// <summary>
|
||||
/// Executable module flags.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ModuleFlags : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Per-Process Library Initialization
|
||||
/// </summary>
|
||||
PerProcessLibrary = 0x04,
|
||||
/// <summary>
|
||||
/// Internal fixups for the module have been applied
|
||||
/// </summary>
|
||||
InternalFixups = 0x10,
|
||||
/// <summary>
|
||||
/// External fixups for the module have been applied
|
||||
/// </summary>
|
||||
ExternalFixups = 0x20,
|
||||
/// <summary>
|
||||
/// Incompatible with Presentation Manager
|
||||
/// </summary>
|
||||
PMIncompatible = 0x100,
|
||||
/// <summary>
|
||||
/// Compatible with Presentation Manager
|
||||
/// </summary>
|
||||
PMCompatible = 0x200,
|
||||
/// <summary>
|
||||
/// Uses Presentation Manager
|
||||
/// </summary>
|
||||
UsesPM = 0x300,
|
||||
/// <summary>
|
||||
/// Module is not loadable. Contains errors or is being linked
|
||||
/// </summary>
|
||||
NotLoadable = 0x2000,
|
||||
/// <summary>
|
||||
/// Library module
|
||||
/// </summary>
|
||||
Library = 0x8000,
|
||||
/// <summary>
|
||||
/// Protected Memory Library module
|
||||
/// </summary>
|
||||
ProtectedMemoryLibrary = 0x18000,
|
||||
/// <summary>
|
||||
/// Physical Device Driver module
|
||||
/// </summary>
|
||||
PhysicalDeviceDriver = 0x20000,
|
||||
/// <summary>
|
||||
/// Virtual Device Driver module
|
||||
/// </summary>
|
||||
VirtualDeviceDriver = 0x28000,
|
||||
/// <summary>
|
||||
/// Per-process Library Termination
|
||||
/// </summary>
|
||||
PerProcessTermination = 0x40000000
|
||||
}
|
||||
|
||||
public enum TargetCpu : ushort
|
||||
{
|
||||
Unknown = 0,
|
||||
i286 = 1,
|
||||
i386 = 2,
|
||||
i486 = 3,
|
||||
Pentium = 4,
|
||||
i860 = 0x20,
|
||||
N11 = 0x21,
|
||||
MIPS1 = 0x40,
|
||||
MIPS2 = 0x41,
|
||||
MIPS3 = 0x42
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Target operating system.
|
||||
/// </summary>
|
||||
public enum TargetOS : ushort
|
||||
{
|
||||
Unknown = 0,
|
||||
OS2 = 1,
|
||||
Windows = 2,
|
||||
DOS = 3,
|
||||
Win32 = 4
|
||||
}
|
||||
}
|
||||
}
|
||||
181
libexeinfo/LX/Info.cs
Normal file
181
libexeinfo/LX/Info.cs
Normal file
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// Info.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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace libexeinfo
|
||||
{
|
||||
public partial class LX
|
||||
{
|
||||
public static string GetInfo(LXHeader header)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if(header.signature == Signature16)
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
case TargetCpu.i286:
|
||||
sb.AppendLine("\tExecutable requires at least an 80286 processor to run.");
|
||||
break;
|
||||
case TargetCpu.i386:
|
||||
sb.AppendLine("\tExecutable requires at least an 80386 processor to run.");
|
||||
break;
|
||||
case TargetCpu.i486:
|
||||
sb.AppendLine("\tExecutable requires at least an 80486 processor to run.");
|
||||
break;
|
||||
case TargetCpu.Pentium:
|
||||
sb.AppendLine("\tExecutable requires at least a Pentium processor to run.");
|
||||
break;
|
||||
case TargetCpu.i860:
|
||||
sb.AppendLine("\tExecutable requires at least an Intel 860 processor to run.");
|
||||
break;
|
||||
case TargetCpu.N11:
|
||||
sb.AppendLine("\tExecutable requires at least an Intel N11 processor to run.");
|
||||
break;
|
||||
case TargetCpu.MIPS1:
|
||||
sb.AppendLine("\tExecutable requires at least a MIPS I processor to run.");
|
||||
break;
|
||||
case TargetCpu.MIPS2:
|
||||
sb.AppendLine("\tExecutable requires at least a MIPS II processor to run.");
|
||||
break;
|
||||
case TargetCpu.MIPS3:
|
||||
sb.AppendLine("\tExecutable requires at least a MIPS III processor to run.");
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("\tExecutable requires unknown cpu with type code {0} to run.", (ushort)header.cpu_type).AppendLine();
|
||||
break;
|
||||
}
|
||||
|
||||
if (header.module_flags.HasFlag(ModuleFlags.PerProcessLibrary))
|
||||
sb.AppendLine("Library should be initialized per-process.");
|
||||
if (header.module_flags.HasFlag(ModuleFlags.PerProcessTermination))
|
||||
sb.AppendLine("Library should be terminated per-process.");
|
||||
if (header.module_flags.HasFlag(ModuleFlags.InternalFixups))
|
||||
sb.AppendLine("Internal fixups have been applied.");
|
||||
if (header.module_flags.HasFlag(ModuleFlags.ExternalFixups))
|
||||
sb.AppendLine("External fixups have been applied.");
|
||||
if (header.module_flags.HasFlag(ModuleFlags.NotLoadable))
|
||||
sb.AppendLine("Executable is not loadable, it contains errors or is still being linked.");
|
||||
|
||||
if(header.module_flags.HasFlag(ModuleFlags.VirtualDeviceDriver))
|
||||
sb.AppendLine("Executable is a driver for a virtual device.");
|
||||
else if (header.module_flags.HasFlag(ModuleFlags.PhysicalDeviceDriver))
|
||||
sb.AppendLine("Executable is a driver for a physical device.");
|
||||
else if (header.module_flags.HasFlag(ModuleFlags.ProtectedMemoryLibrary))
|
||||
sb.AppendLine("Executable is a protected mode library.");
|
||||
else if (header.module_flags.HasFlag(ModuleFlags.Library))
|
||||
sb.AppendLine("Executable is a library.");
|
||||
|
||||
sb.AppendFormat("\tThis executable contains {0} pages", header.module_pages_no).AppendLine();
|
||||
sb.AppendFormat("\tObject number to which the Entry Address is relative: {0}", header.eip_object).AppendLine();
|
||||
sb.AppendFormat("\tEntry address of module: {0:X8}h", header.eip).AppendLine();
|
||||
sb.AppendFormat("\tObject number to which the ESP is relative: {0}", header.esp_object).AppendLine();
|
||||
sb.AppendFormat("\tStarting stack address of module: {0:X8}h", header.esp).AppendLine();
|
||||
sb.AppendFormat("\tOne page is {0} bytes", header.page_size).AppendLine();
|
||||
sb.AppendFormat("\tShift left bits for page offsets: {0}", header.page_off_shift).AppendLine();
|
||||
sb.AppendFormat("\tTotal size of the fixup information: {0}", header.fixup_size).AppendLine();
|
||||
sb.AppendFormat("\tChecksum for fixup information: 0x{0:X8}", header.fixup_checksum).AppendLine();
|
||||
sb.AppendFormat("\tMemory resident tables are {0} bytes long", header.loader_size).AppendLine();
|
||||
sb.AppendFormat("\tChecksum for loader section: 0x{0:X8}", header.loader_checksum).AppendLine();
|
||||
sb.AppendFormat("\tObject table starts at {0} and contains {1} objects", header.obj_table_off, header.obj_no).AppendLine();
|
||||
sb.AppendFormat("\tObject page table starts at {0}", header.obj_page_table_off).AppendLine();
|
||||
sb.AppendFormat("\tObject iterated pages starts at {0}", header.obj_iter_pages_off).AppendLine();
|
||||
sb.AppendFormat("\tResources table starts at {0} and contains {1} entries", header.resource_table_off, header.resource_entries).AppendLine();
|
||||
sb.AppendFormat("\tResident name table starts at {0}", header.resident_names_off).AppendLine();
|
||||
sb.AppendFormat("\tEntry table starts at {0}", header.entry_table_off).AppendLine();
|
||||
sb.AppendFormat("\tModule format directives table starts at {0} and contains {1} entries", header.directives_off, header.directives_no).AppendLine();
|
||||
sb.AppendFormat("\tFixup page table starts at {0}", header.fixup_page_table_off).AppendLine();
|
||||
sb.AppendFormat("\tFixup record table starts at {0}", header.fixup_record_table_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("\tImport procedure name table starts at {0}", header.import_proc_table_off).AppendLine();
|
||||
sb.AppendFormat("\tPer-page checksum table starts at {0}", header.perpage_checksum_off).AppendLine();
|
||||
sb.AppendFormat("\tData pages start at {0}", header.data_pages_off).AppendLine();
|
||||
sb.AppendFormat("\t{0} pages to preload in this executable", header.preload_pages_no).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("\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()
|
||||
{
|
||||
return GetInfo(Header);
|
||||
}
|
||||
}
|
||||
}
|
||||
156
libexeinfo/LX/LX.cs
Normal file
156
libexeinfo/LX/LX.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
//
|
||||
// NE.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.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace libexeinfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Microsoft/IBM Linear EXecutable
|
||||
/// </summary>
|
||||
// TODO: Big-endian (really needed?)
|
||||
public partial class LX
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="FileStream"/> that contains the executable represented by this instance
|
||||
/// </summary>
|
||||
public readonly FileStream BaseStream;
|
||||
/// <summary>
|
||||
/// Header for this executable
|
||||
/// </summary>
|
||||
public readonly LXHeader Header;
|
||||
/// <summary>
|
||||
/// If true this instance correctly represents a Microsoft/IBM Linear EXecutable
|
||||
/// </summary>
|
||||
public readonly bool IsLX;
|
||||
public readonly MZ BaseExecutable;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:libexeinfo.NE"/> class.
|
||||
/// </summary>
|
||||
/// <param name="path">Executable path.</param>
|
||||
public LX(string path)
|
||||
{
|
||||
IsLX = false;
|
||||
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read);
|
||||
BaseExecutable = new MZ(BaseStream);
|
||||
if(BaseExecutable.IsMZ)
|
||||
{
|
||||
if(BaseExecutable.Header.new_offset < BaseStream.Length)
|
||||
{
|
||||
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
|
||||
byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))];
|
||||
BaseStream.Read(buffer, 0, buffer.Length);
|
||||
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
|
||||
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
|
||||
Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
|
||||
Marshal.FreeHGlobal(hdrPtr);
|
||||
IsLX = Header.signature == Signature || Header.signature == Signature16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:libexeinfo.NE"/> class.
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream containing the executable.</param>
|
||||
public LX(FileStream stream)
|
||||
{
|
||||
IsLX = false;
|
||||
BaseStream = stream;
|
||||
BaseExecutable = new MZ(BaseStream);
|
||||
if (BaseExecutable.IsMZ)
|
||||
{
|
||||
if (BaseExecutable.Header.new_offset < BaseStream.Length)
|
||||
{
|
||||
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
|
||||
byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))];
|
||||
BaseStream.Read(buffer, 0, buffer.Length);
|
||||
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
|
||||
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
|
||||
Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
|
||||
Marshal.FreeHGlobal(hdrPtr);
|
||||
IsLX = Header.signature == Signature || Header.signature == Signature16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies if the specified executable is a Microsoft/IBM Linear EXecutable
|
||||
/// </summary>
|
||||
/// <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>
|
||||
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(LXHeader))];
|
||||
BaseStream.Read(buffer, 0, buffer.Length);
|
||||
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
|
||||
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
|
||||
LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
|
||||
Marshal.FreeHGlobal(hdrPtr);
|
||||
return Header.signature == Signature || Header.signature == Signature16;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies if the specified executable is a Microsoft/IBM Linear EXecutable
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public static bool Identify(FileStream stream)
|
||||
{
|
||||
FileStream BaseStream = stream;
|
||||
MZ BaseExecutable = new MZ(BaseStream);
|
||||
if (BaseExecutable.IsMZ)
|
||||
{
|
||||
if (BaseExecutable.Header.new_offset < BaseStream.Length)
|
||||
{
|
||||
BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
|
||||
byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))];
|
||||
BaseStream.Read(buffer, 0, buffer.Length);
|
||||
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
|
||||
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
|
||||
LXHeader Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
|
||||
Marshal.FreeHGlobal(hdrPtr);
|
||||
return Header.signature == Signature || Header.signature == Signature16;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
226
libexeinfo/LX/Structs.cs
Normal file
226
libexeinfo/LX/Structs.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
//
|
||||
// Structs.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.Runtime.InteropServices;
|
||||
|
||||
namespace libexeinfo
|
||||
{
|
||||
public partial class LX
|
||||
{
|
||||
/// <summary>
|
||||
/// Header for a Microsoft Linear Executable and IBM Linear eXecutable
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential/*, Pack = 2*/)]
|
||||
public struct LXHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Executable signature
|
||||
/// </summary>
|
||||
public ushort signature;
|
||||
/// <summary>
|
||||
/// Byte ordering
|
||||
/// </summary>
|
||||
public byte byte_order;
|
||||
/// <summary>
|
||||
/// Word ordering
|
||||
/// </summary>
|
||||
public byte word_order;
|
||||
/// <summary>
|
||||
/// Format level, should be 0
|
||||
/// </summary>
|
||||
public uint format_level;
|
||||
/// <summary>
|
||||
/// Type of CPU required by this executable to run
|
||||
/// </summary>
|
||||
public TargetCpu cpu_type;
|
||||
/// <summary>
|
||||
/// Type of operating system requires by this executable to run
|
||||
/// </summary>
|
||||
public TargetOS os_type;
|
||||
/// <summary>
|
||||
/// Executable version
|
||||
/// </summary>
|
||||
public uint module_version;
|
||||
/// <summary>
|
||||
/// Executable flags
|
||||
/// </summary>
|
||||
public ModuleFlags module_flags;
|
||||
/// <summary>
|
||||
/// Pages contained in this module
|
||||
/// </summary>
|
||||
public uint module_pages_no;
|
||||
/// <summary>
|
||||
/// Object number to which the Entry Address is relative
|
||||
/// </summary>
|
||||
public uint eip_object;
|
||||
/// <summary>
|
||||
/// Entry address of module
|
||||
/// </summary>
|
||||
public uint eip;
|
||||
/// <summary>
|
||||
/// Object number to which the ESP is relative
|
||||
/// </summary>
|
||||
public uint esp_object;
|
||||
/// <summary>
|
||||
/// Starting stack address of module
|
||||
/// </summary>
|
||||
public uint esp;
|
||||
/// <summary>
|
||||
/// Size of one page
|
||||
/// </summary>
|
||||
public uint page_size;
|
||||
/// <summary>
|
||||
/// Shift left bits for page offsets
|
||||
/// </summary>
|
||||
public uint page_off_shift;
|
||||
/// <summary>
|
||||
/// Total size of the fixup information
|
||||
/// </summary>
|
||||
public uint fixup_size;
|
||||
/// <summary>
|
||||
/// Checksum for fixup information
|
||||
/// </summary>
|
||||
public uint fixup_checksum;
|
||||
/// <summary>
|
||||
/// Size of memory resident tables
|
||||
/// </summary>
|
||||
public uint loader_size;
|
||||
/// <summary>
|
||||
/// Checksum for loader section
|
||||
/// </summary>
|
||||
public uint loader_checksum;
|
||||
/// <summary>
|
||||
/// Object table offset
|
||||
/// </summary>
|
||||
public uint obj_table_off;
|
||||
/// <summary>
|
||||
/// Object table count
|
||||
/// </summary>
|
||||
public uint obj_no;
|
||||
/// <summary>
|
||||
/// Object page table offset
|
||||
/// </summary>
|
||||
public uint obj_page_table_off;
|
||||
/// <summary>
|
||||
/// Object iterated pages offset
|
||||
/// </summary>
|
||||
public uint obj_iter_pages_off;
|
||||
/// <summary>
|
||||
/// Resource table offset
|
||||
/// </summary>
|
||||
public uint resource_table_off;
|
||||
/// <summary>
|
||||
/// Entries in resource table
|
||||
/// </summary>
|
||||
public uint resource_entries;
|
||||
/// <summary>
|
||||
/// Resident name table offset
|
||||
/// </summary>
|
||||
public uint resident_names_off;
|
||||
/// <summary>
|
||||
/// Entry table offset
|
||||
/// </summary>
|
||||
public uint entry_table_off;
|
||||
/// <summary>
|
||||
/// Module format directives table offset
|
||||
/// </summary>
|
||||
public uint directives_off;
|
||||
/// <summary>
|
||||
/// Entries in module format directives table
|
||||
/// </summary>
|
||||
public uint directives_no;
|
||||
/// <summary>
|
||||
/// Fixup page table offset
|
||||
/// </summary>
|
||||
public uint fixup_page_table_off;
|
||||
/// <summary>
|
||||
/// Fixup record table offset
|
||||
/// </summary>
|
||||
public uint fixup_record_table_off;
|
||||
/// <summary>
|
||||
/// Import module name table offset
|
||||
/// </summary>
|
||||
public uint import_module_table_off;
|
||||
/// <summary>
|
||||
/// Entries in the import module name table
|
||||
/// </summary>
|
||||
public uint import_module_entries;
|
||||
/// <summary>
|
||||
/// Import procedure name table offset
|
||||
/// </summary>
|
||||
public uint import_proc_table_off;
|
||||
/// <summary>
|
||||
/// Per-page checksum table offset
|
||||
/// </summary>
|
||||
public uint perpage_checksum_off;
|
||||
/// <summary>
|
||||
/// Data pages offset
|
||||
/// </summary>
|
||||
public uint data_pages_off;
|
||||
/// <summary>
|
||||
/// Number of preload pages for this module
|
||||
/// </summary>
|
||||
public uint preload_pages_no;
|
||||
/// <summary>
|
||||
/// Non-resident name table offset
|
||||
/// </summary>
|
||||
public uint nonresident_name_table_off;
|
||||
/// <summary>
|
||||
/// Number of bytes in the non-resident name table
|
||||
/// </summary>
|
||||
public uint nonresident_name_table_len;
|
||||
/// <summary>
|
||||
/// Non-resident name table checksum
|
||||
/// </summary>
|
||||
public uint nonresident_name_table_checksum;
|
||||
/// <summary>
|
||||
/// The auto data segment object number
|
||||
/// </summary>
|
||||
public uint auto_ds_obj_no;
|
||||
/// <summary>
|
||||
/// Debug information offset
|
||||
/// </summary>
|
||||
public uint debug_info_off;
|
||||
/// <summary>
|
||||
/// Debug information length
|
||||
/// </summary>
|
||||
public uint debug_info_len;
|
||||
/// <summary>
|
||||
/// Instance pages in preload section
|
||||
/// </summary>
|
||||
public uint instance_preload_no;
|
||||
/// <summary>
|
||||
/// Instance pages in demand section
|
||||
/// </summary>
|
||||
public uint instance_demand_no;
|
||||
/// <summary>
|
||||
/// Heap size added to the auto ds object
|
||||
/// </summary>
|
||||
public uint heap_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,6 @@
|
||||
<Compile Include="MZ\Info.cs" />
|
||||
<Compile Include="MZ\Structs.cs" />
|
||||
<Compile Include="NE\Consts.cs" />
|
||||
<Compile Include="NE\Enums.cs" />
|
||||
<Compile Include="NE\Info.cs" />
|
||||
<Compile Include="NE\Structs.cs" />
|
||||
<Compile Include="NE\Version.cs" />
|
||||
@@ -59,6 +58,12 @@
|
||||
<Compile Include="AtariST\Consts.cs" />
|
||||
<Compile Include="AtariST\AtariST.cs" />
|
||||
<Compile Include="AtariST\Info.cs" />
|
||||
<Compile Include="LX\Structs.cs" />
|
||||
<Compile Include="NE\Enums.cs" />
|
||||
<Compile Include="LX\Enums.cs" />
|
||||
<Compile Include="LX\Consts.cs" />
|
||||
<Compile Include="LX\Info.cs" />
|
||||
<Compile Include="LX\LX.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
@@ -73,6 +78,7 @@
|
||||
<Folder Include="MZ\" />
|
||||
<Folder Include="NE\" />
|
||||
<Folder Include="AtariST\" />
|
||||
<Folder Include="LX\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\NuGet.Build.Packaging.0.1.276\build\NuGet.Build.Packaging.targets" Condition="Exists('..\packages\NuGet.Build.Packaging.0.1.276\build\NuGet.Build.Packaging.targets')" />
|
||||
|
||||
Reference in New Issue
Block a user