From 49a06f513b26f8eb513c0f974b94a602bf831f49 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 4 Nov 2022 23:56:56 -0700 Subject: [PATCH] Add PE section table --- .../PortableExecutable/Executable.cs | 9 +- .../PortableExecutable/SectionHeader.cs | 104 ++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 BurnOutSharp.Models/PortableExecutable/SectionHeader.cs diff --git a/BurnOutSharp.Models/PortableExecutable/Executable.cs b/BurnOutSharp.Models/PortableExecutable/Executable.cs index e90e7aaf..d6d6cfd0 100644 --- a/BurnOutSharp.Models/PortableExecutable/Executable.cs +++ b/BurnOutSharp.Models/PortableExecutable/Executable.cs @@ -29,6 +29,13 @@ namespace BurnOutSharp.Models.PortableExecutable /// /// Optional header /// - public OptionalHeader Optionalheader { get; set; } + public OptionalHeader OptionalHeader { get; set; } + + /// + /// Section table + /// + public SectionHeader[] SectionTable { get; set; } + + // TODO: Left off at "COFF Relocations (Object Only)" } } diff --git a/BurnOutSharp.Models/PortableExecutable/SectionHeader.cs b/BurnOutSharp.Models/PortableExecutable/SectionHeader.cs new file mode 100644 index 00000000..b8a64569 --- /dev/null +++ b/BurnOutSharp.Models/PortableExecutable/SectionHeader.cs @@ -0,0 +1,104 @@ +using System.Runtime.InteropServices; + +namespace BurnOutSharp.Models.PortableExecutable +{ + /// + /// Each row of the section table is, in effect, a section header. This table + /// immediately follows the optional header, if any. This positioning is required + /// because the file header does not contain a direct pointer to the section table. + /// Instead, the location of the section table is determined by calculating the + /// location of the first byte after the headers. Make sure to use the size of + /// the optional header as specified in the file header. + /// + /// The number of entries in the section table is given by the NumberOfSections + /// field in the file header. Entries in the section table are numbered starting + /// from one (1). The code and data memory section entries are in the order chosen + /// by the linker. + /// + /// In an image file, the VAs for sections must be assigned by the linker so that + /// they are in ascending order and adjacent, and they must be a multiple of the + /// SectionAlignment value in the optional header. + /// + /// + [StructLayout(LayoutKind.Sequential)] + public class SectionHeader + { + /// + /// An 8-byte, null-padded UTF-8 encoded string. If the string is exactly 8 + /// characters long, there is no terminating null. For longer names, this field + /// contains a slash (/) that is followed by an ASCII representation of a + /// decimal number that is an offset into the string table. Executable images + /// do not use a string table and do not support section names longer than 8 + /// characters. Long names in object files are truncated if they are emitted + /// to an executable file. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] + public byte[] Name; + + /// + /// The total size of the section when loaded into memory. If this value is + /// greater than SizeOfRawData, the section is zero-padded. This field is valid + /// only for executable images and should be set to zero for object files. + /// + public uint VirtualSize; + + /// + /// For executable images, the address of the first byte of the section relative + /// to the image base when the section is loaded into memory. For object files, + /// this field is 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 subtracted from offsets during relocation. + /// + public uint VirtualAddress; + + /// + /// The size of the section (for object files) or the size of the initialized + /// data on disk (for image files). For executable images, this must be a multiple + /// of FileAlignment from the optional header. If this is less than VirtualSize, + /// the remainder of the section is zero-filled. Because the SizeOfRawData field + /// is rounded but the VirtualSize field is not, it is possible for SizeOfRawData + /// to be greater than VirtualSize as well. When a section contains only + /// uninitialized data, this field should be zero. + /// + public uint SizeOfRawData; + + /// + /// The file pointer to the first page of the section within the COFF file. For + /// executable images, this must be a multiple of FileAlignment from the optional + /// header. For object files, the value should be aligned on a 4-byte boundary + /// for best performance. When a section contains only uninitialized data, this + /// field should be zero. + /// + public uint PointerToRawData; + + /// + /// The file pointer to the beginning of relocation entries for the section. This + /// is set to zero for executable images or if there are no relocations. + /// + public uint PointerToRelocations; + + /// + /// The file pointer to the beginning of line-number entries for the section. This + /// is set to zero if there are no COFF line numbers. This value should be zero for + /// an image because COFF debugging information is deprecated. + /// + public int PointerToLinenumbers; + + /// + /// The number of relocation entries for the section. This is set to zero for + /// executable images. + /// + public ushort NumberOfRelocations; + + /// + /// The number of line-number entries for the section. This value should be zero + /// for an image because COFF debugging information is deprecated. + /// + public ushort NumberOfLinenumbers; + + /// + /// The flags that describe the characteristics of the section. + /// + public SectionFlags Characteristics; + } +}