Files
Matt Nadareski 7689c6dd07 Libraries
This change looks dramatic, but it's just separating out the already-split namespaces into separate top-level folders. In theory, every single one could be built into their own Nuget package. `SabreTools.Serialization` still builds the normal Nuget package that is used by all other projects and includes all namespaces.
2026-03-21 16:26:56 -04:00

251 lines
10 KiB
C#

using System.Collections.Generic;
namespace SabreTools.Data.Models.PortableExecutable
{
/// <summary>
/// The following list describes the Microsoft PE executable format, with the
/// base of the image header at the top. The section from the MS-DOS 2.0
/// Compatible EXE Header through to the unused section just before the PE header
/// is the MS-DOS 2.0 Section, and is used for MS-DOS compatibility only.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
public sealed class Executable
{
/// <summary>
/// MS-DOS executable stub
/// </summary>
public MSDOS.Executable Stub { get; set; } = new();
/// <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).
/// </summary>
public string Signature { get; set; } = string.Empty;
/// <summary>
/// File header
/// </summary>
public COFF.FileHeader FileHeader { get; set; } = new();
/// <summary>
/// Microsoft extended optional header
/// </summary>
public OptionalHeader OptionalHeader { get; set; } = new();
/// <summary>
/// Section table
/// </summary>
public COFF.SectionHeader[] SectionTable { get; set; } = [];
/// <summary>
/// Symbol table
/// </summary>
public COFF.SymbolTableEntries.BaseEntry[]? SymbolTable { get; set; }
/// <summary>
/// String table
/// </summary>
public COFF.StringTable? StringTable { get; set; }
#region Data Directories
/// <summary>
/// The export data section, named .edata, contains information about symbols that other images
/// can access through dynamic linking. Exported symbols are generally found in DLLs, but DLLs
/// can also import symbols.
///
/// An overview of the general structure of the export section is described below. The tables
/// described are usually contiguous in the file in the order shown (though this is not
/// required). Only the export directory table and export address table are required to export
/// symbols as ordinals. (An ordinal is an export that is accessed directly by its export
/// address table index.) The name pointer table, ordinal table, and export name table all
/// exist to support use of export names.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
#region Export Table (.edata)
/// <summary>
/// A table with just one row (unlike the debug directory). This table indicates the
/// locations and sizes of the other export tables.
/// </summary>
public Export.DirectoryTable? ExportDirectoryTable { get; set; }
/// <summary>
/// An array of RVAs of exported symbols. These are the actual addresses of the exported
/// functions and data within the executable code and data sections. Other image files
/// can import a symbol by using an index to this table (an ordinal) or, optionally, by
/// using the public name that corresponds to the ordinal if a public name is defined.
/// </summary>
public Export.AddressTableEntry[]? ExportAddressTable { get; set; }
/// <summary>
/// An array of pointers to the public export names, sorted in ascending order.
/// </summary>
public Export.NamePointerTable? NamePointerTable { get; set; }
/// <summary>
/// An array of the ordinals that correspond to members of the name pointer table. The
/// correspondence is by position; therefore, the name pointer table and the ordinal table
/// must have the same number of members. Each ordinal is an index into the export address
/// table.
/// </summary>
public Export.OrdinalTable? OrdinalTable { get; set; }
/// <summary>
/// A series of null-terminated ASCII strings. Members of the name pointer table point into
/// this area. These names are the public names through which the symbols are imported and
/// exported; they are not necessarily the same as the private names that are used within
/// the image file.
/// </summary>
public Export.NameTable? ExportNameTable { get; set; }
#endregion
/// <summary>
/// All image files that import symbols, including virtually all executable (EXE) files,
/// have an .idata section. A typical file layout for the import information follows:
///
/// - Directory Table
/// Null Directory Entry
/// - DLL1 Import Lookup Table
/// Null
/// - DLL2 Import Lookup Table
/// Null
/// - DLL3 Import Lookup Table
/// Null
/// - Hint-Name Table
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format"/>
#region Import Table (.idata) and Import Address Table
/// <summary>
/// The import information begins with the import directory table, which describes the
/// remainder of the import information.
/// </summary>
public Import.DirectoryTableEntry[]? ImportDirectoryTable { get; set; }
/// <summary>
/// An import lookup table is an array of 32-bit numbers for PE32 or an array of 64-bit
/// numbers for PE32+.
/// </summary>
public Dictionary<int, Import.LookupTableEntry[]?>? ImportLookupTables { get; set; }
/// <summary>
/// These addresses are the actual memory addresses of the symbols, although technically
/// they are still called "virtual addresses".
/// </summary>
public Dictionary<int, Import.AddressTableEntry[]?>? ImportAddressTables { get; set; }
/// <summary>
/// One hint/name table suffices for the entire import section.
/// </summary>
public Import.HintNameTableEntry[]? HintNameTable { get; set; }
#endregion
#region Resource Table (.rsrc)
/// <summary>
/// Resource directory table (.rsrc)
/// </summary>
public Resource.DirectoryTable? ResourceDirectoryTable { get; set; }
#endregion
// TODO: Handle Exception Table
#region Certificate Table
/// <summary>
/// Attribute certificate table
/// </summary>
public AttributeCertificate.Entry[]? AttributeCertificateTable { get; set; }
#endregion
#region Base Relocation Table (.reloc)
/// <summary>
/// Base relocation table
/// </summary>
public BaseRelocation.Block[]? BaseRelocationTable { get; set; }
#endregion
#region Debug Data (.debug*)
/// <summary>
/// Debug table
/// </summary>
public DebugData.Table? DebugTable { get; set; }
#endregion
// TODO: Handle Architecture
// TODO: Handle Global Ptr
// TODO: Thread Local Storage (.tls)
// TODO: Load Configuration Table
// TODO: Bound Import Table
#region Delay Load Table
/// <summary>
/// Delay-load directory table
/// </summary>
public DelayLoad.DirectoryTable? DelayLoadDirectoryTable { get; set; }
#endregion
// TODO: CLR Runtime Header (.cormeta)
// TODO: Reserved
#endregion
#region Named Sections
// TODO: Support grouped sections in section reading and parsing
// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#grouped-sections-object-only
// Grouped sections are ordered and mean that the data in the sections contributes
// to the "base" section (the one without the "$X" suffix). This may negatively impact
// the use of some of the different types of executables.
// .cormeta - CLR metadata is stored in this section. It is used to indicate that
// the object file contains managed code. The format of the metadata is not
// documented, but can be handed to the CLR interfaces for handling metadata.
// .drectve - A section is a directive section if it has the IMAGE_SCN_LNK_INFO
// flag set in the section header and has the .drectve section name. The linker
// removes a .drectve section after processing the information, so the section
// does not appear in the image file that is being linked.
//
// A .drectve section consists of a string of text that can be encoded as ANSI
// or UTF-8. If the UTF-8 byte order marker (BOM, a three-byte prefix that
// consists of 0xEF, 0xBB, and 0xBF) is not present, the directive string is
// interpreted as ANSI. The directive string is a series of linker options that
// are separated by spaces. Each option contains a hyphen, the option name, and
// any appropriate attribute. If an option contains spaces, the option must be
// enclosed in quotes. The .drectve section must not have relocations or line
// numbers.
//
// TODO: Can we implement reading/parsing the .drectve section?
// .pdata Section - Multiple formats per entry
// .sxdata - The valid exception handlers of an object are listed in the .sxdata
// section of that object. The section is marked IMAGE_SCN_LNK_INFO. It contains
// the COFF symbol index of each valid handler, using 4 bytes per index.
//
// Additionally, the compiler marks a COFF object as registered SEH by emitting
// the absolute symbol "@feat.00" with the LSB of the value field set to 1. A
// COFF object with no registered SEH handlers would have the "@feat.00" symbol,
// but no .sxdata section.
//
// TODO: Can we implement reading/parsing the .sxdata section?
#endregion
// TODO: Determine if "Archive (Library) File Format" is worth modelling
}
}