// dnlib: See LICENSE.txt for more info using System; using dnlib.IO; namespace dnlib.PE { /// /// Represents the IMAGE_NT_HEADERS PE section /// public sealed class ImageNTHeaders : FileSection { readonly uint signature; readonly ImageFileHeader imageFileHeader; readonly IImageOptionalHeader imageOptionalHeader; /// /// Returns the IMAGE_NT_HEADERS.Signature field /// public uint Signature => signature; /// /// Returns the IMAGE_NT_HEADERS.FileHeader field /// public ImageFileHeader FileHeader => imageFileHeader; /// /// Returns the IMAGE_NT_HEADERS.OptionalHeader field /// public IImageOptionalHeader OptionalHeader => imageOptionalHeader; /// /// Constructor /// /// PE file reader pointing to the start of this section /// Verify section /// Thrown if verification fails public ImageNTHeaders(ref DataReader reader, bool verify) { SetStartOffset(ref reader); signature = reader.ReadUInt32(); // Mono only checks the low 2 bytes if (verify && (ushort)signature != 0x4550) throw new BadImageFormatException("Invalid NT headers signature"); imageFileHeader = new ImageFileHeader(ref reader, verify); imageOptionalHeader = CreateImageOptionalHeader(ref reader, verify); SetEndoffset(ref reader); } /// /// Creates an IImageOptionalHeader /// /// PE file reader pointing to the start of the optional header /// Verify section /// The created IImageOptionalHeader /// Thrown if verification fails IImageOptionalHeader CreateImageOptionalHeader(ref DataReader reader, bool verify) { ushort magic = reader.ReadUInt16(); reader.Position -= 2; return magic switch { 0x010B => new ImageOptionalHeader32(ref reader, imageFileHeader.SizeOfOptionalHeader, verify), 0x020B => new ImageOptionalHeader64(ref reader, imageFileHeader.SizeOfOptionalHeader, verify), _ => throw new BadImageFormatException("Invalid optional header magic"), }; } } }