// dnlib: See LICENSE.txt for more info
using System;
using dnlib.IO;
namespace dnlib.PE {
///
/// Represents the IMAGE_OPTIONAL_HEADER (32-bit) PE section
///
public sealed class ImageOptionalHeader32 : FileSection, IImageOptionalHeader {
readonly ushort magic;
readonly byte majorLinkerVersion;
readonly byte minorLinkerVersion;
readonly uint sizeOfCode;
readonly uint sizeOfInitializedData;
readonly uint sizeOfUninitializedData;
readonly RVA addressOfEntryPoint;
readonly RVA baseOfCode;
readonly RVA baseOfData;
readonly uint imageBase;
readonly uint sectionAlignment;
readonly uint fileAlignment;
readonly ushort majorOperatingSystemVersion;
readonly ushort minorOperatingSystemVersion;
readonly ushort majorImageVersion;
readonly ushort minorImageVersion;
readonly ushort majorSubsystemVersion;
readonly ushort minorSubsystemVersion;
readonly uint win32VersionValue;
readonly uint sizeOfImage;
readonly uint sizeOfHeaders;
readonly uint checkSum;
readonly Subsystem subsystem;
readonly DllCharacteristics dllCharacteristics;
readonly uint sizeOfStackReserve;
readonly uint sizeOfStackCommit;
readonly uint sizeOfHeapReserve;
readonly uint sizeOfHeapCommit;
readonly uint loaderFlags;
readonly uint numberOfRvaAndSizes;
readonly ImageDataDirectory[] dataDirectories = new ImageDataDirectory[16];
///
/// Returns the IMAGE_OPTIONAL_HEADER.Magic field
///
public ushort Magic => magic;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MajorLinkerVersion field
///
public byte MajorLinkerVersion => majorLinkerVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MinorLinkerVersion field
///
public byte MinorLinkerVersion => minorLinkerVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfCode field
///
public uint SizeOfCode => sizeOfCode;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfInitializedData field
///
public uint SizeOfInitializedData => sizeOfInitializedData;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfUninitializedData field
///
public uint SizeOfUninitializedData => sizeOfUninitializedData;
///
/// Returns the IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint field
///
public RVA AddressOfEntryPoint => addressOfEntryPoint;
///
/// Returns the IMAGE_OPTIONAL_HEADER.BaseOfCode field
///
public RVA BaseOfCode => baseOfCode;
///
/// Returns the IMAGE_OPTIONAL_HEADER.BaseOfData field
///
public RVA BaseOfData => baseOfData;
///
/// Returns the IMAGE_OPTIONAL_HEADER.ImageBase field
///
public ulong ImageBase => imageBase;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SectionAlignment field
///
public uint SectionAlignment => sectionAlignment;
///
/// Returns the IMAGE_OPTIONAL_HEADER.FileAlignment field
///
public uint FileAlignment => fileAlignment;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MajorOperatingSystemVersion field
///
public ushort MajorOperatingSystemVersion => majorOperatingSystemVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MinorOperatingSystemVersion field
///
public ushort MinorOperatingSystemVersion => minorOperatingSystemVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MajorImageVersion field
///
public ushort MajorImageVersion => majorImageVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MinorImageVersion field
///
public ushort MinorImageVersion => minorImageVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MajorSubsystemVersion field
///
public ushort MajorSubsystemVersion => majorSubsystemVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.MinorSubsystemVersion field
///
public ushort MinorSubsystemVersion => minorSubsystemVersion;
///
/// Returns the IMAGE_OPTIONAL_HEADER.Win32VersionValue field
///
public uint Win32VersionValue => win32VersionValue;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfImage field
///
public uint SizeOfImage => sizeOfImage;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeaders field
///
public uint SizeOfHeaders => sizeOfHeaders;
///
/// Returns the IMAGE_OPTIONAL_HEADER.CheckSum field
///
public uint CheckSum => checkSum;
///
/// Returns the IMAGE_OPTIONAL_HEADER.Subsystem field
///
public Subsystem Subsystem => subsystem;
///
/// Returns the IMAGE_OPTIONAL_HEADER.DllCharacteristics field
///
public DllCharacteristics DllCharacteristics => dllCharacteristics;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfStackReserve field
///
public ulong SizeOfStackReserve => sizeOfStackReserve;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfStackCommit field
///
public ulong SizeOfStackCommit => sizeOfStackCommit;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeapReserve field
///
public ulong SizeOfHeapReserve => sizeOfHeapReserve;
///
/// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeapCommit field
///
public ulong SizeOfHeapCommit => sizeOfHeapCommit;
///
/// Returns the IMAGE_OPTIONAL_HEADER.LoaderFlags field
///
public uint LoaderFlags => loaderFlags;
///
/// Returns the IMAGE_OPTIONAL_HEADER.NumberOfRvaAndSizes field
///
public uint NumberOfRvaAndSizes => numberOfRvaAndSizes;
///
/// Returns the IMAGE_OPTIONAL_HEADER.DataDirectories field
///
public ImageDataDirectory[] DataDirectories => dataDirectories;
///
/// Constructor
///
/// PE file reader pointing to the start of this section
/// Total size of this optional header (from the file header)
/// Verify section
/// Thrown if verification fails
public ImageOptionalHeader32(ref DataReader reader, uint totalSize, bool verify) {
if (totalSize < 0x60)
throw new BadImageFormatException("Invalid optional header size");
if (verify && (ulong)reader.Position + totalSize > reader.Length)
throw new BadImageFormatException("Invalid optional header size");
SetStartOffset(ref reader);
magic = reader.ReadUInt16();
majorLinkerVersion = reader.ReadByte();
minorLinkerVersion = reader.ReadByte();
sizeOfCode = reader.ReadUInt32();
sizeOfInitializedData = reader.ReadUInt32();
sizeOfUninitializedData = reader.ReadUInt32();
addressOfEntryPoint = (RVA)reader.ReadUInt32();
baseOfCode = (RVA)reader.ReadUInt32();
baseOfData = (RVA)reader.ReadUInt32();
imageBase = reader.ReadUInt32();
sectionAlignment = reader.ReadUInt32();
fileAlignment = reader.ReadUInt32();
majorOperatingSystemVersion = reader.ReadUInt16();
minorOperatingSystemVersion = reader.ReadUInt16();
majorImageVersion = reader.ReadUInt16();
minorImageVersion = reader.ReadUInt16();
majorSubsystemVersion = reader.ReadUInt16();
minorSubsystemVersion = reader.ReadUInt16();
win32VersionValue = reader.ReadUInt32();
sizeOfImage = reader.ReadUInt32();
sizeOfHeaders = reader.ReadUInt32();
checkSum = reader.ReadUInt32();
subsystem = (Subsystem)reader.ReadUInt16();
dllCharacteristics = (DllCharacteristics)reader.ReadUInt16();
sizeOfStackReserve = reader.ReadUInt32();
sizeOfStackCommit = reader.ReadUInt32();
sizeOfHeapReserve = reader.ReadUInt32();
sizeOfHeapCommit = reader.ReadUInt32();
loaderFlags = reader.ReadUInt32();
numberOfRvaAndSizes = reader.ReadUInt32();
for (int i = 0; i < dataDirectories.Length; i++) {
uint len = reader.Position - (uint)startOffset;
if (len + 8 <= totalSize)
dataDirectories[i] = new ImageDataDirectory(ref reader, verify);
else
dataDirectories[i] = new ImageDataDirectory();
}
reader.Position = (uint)startOffset + totalSize;
SetEndoffset(ref reader);
}
}
}