BOS.* -> BOS.*

This commit is contained in:
Matt Nadareski
2023-03-07 16:59:14 -05:00
parent e32b24c9f6
commit 473cbc5694
591 changed files with 1214 additions and 1214 deletions

View File

@@ -0,0 +1,11 @@
namespace BinaryObjectScanner.Models.NewExecutable
{
public static class Constants
{
public static readonly byte[] SignatureBytes = new byte[] { 0x4e, 0x45 };
public const string SignatureString = "NE";
public const ushort SignatureUInt16 = 0x454e;
}
}

View File

@@ -0,0 +1,84 @@
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The entry table follows the imported-name table. This table contains
/// bundles of entry-point definitions. Bundling is done to save space in
/// the entry table. The entry table is accessed by an ordinal value.
/// Ordinal number one is defined to index the first entry in the entry
/// table. To find an entry point, the bundles are scanned searching for a
/// specific entry point using an ordinal number. The ordinal number is
/// adjusted as each bundle is checked. When the bundle that contains the
/// entry point is found, the ordinal number is multiplied by the size of
/// the bundle's entries to index the proper entry.
/// </summary>
/// <remarks>
/// The linker forms bundles in the most dense manner it can, under the
/// restriction that it cannot reorder entry points to improve bundling.
/// The reason for this restriction is that other .EXE files may refer to
/// entry points within this bundle by their ordinal number. The following
/// describes the format of the entry table bundles.
/// </remarks>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
public sealed class EntryTableBundle
{
/// <summary>
/// Number of entries in this bundle. All records in one bundle
/// are either moveable or refer to the same fixed segment. A zero
/// value in this field indicates the end of the entry table.
/// </summary>
public byte EntryCount;
/// <summary>
/// Segment indicator for this bundle. This defines the type of
/// entry table entry data within the bundle. There are three
/// types of entries that are defined.
/// - 000h = Unused entries. There is no entry data in an unused
/// bundle. The next bundle follows this field. This is
/// used by the linker to skip ordinal numbers.
/// - 001h-0FEh = Segment number for fixed segment entries. A fixed
/// segment entry is 3 bytes long.
/// - 0FFH = Moveable segment entries. The entry data contains the
/// segment number for the entry points. A moveable segment
/// entry is 6 bytes long.
/// </summary>
public byte SegmentIndicator;
#region Fixed Segment Entry
/// <summary>
/// Flag word.
/// </summary>
public FixedSegmentEntryFlag FixedFlagWord;
/// <summary>
/// Offset within segment to entry point.
/// </summary>
public ushort FixedOffset;
#endregion
#region Moveable Segment Entry
/// <summary>
/// Flag word.
/// </summary>
public MoveableSegmentEntryFlag MoveableFlagWord;
/// <summary>
/// INT 3FH.
/// </summary>
public ushort MoveableReserved;
/// <summary>
/// Segment number.
/// </summary>
public byte MoveableSegmentNumber;
/// <summary>
/// Offset within segment to entry point.
/// </summary>
public ushort MoveableOffset;
#endregion
}
}

View File

@@ -0,0 +1,324 @@
using System;
namespace BinaryObjectScanner.Models.NewExecutable
{
[Flags]
public enum FixedSegmentEntryFlag : byte
{
/// <summary>
/// Set if the entry is exported.
/// </summary>
Exported = 0x01,
/// <summary>
/// Set if the entry uses a global (shared) data segments.
/// </summary>
/// <remarks>
/// The first assembly-language instruction in the
/// entry point prologue must be "MOV AX,data
/// segment number". This may be set only for
/// SINGLEDATA library modules.
/// </remarks>
Global = 0x02,
}
[Flags]
public enum HeaderFlag : ushort
{
#region Program Flags
NOAUTODATA = 0x0000,
/// <summary>
/// Shared automatic data segment
/// </summary>
SINGLEDATA = 0x0001,
/// <summary>
/// Instanced automatic data segment
/// </summary>
MULTIPLEDATA = 0x0002,
/// <summary>
/// Global initialization
/// </summary>
GlobalInitialization = 0x0004,
/// <summary>
/// Protected mode only
/// </summary>
ProtectedModeOnly = 0x0008,
/// <summary>
/// 8086 instructions
/// </summary>
Instructions8086 = 0x0010,
/// <summary>
/// 80286 instructions
/// </summary>
Instructions80286 = 0x0020,
/// <summary>
/// 80386 instructions
/// </summary>
Instructions80386 = 0x0040,
/// <summary>
/// 80x87 instructions
/// </summary>
Instructions80x87 = 0x0080,
#endregion
#region Application Flags
/// <summary>
/// Full screen (not aware of Windows/P.M. API)
/// </summary>
FullScreen = 0x0100,
/// <summary>
/// Compatible with Windows/P.M. API
/// </summary>
WindowsPMCompatible = 0x0200,
/// <summary>
/// Uses Windows/P.M. API
/// </summary>
WindowsPM = 0x0400,
/// <summary>
/// OS/2 family application
/// </summary>
OS2FamilyApplication = 0x0800,
/// <summary>
/// Unknown (Reserved?)
/// </summary>
UnknownReserved = 0x1000,
/// <summary>
/// Errors detected at link time, module will not load
/// </summary>
ErrorsDetectedAtLinkTime = 0x2000,
/// <summary>
/// Unknown (non-conforming program)
/// </summary>
UnknownNonConforming = 0x4000,
/// <summary>
/// Library module.
/// The SS:SP information is invalid, CS:IP points
/// to an initialization procedure that is called
/// with AX equal to the module handle. This
/// initialization procedure must perform a far
/// return to the caller, with AX not equal to
/// zero to indicate success, or AX equal to zero
/// to indicate failure to initialize. DS is set
/// to the library's data segment if the
/// SINGLEDATA flag is set. Otherwise, DS is set
/// to the caller's data segment.
/// </summary>
/// <remarks>
/// A program or DLL can only contain dynamic
/// links to executable files that have this
/// library module flag set. One program cannot
/// dynamic-link to another program.
/// </remarks>
LibraryModule = 0x8000,
#endregion
}
[Flags]
public enum MoveableSegmentEntryFlag : byte
{
/// <summary>
/// Set if the entry is exported.
/// </summary>
Exported = 0x01,
/// <summary>
/// Set if the entry uses a global (shared) data segments.
/// </summary>
Global = 0x02,
}
public enum OperatingSystem : byte
{
OS2 = 0x01,
WINDOWS = 0x02,
EU_MSDOS4 = 0x03,
WINDOWS_386 = 0x04,
BOSS = 0x05,
}
[Flags]
public enum OS2Flag : byte
{
/// <summary>
/// Long filename support
/// </summary>
LongFilenameSupport = 0x01,
/// <summary>
/// 2.x protected mode
/// </summary>
ProtectedMode = 0x02,
/// <summary>
/// 2.x proportional fonts
/// </summary>
ProportionalFonts = 0x04,
/// <summary>
/// Executable has gangload area
/// </summary>
HasGangload = 0x08,
/// <summary>
/// Unknown
/// </summary>
Unknown = 0xF0,
}
public enum OSFixupType : ushort
{
/// <summary>
/// FIARQQ, FJARQQ
/// </summary>
FIARQQ = 0x0001,
/// <summary>
/// FISRQQ, FJSRQQ
/// </summary>
FISRQQ = 0x0002,
/// <summary>
/// FICRQQ, FJCRQQ
/// </summary>
FICRQQ = 0x0003,
FIERQQ = 0x0004,
FIDRQQ = 0x0005,
FIWRQQ = 0x0006,
}
[Flags]
public enum RelocationRecordFlag : byte
{
TARGET_MASK = 0x03,
INTERNALREF = 0x00,
IMPORTORDINAL = 0x01,
IMPORTNAME = 0x02,
OSFIXUP = 0x03,
ADDITIVE = 0x04,
}
public enum RelocationRecordSourceType : byte
{
SOURCE_MASK = 0x0F,
LOBYTE = 0x00,
SEGMENT = 0x02,
/// <summary>
/// 32-bit pointer
/// </summary>
FAR_ADDR = 0x03,
/// <summary>
/// 16-bit offset
/// </summary>
OFFSET = 0x05,
}
[Flags]
public enum ResourceTypeResourceFlag : ushort
{
/// <summary>
/// Resource is not fixed.
/// </summary>
MOVEABLE = 0x0010,
/// <summary>
/// Resource can be shared.
/// </summary>
PURE = 0x0020,
/// <summary>
/// Resource is preloaded.
/// </summary>
PRELOAD = 0x0040,
}
public enum SegmentEntryType
{
/// <summary>
/// 000h - There is no entry data in an unused bundle. The next bundle
/// follows this field. This is used by the linker to skip ordinal numbers.
/// </summary>
Unused,
/// <summary>
/// 001h-0FEh - Segment number for fixed segment entries. A fixed segment
/// entry is 3 bytes long.
/// </summary>
FixedSegment,
/// <summary>
/// 0FFH - Moveable segment entries. The entry data contains the segment
/// number for the entry points. A moveable segment entry is 6 bytes long.
/// </summary>
MoveableSegment,
}
[Flags]
public enum SegmentTableEntryFlag : ushort
{
/// <summary>
/// Segment-type field.
/// </summary>
TYPE_MASK = 0x0007,
/// <summary>
/// Code-segment type.
/// </summary>
CODE = 0x0000,
/// <summary>
/// Data-segment type.
/// </summary>
DATA = 0x0001,
/// <summary>
/// Segment is not fixed.
/// </summary>
MOVEABLE = 0x0010,
/// <summary>
/// Segment will be preloaded; read-only if this is a data segment.
/// </summary>
PRELOAD = 0x0040,
/// <summary>
/// Set if segment has relocation records.
/// </summary>
RELOCINFO = 0x0100,
/// <summary>
/// Discard priority.
/// </summary>
DISCARD = 0xF000,
}
}

View File

@@ -0,0 +1,61 @@
using System.Collections.Generic;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The segmented EXE header contains general information about the EXE
/// file and contains information on the location and size of the other
/// sections. The Windows loader copies this section, along with other
/// data, into the module table in the system data. The module table is
/// internal data used by the loader to manage the loaded executable
/// modules in the system and to support dynamic linking.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
public sealed class Executable
{
/// <summary>
/// MS-DOS executable stub
/// </summary>
public MSDOS.Executable Stub { get; set; }
/// <summary>
/// New Executable header
/// </summary>
public ExecutableHeader Header { get; set; }
/// <summary>
/// Segment table
/// </summary>
public SegmentTableEntry[] SegmentTable { get; set; }
/// <summary>
/// Resource table
/// </summary>
public ResourceTable ResourceTable { get; set; }
/// <summary>
/// Resident-Name table
/// </summary>
public ResidentNameTableEntry[] ResidentNameTable { get; set; }
/// <summary>
/// Module-Reference table
/// </summary>
public ModuleReferenceTableEntry[] ModuleReferenceTable { get; set; }
/// <summary>
/// Imported-Name table
/// </summary>
public Dictionary<ushort, ImportedNameTableEntry> ImportedNameTable { get; set; }
/// <summary>
/// Entry table
/// </summary>
public EntryTableBundle[] EntryTable { get; set; }
/// <summary>
/// Nonresident-Name table
/// </summary>
public NonResidentNameTableEntry[] NonResidentNameTable { get; set; }
}
}

View File

@@ -0,0 +1,198 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The NE header is a relatively large structure with multiple characteristics.
/// Because of the age of the format some items are unclear in meaning.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
/// <see href="https://github.com/libyal/libexe/blob/main/documentation/Executable%20(EXE)%20file%20format.asciidoc#24-ne-extended-header"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ExecutableHeader
{
/// <summary>
/// Signature word.
/// "N" is low-order byte.
/// "E" is high-order byte.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public string Magic;
/// <summary>
/// Version number of the linker.
/// </summary>
public byte LinkerVersion;
/// <summary>
/// Revision number of the linker.
/// </summary>
public byte LinkerRevision;
/// <summary>
/// Entry Table file offset, relative to the beginning of the segmented EXE header.
/// </summary>
public ushort EntryTableOffset;
/// <summary>
/// Number of bytes in the entry table.
/// </summary>
public ushort EntryTableSize;
/// <summary>
/// 32-bit CRC of entire contents of file.
/// </summary>
/// <remarks>These words are taken as 00 during the calculation.</remarks>
public uint CrcChecksum;
/// <summary>
/// Flag word
/// </summary>
public HeaderFlag FlagWord;
/// <summary>
/// Segment number of automatic data segment.
/// This value is set to zero if SINGLEDATA and
/// MULTIPLEDATA flag bits are clear, NOAUTODATA is
/// indicated in the flags word.
/// </summary>
/// <remarks>
/// A Segment number is an index into the module's segment
/// table. The first entry in the segment table is segment
/// number 1.
/// </remarks>
public ushort AutomaticDataSegmentNumber;
/// <summary>
/// Initial size, in bytes, of dynamic heap added to the
/// data segment. This value is zero if no initial local
/// heap is allocated.
/// </summary>
public ushort InitialHeapAlloc;
/// <summary>
/// Initial size, in bytes, of stack added to the data
/// segment. This value is zero to indicate no initial
/// stack allocation, or when SS is not equal to DS.
/// </summary>
public ushort InitialStackAlloc;
/// <summary>
/// Segment number:offset of CS:IP.
/// </summary>
public uint InitialCSIPSetting;
/// <summary>
/// Segment number:offset of SS:SP.
/// </summary>
/// <remarks>
/// If SS equals the automatic data segment and SP equals
/// zero, the stack pointer is set to the top of the
/// automatic data segment just below the additional heap
/// area.
/// </remarks>
public uint InitialSSSPSetting;
/// <summary>
/// Number of entries in the Segment Table.
/// </summary>
public ushort FileSegmentCount;
/// <summary>
/// Number of entries in the Module Reference Table.
/// </summary>
public ushort ModuleReferenceTableSize;
/// <summary>
/// Number of bytes in the Non-Resident Name Table.
/// </summary>
public ushort NonResidentNameTableSize;
/// <summary>
/// Segment Table file offset, relative to the beginning
/// of the segmented EXE header.
/// </summary>
public ushort SegmentTableOffset;
/// <summary>
/// Resource Table file offset, relative to the beginning
/// of the segmented EXE header.
/// </summary>
public ushort ResourceTableOffset;
/// <summary>
/// Resident Name Table file offset, relative to the
/// beginning of the segmented EXE header.
/// </summary>
public ushort ResidentNameTableOffset;
/// <summary>
/// Module Reference Table file offset, relative to the
/// beginning of the segmented EXE header.
/// </summary>
public ushort ModuleReferenceTableOffset;
/// <summary>
/// Imported Names Table file offset, relative to the
/// beginning of the segmented EXE header.
/// </summary>
public ushort ImportedNamesTableOffset;
/// <summary>
/// Non-Resident Name Table offset, relative to the
/// beginning of the file.
/// </summary>
public uint NonResidentNamesTableOffset;
/// <summary>
/// Number of movable entries in the Entry Table.
/// </summary>
public ushort MovableEntriesCount;
/// <summary>
/// Logical sector alignment shift count, log(base 2) of
/// the segment sector size (default 9).
/// </summary>
public ushort SegmentAlignmentShiftCount;
/// <summary>
/// Number of resource entries.
/// </summary>
public ushort ResourceEntriesCount;
/// <summary>
/// Executable type, used by loader.
/// </summary>
public OperatingSystem TargetOperatingSystem;
/// <summary>
/// Other OS/2 flags
/// </summary>
public OS2Flag AdditionalFlags;
/// <summary>
/// Offset to return thunks or start of gangload area
/// </summary>
public ushort ReturnThunkOffset;
/// <summary>
/// Offset to segment reference thunks or size of gangload area
/// </summary>
public ushort SegmentReferenceThunkOffset;
/// <summary>
/// Minimum code swap area size
/// </summary>
public ushort MinCodeSwapAreaSize;
/// <summary>
/// Windows SDK revison number
/// </summary>
public byte WindowsSDKRevision;
/// <summary>
/// Windows SDK version number
/// </summary>
public byte WindowsSDKVersion;
}
}

View File

@@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ImportNameRelocationRecord
{
/// <summary>
/// Index into module reference table for the imported module.
/// </summary>
public ushort Index;
/// <summary>
/// Offset within Imported Names Table to procedure name string.
/// </summary>
public ushort Offset;
}
}

View File

@@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ImportOrdinalRelocationRecord
{
/// <summary>
/// Index into module reference table for the imported module.
/// </summary>
public ushort Index;
/// <summary>
/// Procedure ordinal number.
/// </summary>
public ushort Ordinal;
}
}

View File

@@ -0,0 +1,28 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The imported-name table follows the module-reference table. This table
/// contains the names of modules and procedures that are imported by the
/// executable file. Each entry is composed of a 1-byte field that
/// contains the length of the string, followed by any number of
/// characters. The strings are not null-terminated and are case
/// sensitive.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ImportedNameTableEntry
{
/// <summary>
/// Length of the name string that follows. A zero value indicates
/// the end of the name table.
/// </summary>
public byte Length;
/// <summary>
/// ASCII text of the name string.
/// </summary>
public byte[] NameString;
}
}

View File

@@ -0,0 +1,26 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class InternalRefRelocationRecord
{
/// <summary>
/// Segment number for a fixed segment, or 0FFh for a
/// movable segment.
/// </summary>
public byte SegmentNumber;
/// <summary>
/// 0
/// </summary>
public byte Reserved;
/// <summary>
/// Offset into segment if fixed segment, or ordinal
/// number index into Entry Table if movable segment.
/// </summary>
public ushort Offset;
}
}

View File

@@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The module-reference table follows the resident-name table. Each entry
/// contains an offset for the module-name string within the imported-
/// names table; each entry is 2 bytes long.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ModuleReferenceTableEntry
{
/// <summary>
/// Offset within Imported Names Table to referenced module name string.
/// </summary>
public ushort Offset;
}
}

View File

@@ -0,0 +1,34 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The nonresident-name table follows the entry table, and contains a
/// module description and nonresident exported procedure name strings.
/// The first string in this table is a module description. These name
/// strings are case-sensitive and are not null-terminated. The name
/// strings follow the same format as those defined in the resident name
/// table.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class NonResidentNameTableEntry
{
/// <summary>
/// Length of the name string that follows. A zero value indicates
/// the end of the name table.
/// </summary>
public byte Length;
/// <summary>
/// ASCII text of the name string.
/// </summary>
public byte[] NameString;
/// <summary>
/// Ordinal number (index into entry table). This value is ignored
/// for the module name.
/// </summary>
public ushort OrdinalNumber;
}
}

View File

@@ -0,0 +1,20 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class OSFixupRelocationRecord
{
/// <summary>
/// Operating system fixup type.
/// Floating-point fixups.
/// </summary>
public OSFixupType FixupType;
/// <summary>
/// 0
/// </summary>
public ushort Reserved;
}
}

View File

@@ -0,0 +1,23 @@
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The location and size of the per-segment data is defined in the
/// segment table entry for the segment. If the segment has relocation
/// fixups, as defined in the segment table entry flags, they directly
/// follow the segment data in the file. The relocation fixup information
/// is defined as follows:
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
public sealed class PerSegmentData
{
/// <summary>
/// Number of relocation records that follow.
/// </summary>
public ushort RelocationRecordCount;
/// <summary>
/// A table of relocation records follows.
/// </summary>
public RelocationRecord[] RelocationRecords;
}
}

View File

@@ -0,0 +1,60 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// A table of relocation records follows. The following is the format
/// of each relocation record.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class RelocationRecord
{
/// <summary>
/// Source type.
/// </summary>
public RelocationRecordSourceType SourceType;
/// <summary>
/// Flags byte.
///
/// The target value has four types that are defined in the flag
/// byte field.
/// </summary>
public RelocationRecordFlag Flags;
/// <summary>
/// Offset within this segment of the source chain.
/// If the ADDITIVE flag is set, then target value is added to
/// the source contents, instead of replacing the source and
/// following the chain. The source chain is an 0FFFFh
/// terminated linked list within this segment of all
/// references to the target.
/// </summary>
public ushort Offset;
/// <summary>
/// INTERNALREF
/// </summary>
/// <remarks>Must be <c>NULL</c> if <see cref="Flags"/> is not set to <see cref="RelocationRecordFlag.INTERNALREF"/></remarks>
public InternalRefRelocationRecord InternalRefRelocationRecord;
/// <summary>
/// IMPORTNAME
/// </summary>
/// <remarks>Must be <c>NULL</c> if <see cref="Flags"/> is not set to <see cref="RelocationRecordFlag.IMPORTNAME"/></remarks>
public ImportNameRelocationRecord ImportNameRelocationRecord;
/// <summary>
/// IMPORTORDINAL
/// </summary>
/// <remarks>Must be <c>NULL</c> if <see cref="Flags"/> is not set to <see cref="RelocationRecordFlag.IMPORTORDINAL"/></remarks>
public ImportOrdinalRelocationRecord ImportOrdinalRelocationRecord;
/// <summary>
/// IMPORTORDINAL
/// </summary>
/// <remarks>Must be <c>NULL</c> if <see cref="Flags"/> is not set to <see cref="RelocationRecordFlag.OSFIXUP"/></remarks>
public OSFixupRelocationRecord OSFixupRelocationRecord;
}
}

View File

@@ -0,0 +1,33 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The resident-name table follows the resource table, and contains this
/// module's name string and resident exported procedure name strings. The
/// first string in this table is this module's name. These name strings
/// are case-sensitive and are not null-terminated. The following
/// describes the format of the name strings:
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ResidentNameTableEntry
{
/// <summary>
/// Length of the name string that follows. A zero value indicates
/// the end of the name table.
/// </summary>
public byte Length;
/// <summary>
/// ASCII text of the name string.
/// </summary>
public byte[] NameString;
/// <summary>
/// Ordinal number (index into entry table). This value is ignored
/// for the module name.
/// </summary>
public ushort OrdinalNumber;
}
}

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The resource table follows the segment table and contains entries for
/// each resource in the executable file. The resource table consists of
/// an alignment shift count, followed by a table of resource records. The
/// resource records define the type ID for a set of resources. Each
/// resource record contains a table of resource entries of the defined
/// type. The resource entry defines the resource ID or name ID for the
/// resource. It also defines the location and size of the resource. The
/// following describes the contents of each of these structures:
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ResourceTable
{
/// <summary>
/// Alignment shift count for resource data.
/// </summary>
public ushort AlignmentShiftCount;
/// <summary>
/// A table of resource type information blocks follows.
/// </summary>
public ResourceTypeInformationEntry[] ResourceTypes;
/// <summary>
/// Resource type and name strings are stored at the end of the
/// resource table.
/// </summary>
public Dictionary<ushort, ResourceTypeAndNameString> TypeAndNameStrings;
}
}

View File

@@ -0,0 +1,26 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// Resource type and name strings are stored at the end of the
/// resource table. Note that these strings are NOT null terminated and
/// are case sensitive.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ResourceTypeAndNameString
{
/// <summary>
/// Length of the type or name string that follows. A zero value
/// indicates the end of the resource type and name string, also
/// the end of the resource table.
/// </summary>
public byte Length;
/// <summary>
/// ASCII text of the type or name string.
/// </summary>
public byte[] Text;
}
}

View File

@@ -0,0 +1,37 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// A table of resource type information blocks follows. The following
/// is the format of each type information block:
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ResourceTypeInformationEntry
{
/// <summary>
/// Type ID. This is an integer type if the high-order bit is
/// set (8000h); otherwise, it is an offset to the type string,
/// the offset is relative to the beginning of the resource
/// table. A zero type ID marks the end of the resource type
/// information blocks.
/// </summary>
public ushort TypeID;
/// <summary>
/// Number of resources for this type.
/// </summary>
public ushort ResourceCount;
/// <summary>
/// Reserved.
/// </summary>
public uint Reserved;
/// <summary>
/// A table of resources for this type follows.
/// </summary>
public ResourceTypeResourceEntry[] Resources;
}
}

View File

@@ -0,0 +1,44 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// A table of resources for this type follows. The following is
/// the format of each resource (8 bytes each):
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class ResourceTypeResourceEntry
{
/// <summary>
/// File offset to the contents of the resource data,
/// relative to beginning of file. The offset is in terms
/// of the alignment shift count value specified at
/// beginning of the resource table.
/// </summary>
public ushort Offset;
/// <summary>
/// Length of the resource in the file (in bytes).
/// </summary>
public ushort Length;
/// <summary>
/// Flag word.
/// </summary>
public ResourceTypeResourceFlag FlagWord;
/// <summary>
/// Resource ID. This is an integer type if the high-order
/// bit is set (8000h), otherwise it is the offset to the
/// resource string, the offset is relative to the
/// beginning of the resource table.
/// </summary>
public ushort ResourceID;
/// <summary>
/// Reserved.
/// </summary>
public uint Reserved;
}
}

View File

@@ -0,0 +1,38 @@
using System.Runtime.InteropServices;
namespace BinaryObjectScanner.Models.NewExecutable
{
/// <summary>
/// The segment table contains an entry for each segment in the executable
/// file. The number of segment table entries are defined in the segmented
/// EXE header. The first entry in the segment table is segment number 1.
/// The following is the structure of a segment table entry.
/// </summary>
/// <see href="http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm"/>
[StructLayout(LayoutKind.Sequential)]
public sealed class SegmentTableEntry
{
/// <summary>
/// Logical-sector offset (n byte) to the contents of the segment
/// data, relative to the beginning of the file. Zero means no
/// file data.
/// </summary>
public ushort Offset;
/// <summary>
/// Length of the segment in the file, in bytes. Zero means 64K.
/// </summary>
public ushort Length;
/// <summary>
/// Flag word.
/// </summary>
public SegmentTableEntryFlag FlagWord;
/// <summary>
/// Minimum allocation size of the segment, in bytes. Total size
/// of the segment. Zero means 64K.
/// </summary>
public ushort MinimumAllocationSize;
}
}