// 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"),
};
}
}
}