// This file was generated by Code Generator.
// 2004/10/22 4:34:47

using System;
using System.Text;

namespace Girl.PEAnalyzer
{
	/// <summary>
	/// Immediately after the PE signature is the PE File header
	/// consisting of the following:
	/// </summary>
	public class PEFileHeader : HeaderBase
	{
		/// <summary>
		/// Always 0x14c (see Section 23.1).
		/// </summary>
		public short Machine;

		/// <summary>
		/// Number of sections; indicates size of the Section Table,
		/// which immediately follows the headers.
		/// </summary>
		public short NumberOfSections;

		/// <summary>
		/// Time and date the file was created in seconds since January
		/// 1st 1970 00:00:00 or 0.
		/// </summary>
		public int TimeDateStamp;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public int PointerToSymbolTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public int NumberOfSymbols;

		/// <summary>
		/// Size of the optional header, the format is described below.
		/// </summary>
		public short OptionalHeaderSize;

		/// <summary>
		/// Flags indicating attributes of the file, see
		/// Characteristics.
		/// </summary>
		public short Characteristics;

		public PEFileHeader()
		{
			title = "PE File Header";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Machine = ReadInt16(0);
			NumberOfSections = ReadInt16(2);
			TimeDateStamp = ReadInt32(4);
			PointerToSymbolTable = ReadInt32(8);
			NumberOfSymbols = ReadInt32(12);
			OptionalHeaderSize = ReadInt16(16);
			Characteristics = ReadInt16(18);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, Machine, "Machine: Always 0x14c (see Section 23.1)."));
			sb.Append(GetInfo(2, NumberOfSections, "Number of Sections: Number of sections; indicates size of the Section Table, which immediately follows the headers."));
			sb.Append(GetInfo(4, TimeDateStamp, "Time/Date Stamp: Time and date the file was created in seconds since January 1st 1970 00:00:00 or 0."));
			sb.Append(GetInfo(8, PointerToSymbolTable, "Pointer to Symbol Table: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(12, NumberOfSymbols, "Number of Symbols: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(16, OptionalHeaderSize, "Optional Header Size: Size of the optional header, the format is described below."));
			sb.Append(GetInfo(18, Characteristics, "Characteristics: Flags indicating attributes of the file, see Characteristics."));
		}
	}

	/// <summary>
	/// Immediately after the PE Header is the PE Optional Header.
	/// This header contains the following information:
	/// </summary>
	public class PEOptionalHeader : HeaderBase
	{
		public PEOptionalHeader()
		{
			title = "PE Optional Header";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

		}
	}

	/// <summary>
	/// These fields are required for all PE files and contain the
	/// following information:
	/// </summary>
	public class PEHeaderStandardFields : HeaderBase
	{
		/// <summary>
		/// Always 0x10B (see Section 23.1).
		/// </summary>
		public short Magic;

		/// <summary>
		/// Always 6 (see Section 23.1).
		/// </summary>
		public byte LMajor;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public byte LMinor;

		/// <summary>
		/// Size of the code (text) section, or the sum of all code
		/// sections if there are multiple sections.
		/// </summary>
		public int CodeSize;

		/// <summary>
		/// Size of the initialized data section, or the sum of all such
		/// sections if there are multiple data sections.
		/// </summary>
		public int InitializedDataSize;

		/// <summary>
		/// Size of the uninitialized data section, or the sum of all
		/// such sections if there are multiple unitinitalized data
		/// sections.
		/// </summary>
		public int UninitializedDataSize;

		/// <summary>
		/// RVA of entry point , needs to point to bytes 0xFF 0x25
		/// followed by the RVA in a section marked execute/read for
		/// EXEs or 0 for DLLs
		/// </summary>
		public int EntryPointRVA;

		/// <summary>
		/// RVA of the code section, always 0x00400000 for exes and
		/// 0x10000000 for DLL.
		/// </summary>
		public int BaseOfCode;

		/// <summary>
		/// RVA of the data section.
		/// </summary>
		public int BaseOfData;

		public PEHeaderStandardFields()
		{
			title = "PE Header Standard Fields";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Magic = ReadInt16(0);
			LMajor = ReadByte(2);
			LMinor = ReadByte(3);
			CodeSize = ReadInt32(4);
			InitializedDataSize = ReadInt32(8);
			UninitializedDataSize = ReadInt32(12);
			EntryPointRVA = ReadInt32(16);
			BaseOfCode = ReadInt32(20);
			BaseOfData = ReadInt32(24);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, Magic, "Magic: Always 0x10B (see Section 23.1)."));
			sb.Append(GetInfo(2, LMajor, "LMajor: Always 6 (see Section 23.1)."));
			sb.Append(GetInfo(3, LMinor, "LMinor: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(4, CodeSize, "Code Size: Size of the code (text) section, or the sum of all code sections if there are multiple sections."));
			sb.Append(GetInfo(8, InitializedDataSize, "Initialized Data Size: Size of the initialized data section, or the sum of all such sections if there are multiple data sections."));
			sb.Append(GetInfo(12, UninitializedDataSize, "Uninitialized Data Size: Size of the uninitialized data section, or the sum of all such sections if there are multiple unitinitalized data sections."));
			sb.Append(GetInfo(16, EntryPointRVA, "Entry Point RVA: RVA of entry point , needs to point to bytes 0xFF 0x25 followed by the RVA in a section marked execute/read for EXEs or 0 for DLLs"));
			sb.Append(GetInfo(20, BaseOfCode, "Base Of Code: RVA of the code section, always 0x00400000 for exes and 0x10000000 for DLL."));
			sb.Append(GetInfo(24, BaseOfData, "Base Of Data: RVA of the data section."));
		}
	}

	/// <summary>
	/// These fields are Windows NT specific:
	/// </summary>
	public class PEHeaderWindowsNTSpecificFields : HeaderBase
	{
		/// <summary>
		/// Always 0x400000 (see Section 23.1).
		/// </summary>
		public int ImageBase;

		/// <summary>
		/// Always 0x2000 (see Section 23.1).
		/// </summary>
		public int SectionAlignment;

		/// <summary>
		/// Either 0x200 or 0x1000.
		/// </summary>
		public int FileAlignment;

		/// <summary>
		/// Always 4 (see Section 23.1).
		/// </summary>
		public short OSMajor;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public short OSMinor;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public short UserMajor;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public short UserMinor;

		/// <summary>
		/// Always 4 (see Section 23.1).
		/// </summary>
		public short SubSysMajor;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public short SubSysMinor;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public int Reserved;

		/// <summary>
		/// Size, in bytes, of image, including all headers and padding;
		/// shall be a multiple of Section Alignment.
		/// </summary>
		public int ImageSize;

		/// <summary>
		/// Combined size of MS-DOS Header, PE Header, PE Optional
		/// Header and padding; shall be a multiple of the file
		/// alignment.
		/// </summary>
		public int HeaderSize;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public int FileChecksum;

		/// <summary>
		/// Subsystem required to run this image. Shall be either
		/// IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (0x3) or
		/// IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2).
		/// </summary>
		public short SubSystem;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public short DLLFlags;

		/// <summary>
		/// Always 0x100000 (1Mb) (see Section 23.1).
		/// </summary>
		public int StackReserveSize;

		/// <summary>
		/// Always 0x1000 (4Kb) (see Section 23.1).
		/// </summary>
		public int StackCommitSize;

		/// <summary>
		/// Always 0x100000 (1Mb) (see Section 23.1).
		/// </summary>
		public int HeapReserveSize;

		/// <summary>
		/// Always 0x1000 (4Kb) (see Section 23.1).
		/// </summary>
		public int HeapCommitSize;

		/// <summary>
		/// Always 0 (see Section 23.1)
		/// </summary>
		public int LoaderFlags;

		/// <summary>
		/// Always 0x10 (see Section 23.1).
		/// </summary>
		public int NumberOfDataDirectories;

		public PEHeaderWindowsNTSpecificFields()
		{
			title = "PE Header Windows NT-Specific Fields";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			ImageBase = ReadInt32(28);
			SectionAlignment = ReadInt32(32);
			FileAlignment = ReadInt32(36);
			OSMajor = ReadInt16(40);
			OSMinor = ReadInt16(42);
			UserMajor = ReadInt16(44);
			UserMinor = ReadInt16(46);
			SubSysMajor = ReadInt16(48);
			SubSysMinor = ReadInt16(50);
			Reserved = ReadInt32(52);
			ImageSize = ReadInt32(56);
			HeaderSize = ReadInt32(60);
			FileChecksum = ReadInt32(64);
			SubSystem = ReadInt16(68);
			DLLFlags = ReadInt16(70);
			StackReserveSize = ReadInt32(72);
			StackCommitSize = ReadInt32(76);
			HeapReserveSize = ReadInt32(80);
			HeapCommitSize = ReadInt32(84);
			LoaderFlags = ReadInt32(88);
			NumberOfDataDirectories = ReadInt32(92);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(28, ImageBase, "Image Base: Always 0x400000 (see Section 23.1)."));
			sb.Append(GetInfo(32, SectionAlignment, "Section Alignment: Always 0x2000 (see Section 23.1)."));
			sb.Append(GetInfo(36, FileAlignment, "File Alignment: Either 0x200 or 0x1000."));
			sb.Append(GetInfo(40, OSMajor, "OS Major: Always 4 (see Section 23.1)."));
			sb.Append(GetInfo(42, OSMinor, "OS Minor: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(44, UserMajor, "User Major: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(46, UserMinor, "User Minor: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(48, SubSysMajor, "SubSys Major: Always 4 (see Section 23.1)."));
			sb.Append(GetInfo(50, SubSysMinor, "SubSys Minor: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(52, Reserved, "Reserved: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(56, ImageSize, "Image Size: Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment."));
			sb.Append(GetInfo(60, HeaderSize, "Header Size: Combined size of MS-DOS Header, PE Header, PE Optional Header and padding; shall be a multiple of the file alignment."));
			sb.Append(GetInfo(64, FileChecksum, "File Checksum: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(68, SubSystem, "SubSystem: Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2)."));
			sb.Append(GetInfo(70, DLLFlags, "DLL Flags: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(72, StackReserveSize, "Stack Reserve Size: Always 0x100000 (1Mb) (see Section 23.1)."));
			sb.Append(GetInfo(76, StackCommitSize, "Stack Commit Size: Always 0x1000 (4Kb) (see Section 23.1)."));
			sb.Append(GetInfo(80, HeapReserveSize, "Heap Reserve Size: Always 0x100000 (1Mb) (see Section 23.1)."));
			sb.Append(GetInfo(84, HeapCommitSize, "Heap Commit Size: Always 0x1000 (4Kb) (see Section 23.1)."));
			sb.Append(GetInfo(88, LoaderFlags, "Loader Flags: Always 0 (see Section 23.1)"));
			sb.Append(GetInfo(92, NumberOfDataDirectories, "Number of Data Directories: Always 0x10 (see Section 23.1)."));
		}
	}

	/// <summary>
	/// The optional header data directories give the address and
	/// size of several tables that appear in the sections of the PE
	/// file. Each data directory entry contains the RVA and Size of
	/// the structure it describes.
	/// The tables pointed to by the directory entries are stored in
	/// on of the PE file's sections; these sections themselves are
	/// described by section headers.
	/// </summary>
	public class PEHeaderDataDirectories : HeaderBase
	{
		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long ExportTable;

		/// <summary>
		/// RVA of Import Table, (see clause 24.3.1).
		/// </summary>
		public long ImportTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long ResourceTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long ExceptionTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long CertificateTable;

		/// <summary>
		/// Relocation Table, set to 0 if unused (see clause 24.3.1).
		/// </summary>
		public long BaseRelocationTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long Debug;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long Copyright;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long GlobalPtr;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long TLSTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long LoadConfigTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long BoundImport;

		/// <summary>
		/// RVA of Import Address Table, (see clause 24.3.1).
		/// </summary>
		public long IAT;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long DelayImportDescriptor;

		/// <summary>
		/// CLI Header with directories for runtime data, (see clause
		/// 24.3.1).
		/// </summary>
		public long CLIHeader;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long Reserved;

		public PEHeaderDataDirectories()
		{
			title = "PE Header Data Directories";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			ExportTable = ReadInt64(96);
			ImportTable = ReadInt64(104);
			ResourceTable = ReadInt64(112);
			ExceptionTable = ReadInt64(120);
			CertificateTable = ReadInt64(128);
			BaseRelocationTable = ReadInt64(136);
			Debug = ReadInt64(144);
			Copyright = ReadInt64(152);
			GlobalPtr = ReadInt64(160);
			TLSTable = ReadInt64(168);
			LoadConfigTable = ReadInt64(176);
			BoundImport = ReadInt64(184);
			IAT = ReadInt64(192);
			DelayImportDescriptor = ReadInt64(200);
			CLIHeader = ReadInt64(208);
			Reserved = ReadInt64(216);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(96, ExportTable, "Export Table: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(104, ImportTable, "Import Table: RVA of Import Table, (see clause 24.3.1)."));
			sb.Append(GetInfo(112, ResourceTable, "Resource Table: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(120, ExceptionTable, "Exception Table: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(128, CertificateTable, "Certificate Table: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(136, BaseRelocationTable, "Base Relocation Table: Relocation Table, set to 0 if unused (see clause 24.3.1)."));
			sb.Append(GetInfo(144, Debug, "Debug: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(152, Copyright, "Copyright: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(160, GlobalPtr, "Global Ptr: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(168, TLSTable, "TLS Table: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(176, LoadConfigTable, "Load Config Table: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(184, BoundImport, "Bound Import: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(192, IAT, "IAT: RVA of Import Address Table, (see clause 24.3.1)."));
			sb.Append(GetInfo(200, DelayImportDescriptor, "Delay Import Descriptor: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(208, CLIHeader, "CLI Header: CLI Header with directories for runtime data, (see clause 24.3.1)."));
			sb.Append(GetInfo(216, Reserved, "Reserved: Always 0 (see Section 23.1)."));
		}
	}

	/// <summary>
	/// Immediately following the optional header is the Section
	/// Table, which contains a number of section headers. This
	/// positioning is required because the file header does not
	/// contain a direct pointer to the section table; the location
	/// of the section table is determined by calculating the
	/// location of the first byte after the headers.
	/// Each section header has the following format, for a total of
	/// 40 bytes per entry:
	/// </summary>
	public class SectionHeaders : HeaderBase
	{
		/// <summary>
		/// An 8-byte, null-padded ASCII string. There is no terminating
		/// null if the string is exactly eight characters long.
		/// </summary>
		public long Name;

		/// <summary>
		/// Total size of the section when loaded into memory in bytes
		/// rounded to Section Alignment. If this value is greater than
		/// Size of Raw Data, the section is zero-padded.
		/// </summary>
		public int VirtualSize;

		/// <summary>
		/// For executable images this is the address of the first byte
		/// of the section, when loaded into memory, relative to the
		/// image base.
		/// </summary>
		public int VirtualAddress;

		/// <summary>
		/// Size of the initialized data on disk in bytes, shall be a
		/// multiple of FileAlignment from the PE header. If this is
		/// less than VirtualSize the remainder of the section is zero
		/// filled. Because this field is rounded while the VirtualSize
		/// field is not it is possible for this to be greater than
		/// VirtualSize as well. When a section contains only
		/// uninitialized data, this field should be 0.
		/// </summary>
		public int SizeOfRawData;

		/// <summary>
		/// Offset of section's first page within the PE file. This
		/// shall be a multiple of FileAlignment from the optional
		/// header. When a section contains only uninitialized data,
		/// this field should be 0.
		/// </summary>
		public int PointerToRawData;

		/// <summary>
		/// RVA of Relocation section.
		/// </summary>
		public int PointerToRelocations;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public int PointerToLinenumbers;

		/// <summary>
		/// Number of relocations, set to 0 if unused.
		/// </summary>
		public short NumberOfRelocations;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public short NumberOfLinenumbers;

		/// <summary>
		/// Flags describing section's characteristics, see below.
		/// </summary>
		public int Characteristics;

		public SectionHeaders()
		{
			title = "Section Headers";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Name = ReadInt64(0);
			VirtualSize = ReadInt32(8);
			VirtualAddress = ReadInt32(12);
			SizeOfRawData = ReadInt32(16);
			PointerToRawData = ReadInt32(20);
			PointerToRelocations = ReadInt32(24);
			PointerToLinenumbers = ReadInt32(28);
			NumberOfRelocations = ReadInt16(32);
			NumberOfLinenumbers = ReadInt16(34);
			Characteristics = ReadInt32(36);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, Name, "Name: An 8-byte, null-padded ASCII string. There is no terminating null if the string is exactly eight characters long."));
			sb.Append(GetInfo(8, VirtualSize, "VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded."));
			sb.Append(GetInfo(12, VirtualAddress, "VirtualAddress: For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base."));
			sb.Append(GetInfo(16, SizeOfRawData, "SizeOfRawData: Size of the initialized data on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0."));
			sb.Append(GetInfo(20, PointerToRawData, "PointerToRawData: Offset of section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized data, this field should be 0."));
			sb.Append(GetInfo(24, PointerToRelocations, "PointerToRelocations: RVA of Relocation section."));
			sb.Append(GetInfo(28, PointerToLinenumbers, "PointerToLinenumbers: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(32, NumberOfRelocations, "NumberOfRelocations: Number of relocations, set to 0 if unused."));
			sb.Append(GetInfo(34, NumberOfLinenumbers, "NumberOfLinenumbers: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(36, Characteristics, "Characteristics: Flags describing section's characteristics, see below."));
		}
	}

	/// <summary>
	/// The Import Table and the Import Address Table (IAT) are used
	/// to import the _CorExeMain (for a .exe) or _CorDllMain (for a
	/// .dll) entries of the runtime engine (mscoree.dll). The
	/// Import Table directory entry points to a one element zero
	/// terminated array of Import Directory entries (in a general
	/// PE file there is one entry for each imported DLL):
	/// </summary>
	public class ImportTable : HeaderBase
	{
		/// <summary>
		/// RVA of the Import Lookup Table
		/// </summary>
		public int ImportLookupTable;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public int DateTimeStamp;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public int ForwarderChain;

		/// <summary>
		/// RVA of null terminated ASCII string "mscoree.dll".
		/// </summary>
		public int Name;

		/// <summary>
		/// RVA of Import Address Table (this is the same as the RVA of
		/// the IAT descriptor in the optional header).
		/// </summary>
		public int ImportAddressTable;

		public ImportTable()
		{
			title = "Import Table";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			ImportLookupTable = ReadInt32(0);
			DateTimeStamp = ReadInt32(4);
			ForwarderChain = ReadInt32(8);
			Name = ReadInt32(12);
			ImportAddressTable = ReadInt32(16);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, ImportLookupTable, "ImportLookupTable: RVA of the Import Lookup Table"));
			sb.Append(GetInfo(4, DateTimeStamp, "DateTimeStamp: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(8, ForwarderChain, "ForwarderChain: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(12, Name, "Name: RVA of null terminated ASCII string \"mscoree.dll\"."));
			sb.Append(GetInfo(16, ImportAddressTable, "ImportAddressTable: RVA of Import Address Table (this is the same as the RVA of the IAT descriptor in the optional header)."));
		}
	}

	/// <summary>
	/// In a pure CIL image, a single fixup of type
	/// IMAGE_REL_BASED_HIGHLOW (0x3) is required for the x86
	/// startup stub which access the IAT to load the runtime engine
	/// on down level loaders. When building a mixed CIL/native
	/// image or when the image contains embedded RVAs in user data,
	/// the relocation section contains relocations for these as
	/// well.
	/// The relocations shall be in their own section, named
	/// ".reloc", which shall be the final section in the PE file.
	/// The relocation section contains a Fix-Up Table. The fixup
	/// table is broken into blocks of fixups. Each block represents
	/// the fixups for a 4K page, and each block shall start on a
	/// 32-bit boundary.
	/// Each fixup block starts with the following structure:
	/// </summary>
	public class Relocations : HeaderBase
	{
		/// <summary>
		/// The RVA of the block in which the fixup needs to be applied.
		/// The low 12 bits shall be zero.
		/// </summary>
		public int PageRVA;

		/// <summary>
		/// Total number of bytes in the fixup block, including the Page
		/// RVA and Block Size fields, as well as the Type/Offset fields
		/// that follow, rounded up to the next multiple of 4.
		/// </summary>
		public int BlockSize;

		public Relocations()
		{
			title = "Relocations";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			PageRVA = ReadInt32(0);
			BlockSize = ReadInt32(4);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, PageRVA, "PageRVA: The RVA of the block in which the fixup needs to be applied. The low 12 bits shall be zero."));
			sb.Append(GetInfo(4, BlockSize, "Block Size: Total number of bytes in the fixup block, including the Page RVA and Block Size fields, as well as the Type/Offset fields that follow, rounded up to the next multiple of 4."));
		}
	}

	/// <summary>
	/// The CLI header contains all of the runtime-specific data
	/// entries and other information. The header should be placed
	/// in a read only, sharable section of the image. This header
	/// is defined as follows:
	/// </summary>
	public class CLIHeader : HeaderBase
	{
		/// <summary>
		/// Size of the header in bytes
		/// </summary>
		public int Cb;

		/// <summary>
		/// The minimum version of the runtime required to run this
		/// program, currently 2.
		/// </summary>
		public short MajorRuntimeVersion;

		/// <summary>
		/// The minor portion of the version, currently 0.
		/// </summary>
		public short MinorRuntimeVersion;

		/// <summary>
		/// RVA and size of the physical meta data (see Chapter 23).
		/// </summary>
		public long MetaData;

		/// <summary>
		/// Flags describing this runtime image. (see clause 24.3.3.1).
		/// </summary>
		public int Flags;

		/// <summary>
		/// Token for the MethodDef or File of the entry point for the
		/// image
		/// </summary>
		public int EntryPointToken;

		/// <summary>
		/// Location of CLI resources. (See Partition V ).
		/// </summary>
		public long Resources;

		/// <summary>
		/// RVA of the hash data for this PE file used by the CLI loader
		/// for binding and versioning
		/// </summary>
		public long StrongNameSignature;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long CodeManagerTable;

		/// <summary>
		/// RVA of an array of locations in the file that contain an
		/// array of function pointers (e.g., vtable slots), see below.
		/// </summary>
		public long VTableFixups;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long ExportAddressTableJumps;

		/// <summary>
		/// Always 0 (see Section 23.1).
		/// </summary>
		public long ManagedNativeHeader;

		public CLIHeader()
		{
			title = "CLI Header";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Cb = ReadInt32(0);
			MajorRuntimeVersion = ReadInt16(4);
			MinorRuntimeVersion = ReadInt16(6);
			MetaData = ReadInt64(8);
			Flags = ReadInt32(16);
			EntryPointToken = ReadInt32(20);
			Resources = ReadInt64(24);
			StrongNameSignature = ReadInt64(32);
			CodeManagerTable = ReadInt64(40);
			VTableFixups = ReadInt64(48);
			ExportAddressTableJumps = ReadInt64(56);
			ManagedNativeHeader = ReadInt64(64);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, Cb, "Cb: Size of the header in bytes"));
			sb.Append(GetInfo(4, MajorRuntimeVersion, "MajorRuntimeVersion: The minimum version of the runtime required to run this program, currently 2."));
			sb.Append(GetInfo(6, MinorRuntimeVersion, "MinorRuntimeVersion: The minor portion of the version, currently 0."));
			sb.Append(GetInfo(8, MetaData, "MetaData: RVA and size of the physical meta data (see Chapter 23)."));
			sb.Append(GetInfo(16, Flags, "Flags: Flags describing this runtime image. (see clause 24.3.3.1)."));
			sb.Append(GetInfo(20, EntryPointToken, "EntryPointToken: Token for the MethodDef or File of the entry point for the image"));
			sb.Append(GetInfo(24, Resources, "Resources: Location of CLI resources. (See Partition V )."));
			sb.Append(GetInfo(32, StrongNameSignature, "StrongNameSignature: RVA of the hash data for this PE file used by the CLI loader for binding and versioning"));
			sb.Append(GetInfo(40, CodeManagerTable, "CodeManagerTable: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(48, VTableFixups, "VTableFixups: RVA of an array of locations in the file that contain an array of function pointers (e.g., vtable slots), see below."));
			sb.Append(GetInfo(56, ExportAddressTableJumps, "ExportAddressTableJumps: Always 0 (see Section 23.1)."));
			sb.Append(GetInfo(64, ManagedNativeHeader, "ManagedNativeHeader: Always 0 (see Section 23.1)."));
		}
	}

	/// <summary>
	/// Certain languages, which choose not to follow the common
	/// type system runtime model, may have virtual functions which
	/// need to be represented in a v-table. These v-tables are laid
	/// out by the compiler, not by the runtime. Finding the correct
	/// v-table slot and calling indirectly through the value held
	/// in that slot is also done by the compiler. The VtableFixups
	/// field in the runtime header contains the location and size
	/// of an array of Vtable Fixups (see clause 14.5.1). V-tables
	/// shall be emitted into a read-write section of the PE file.
	/// Each entry in this array describes a contiguous array of
	/// v-table slots of the specified size. Each slot starts out
	/// initialized to the metadata token value for the method they
	/// need to call. At image load time, the runtime Loader will
	/// turn each entry into a pointer to machine code for the CPU
	/// and can be called directly.
	/// </summary>
	public class VtableFixup : HeaderBase
	{
		/// <summary>
		/// RVA of Vtable
		/// </summary>
		public int VirtualAddress;

		/// <summary>
		/// Number of entries in Vtable
		/// </summary>
		public short Size;

		/// <summary>
		/// Type of the entries, as defined in table below
		/// </summary>
		public short Type;

		public VtableFixup()
		{
			title = "Vtable Fixup";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			VirtualAddress = ReadInt32(0);
			Size = ReadInt16(4);
			Type = ReadInt16(6);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, VirtualAddress, "VirtualAddress: RVA of Vtable"));
			sb.Append(GetInfo(4, Size, "Size: Number of entries in Vtable"));
			sb.Append(GetInfo(6, Type, "Type: Type of the entries, as defined in table below"));
		}
	}

	/// <summary>
	/// Exception handling clauses also come in small and fat
	/// versions.
	/// The layout of fat form of exception handling clauses is as
	/// follows:
	/// </summary>
	public class ExceptionHandlingClauses : HeaderBase
	{
		/// <summary>
		/// Flags, see below.
		/// </summary>
		public int Flags;

		/// <summary>
		/// Offset in bytes of try block from start of the header.
		/// </summary>
		public int TryOffset;

		/// <summary>
		/// Length in bytes of the try block
		/// </summary>
		public int TryLength;

		/// <summary>
		/// Location of the handler for this try block
		/// </summary>
		public int HandlerOffset;

		/// <summary>
		/// Size of the handler code in bytes
		/// </summary>
		public int HandlerLength;

		/// <summary>
		/// Meta data token for a type-based exception handler
		/// </summary>
		public int ClassToken;

		/// <summary>
		/// Offset in method body for filter-based exception handler
		/// </summary>
		public int FilterOffset;

		public ExceptionHandlingClauses()
		{
			title = "Exception Handling Clauses";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Flags = ReadInt32(0);
			TryOffset = ReadInt32(4);
			TryLength = ReadInt32(8);
			HandlerOffset = ReadInt32(12);
			HandlerLength = ReadInt32(16);
			ClassToken = ReadInt32(20);
			FilterOffset = ReadInt32(20);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, Flags, "Flags: Flags, see below."));
			sb.Append(GetInfo(4, TryOffset, "TryOffset: Offset in bytes of try block from start of the header."));
			sb.Append(GetInfo(8, TryLength, "TryLength: Length in bytes of the try block"));
			sb.Append(GetInfo(12, HandlerOffset, "HandlerOffset: Location of the handler for this try block"));
			sb.Append(GetInfo(16, HandlerLength, "HandlerLength: Size of the handler code in bytes"));
			sb.Append(GetInfo(20, ClassToken, "ClassToken: Meta data token for a type-based exception handler"));
			sb.Append(GetInfo(20, FilterOffset, "FilterOffset: Offset in method body for filter-based exception handler"));
		}
	}

	/// <summary>
	/// The root of the physical metadata starts with a magic
	/// signature, several bytes of version and other miscellaneous
	/// information, followed by a count and an array of stream
	/// headers, one for each stream that is present. The actual
	/// encoded tables and heaps are stored in the streams, which
	/// immediately follow this array of headers.
	/// </summary>
	public class MetadataRoot : HeaderBase
	{
		/// <summary>
		/// Magic signature for physical metadata : 0x424A5342.
		/// </summary>
		public int Signature;

		/// <summary>
		/// Major version, 1 (ignore on read)
		/// </summary>
		public short MajorVersion;

		/// <summary>
		/// Minor version, 1 (ignore on read)
		/// </summary>
		public short MinorVersion;

		/// <summary>
		/// Reserved, always 0 (see Section 23.1).
		/// </summary>
		public int Reserved;

		/// <summary>
		/// Length of version string in bytes, say m (&lt;= 255), rounded
		/// up to a multiple of four.
		/// </summary>
		public int Length;

		public MetadataRoot()
		{
			title = "Metadata root";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Signature = ReadInt32(0);
			MajorVersion = ReadInt16(4);
			MinorVersion = ReadInt16(6);
			Reserved = ReadInt32(8);
			Length = ReadInt32(12);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, Signature, "Signature: Magic signature for physical metadata : 0x424A5342."));
			sb.Append(GetInfo(4, MajorVersion, "MajorVersion: Major version, 1 (ignore on read)"));
			sb.Append(GetInfo(6, MinorVersion, "MinorVersion: Minor version, 1 (ignore on read)"));
			sb.Append(GetInfo(8, Reserved, "Reserved: Reserved, always 0 (see Section 23.1)."));
			sb.Append(GetInfo(12, Length, "Length: Length of version string in bytes, say m (<= 255), rounded up to a multiple of four."));
		}
	}

	/// <summary>
	/// The "#~" streams contain the actual physical representations
	/// of the logical metadata tables (see Chapter 21). A "#~"
	/// stream has the following top-level structure:
	/// </summary>
	public class SharpTildeStream : HeaderBase
	{
		/// <summary>
		/// Reserved, always 0 (see Section 23.1).
		/// </summary>
		public int Reserved1;

		/// <summary>
		/// Major version of table schemata, always 1 (see Section
		/// 23.1).
		/// </summary>
		public byte MajorVersion;

		/// <summary>
		/// Minor version of table schemata, always 0 (see Section
		/// 23.1).
		/// </summary>
		public byte MinorVersion;

		/// <summary>
		/// Bit vector for heap sizes.
		/// </summary>
		public byte HeapSizes;

		/// <summary>
		/// Reserved, always 1 (see Section 23.1).
		/// </summary>
		public byte Reserved2;

		/// <summary>
		/// Bit vector of present tables, let n be the number of bits
		/// that are 1.
		/// </summary>
		public long Valid;

		/// <summary>
		/// Bit vector of sorted tables.
		/// </summary>
		public long Sorted;

		public SharpTildeStream()
		{
			title = "Sharp Tilde (#~) Stream";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Reserved1 = ReadInt32(0);
			MajorVersion = ReadByte(4);
			MinorVersion = ReadByte(5);
			HeapSizes = ReadByte(6);
			Reserved2 = ReadByte(7);
			Valid = ReadInt64(8);
			Sorted = ReadInt64(16);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(0, Reserved1, "Reserved1: Reserved, always 0 (see Section 23.1)."));
			sb.Append(GetInfo(4, MajorVersion, "MajorVersion: Major version of table schemata, always 1 (see Section 23.1)."));
			sb.Append(GetInfo(5, MinorVersion, "MinorVersion: Minor version of table schemata, always 0 (see Section 23.1)."));
			sb.Append(GetInfo(6, HeapSizes, "HeapSizes: Bit vector for heap sizes."));
			sb.Append(GetInfo(7, Reserved2, "Reserved2: Reserved, always 1 (see Section 23.1)."));
			sb.Append(GetInfo(8, Valid, "Valid: Bit vector of present tables, let n be the number of bits that are 1."));
			sb.Append(GetInfo(16, Sorted, "Sorted: Bit vector of sorted tables."));
		}
	}
}
