internal static ImageOptionalHeader FromReadingContext(ReadingContext context)
{
var reader = context.Reader;
var header = new ImageOptionalHeader
{
StartOffset = reader.Position,
Magic = (OptionalHeaderMagic)reader.ReadUInt16(),
MajorLinkerVersion = reader.ReadByte(),
MinorLinkerVersion = reader.ReadByte(),
SizeOfCode = reader.ReadUInt32(),
SizeOfInitializedData = reader.ReadUInt32(),
SizeOfUninitializedData = reader.ReadUInt32(),
AddressOfEntrypoint = reader.ReadUInt32(),
BaseOfCode = reader.ReadUInt32()
};
switch (header.Magic)
{
case OptionalHeaderMagic.Pe32:
header.BaseOfData = reader.ReadUInt32();
header.ImageBase = reader.ReadUInt32();
break;
case OptionalHeaderMagic.Pe32Plus:
header.ImageBase = reader.ReadUInt64();
break;
default:
throw new NotSupportedException(string.Format("Unrecognized or unsupported executable format."));
}
header.SectionAlignment = reader.ReadUInt32();
header.FileAlignment = reader.ReadUInt32();
header.MajorOperatingSystemVersion = reader.ReadUInt16();
header.MinorOperatingSystemVersion = reader.ReadUInt16();
header.MajorImageVersion = reader.ReadUInt16();
header.MinorImageVersion = reader.ReadUInt16();
header.MajorSubsystemVersion = reader.ReadUInt16();
header.MinorSubsystemVersion = reader.ReadUInt16();
header.Win32VersionValue = reader.ReadUInt32();
header.SizeOfImage = reader.ReadUInt32();
header.SizeOfHeaders = reader.ReadUInt32();
header.CheckSum = reader.ReadUInt32();
header.Subsystem = (ImageSubSystem)reader.ReadUInt16();
header.DllCharacteristics = (ImageDllCharacteristics)reader.ReadUInt16();
if (header.Magic == OptionalHeaderMagic.Pe32)
{
header.SizeOfStackReserve = reader.ReadUInt32();
header.SizeOfStackCommit = reader.ReadUInt32();
header.SizeOfHeapReserve = reader.ReadUInt32();
header.SizeOfHeapCommit = reader.ReadUInt32();
}
else
{
header.SizeOfStackReserve = reader.ReadUInt64();
header.SizeOfStackCommit = reader.ReadUInt64();
header.SizeOfHeapReserve = reader.ReadUInt64();
header.SizeOfHeapCommit = reader.ReadUInt64();
}
header.LoaderFlags = reader.ReadUInt32();
header.NumberOfRvaAndSizes = reader.ReadUInt32();
int dataDirectories = context.Parameters.ForceDataDirectoryCount
? context.Parameters.DataDirectoryCount
: (int)header.NumberOfRvaAndSizes;
for (int i = 0; i < dataDirectories; i++)
{
header.DataDirectories.Add(ImageDataDirectory.FromReadingContext(context));
}
return(header);
}