< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 126
Coverable lines: 126
Total lines: 381
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
Size(...)0%220%
.ctor(...)0%10100%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEHeader.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics;
 5using System.Reflection.Metadata;
 6
 7namespace System.Reflection.PortableExecutable
 8{
 9    public sealed class PEHeader
 10    {
 11        #region Standard fields
 12
 13        /// <summary>
 14        /// Identifies the format of the image file.
 15        /// </summary>
 016        public PEMagic Magic { get; }
 17
 18        /// <summary>
 19        /// The linker major version number.
 20        /// </summary>
 021        public byte MajorLinkerVersion { get; }
 22
 23        /// <summary>
 24        /// The linker minor version number.
 25        /// </summary>
 026        public byte MinorLinkerVersion { get; }
 27
 28        /// <summary>
 29        /// The size of the code (text) section, or the sum of all code sections if there are multiple sections.
 30        /// </summary>
 031        public int SizeOfCode { get; }
 32
 33        /// <summary>
 34        /// The size of the initialized data section, or the sum of all such sections if there are multiple data section
 35        /// </summary>
 036        public int SizeOfInitializedData { get; }
 37
 38        /// <summary>
 39        /// The size of the uninitialized data section (BSS), or the sum of all such sections if there are multiple BSS 
 40        /// </summary>
 041        public int SizeOfUninitializedData { get; }
 42
 43        /// <summary>
 44        /// The address of the entry point relative to the image base when the PE file is loaded into memory.
 45        /// For program images, this is the starting address. For device drivers, this is the address of the initializat
 46        /// An entry point is optional for DLLs. When no entry point is present, this field must be zero.
 47        /// </summary>
 048        public int AddressOfEntryPoint { get; }
 49
 50        /// <summary>
 51        /// The address that is relative to the image base of the beginning-of-code section when it is loaded into memor
 52        /// </summary>
 053        public int BaseOfCode { get; }
 54
 55        /// <summary>
 56        /// The address that is relative to the image base of the beginning-of-data section when it is loaded into memor
 57        /// </summary>
 058        public int BaseOfData { get; }
 59
 60        #endregion
 61
 62        #region Windows Specific Fields
 63
 64        /// <summary>
 65        /// The preferred address of the first byte of image when loaded into memory;
 66        /// must be a multiple of 64K.
 67        /// </summary>
 068        public ulong ImageBase { get; }
 69
 70        /// <summary>
 71        /// The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to <
 72        /// The default is the page size for the architecture.
 73        /// </summary>
 074        public int SectionAlignment { get; }
 75
 76        /// <summary>
 77        /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file.
 78        /// The value should be a power of 2 between 512 and 64K, inclusive. The default is 512.
 79        /// If the <see cref="SectionAlignment"/> is less than the architecture's page size,
 80        /// then <see cref="FileAlignment"/> must match <see cref="SectionAlignment"/>.
 81        /// </summary>
 082        public int FileAlignment { get; }
 83
 84        /// <summary>
 85        /// The major version number of the required operating system.
 86        /// </summary>
 087        public ushort MajorOperatingSystemVersion { get; }
 88
 89        /// <summary>
 90        /// The minor version number of the required operating system.
 91        /// </summary>
 092        public ushort MinorOperatingSystemVersion { get; }
 93
 94        /// <summary>
 95        /// The major version number of the image.
 96        /// </summary>
 097        public ushort MajorImageVersion { get; }
 98
 99        /// <summary>
 100        /// The minor version number of the image.
 101        /// </summary>
 0102        public ushort MinorImageVersion { get; }
 103
 104        /// <summary>
 105        /// The major version number of the subsystem.
 106        /// </summary>
 0107        public ushort MajorSubsystemVersion { get; }
 108
 109        /// <summary>
 110        /// The minor version number of the subsystem.
 111        /// </summary>
 0112        public ushort MinorSubsystemVersion { get; }
 113
 114        /// <summary>
 115        /// The size (in bytes) of the image, including all headers, as the image is loaded in memory.
 116        /// It must be a multiple of <see cref="SectionAlignment"/>.
 117        /// </summary>
 0118        public int SizeOfImage { get; }
 119
 120        /// <summary>
 121        /// The combined size of an MS DOS stub, PE header, and section headers rounded up to a multiple of FileAlignmen
 122        /// </summary>
 0123        public int SizeOfHeaders { get; }
 124
 125        /// <summary>
 126        /// The image file checksum.
 127        /// </summary>
 0128        public uint CheckSum { get; }
 129
 130        /// <summary>
 131        /// The subsystem that is required to run this image.
 132        /// </summary>
 0133        public Subsystem Subsystem { get; }
 134
 0135        public DllCharacteristics DllCharacteristics { get; }
 136
 137        /// <summary>
 138        /// The size of the stack to reserve. Only <see cref="SizeOfStackCommit"/> is committed;
 139        /// the rest is made available one page at a time until the reserve size is reached.
 140        /// </summary>
 0141        public ulong SizeOfStackReserve { get; }
 142
 143        /// <summary>
 144        /// The size of the stack to commit.
 145        /// </summary>
 0146        public ulong SizeOfStackCommit { get; }
 147
 148        /// <summary>
 149        /// The size of the local heap space to reserve. Only <see cref="SizeOfHeapCommit"/> is committed;
 150        /// the rest is made available one page at a time until the reserve size is reached.
 151        /// </summary>
 0152        public ulong SizeOfHeapReserve { get; }
 153
 154        /// <summary>
 155        /// The size of the local heap space to commit.
 156        /// </summary>
 0157        public ulong SizeOfHeapCommit { get; }
 158
 159        /// <summary>
 160        /// The number of data-directory entries in the remainder of the <see cref="PEHeader"/>. Each describes a locati
 161        /// </summary>
 0162        public int NumberOfRvaAndSizes { get; }
 163
 164        #endregion
 165
 166        #region Directory Entries
 167
 168        /// <remarks>
 169        /// Aka IMAGE_DIRECTORY_ENTRY_EXPORT.
 170        /// </remarks>
 0171        public DirectoryEntry ExportTableDirectory { get; }
 172
 173        /// <remarks>
 174        /// Aka IMAGE_DIRECTORY_ENTRY_IMPORT.
 175        /// </remarks>
 0176        public DirectoryEntry ImportTableDirectory { get; }
 177
 178        /// <remarks>
 179        /// Aka IMAGE_DIRECTORY_ENTRY_RESOURCE.
 180        /// </remarks>
 0181        public DirectoryEntry ResourceTableDirectory { get; }
 182
 183        /// <remarks>
 184        /// Aka IMAGE_DIRECTORY_ENTRY_EXCEPTION.
 185        /// </remarks>
 0186        public DirectoryEntry ExceptionTableDirectory { get; }
 187
 188        /// <summary>
 189        /// The Certificate Table entry points to a table of attribute certificates.
 190        /// </summary>
 191        /// <remarks>
 192        /// These certificates are not loaded into memory as part of the image.
 193        /// As such, the first field of this entry, which is normally an RVA, is a file pointer instead.
 194        ///
 195        /// Aka IMAGE_DIRECTORY_ENTRY_SECURITY.
 196        /// </remarks>
 0197        public DirectoryEntry CertificateTableDirectory { get; }
 198
 199        /// <remarks>
 200        /// Aka IMAGE_DIRECTORY_ENTRY_BASERELOC.
 201        /// </remarks>
 0202        public DirectoryEntry BaseRelocationTableDirectory { get; }
 203
 204        /// <remarks>
 205        /// Aka IMAGE_DIRECTORY_ENTRY_DEBUG.
 206        /// </remarks>
 0207        public DirectoryEntry DebugTableDirectory { get; }
 208
 209        /// <remarks>
 210        /// Aka IMAGE_DIRECTORY_ENTRY_COPYRIGHT or IMAGE_DIRECTORY_ENTRY_ARCHITECTURE.
 211        /// </remarks>
 0212        public DirectoryEntry CopyrightTableDirectory { get; }
 213
 214        /// <remarks>
 215        /// Aka IMAGE_DIRECTORY_ENTRY_GLOBALPTR.
 216        /// </remarks>
 0217        public DirectoryEntry GlobalPointerTableDirectory { get; }
 218
 219        /// <remarks>
 220        /// Aka IMAGE_DIRECTORY_ENTRY_TLS.
 221        /// </remarks>
 0222        public DirectoryEntry ThreadLocalStorageTableDirectory { get; }
 223
 224        /// <remarks>
 225        /// Aka IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG.
 226        /// </remarks>
 0227        public DirectoryEntry LoadConfigTableDirectory { get; }
 228
 229        /// <remarks>
 230        /// Aka IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT.
 231        /// </remarks>
 0232        public DirectoryEntry BoundImportTableDirectory { get; }
 233
 234        /// <remarks>
 235        /// Aka IMAGE_DIRECTORY_ENTRY_IAT.
 236        /// </remarks>
 0237        public DirectoryEntry ImportAddressTableDirectory { get; }
 238
 239        /// <remarks>
 240        /// Aka IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT.
 241        /// </remarks>
 0242        public DirectoryEntry DelayImportTableDirectory { get; }
 243
 244        /// <remarks>
 245        /// Aka IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR.
 246        /// </remarks>
 0247        public DirectoryEntry CorHeaderTableDirectory { get; }
 248
 249        #endregion
 250
 251        internal const int OffsetOfChecksum =
 252            sizeof(short) +                              // Magic
 253            sizeof(byte) +                               // MajorLinkerVersion
 254            sizeof(byte) +                               // MinorLinkerVersion
 255            sizeof(int) +                                // SizeOfCode
 256            sizeof(int) +                                // SizeOfInitializedData
 257            sizeof(int) +                                // SizeOfUninitializedData
 258            sizeof(int) +                                // AddressOfEntryPoint
 259            sizeof(int) +                                // BaseOfCode
 260            sizeof(long) +                               // PE32:  BaseOfData (int), ImageBase (int)
 261                                                         // PE32+: ImageBase (long)
 262            sizeof(int) +                                // SectionAlignment
 263            sizeof(int) +                                // FileAlignment
 264            sizeof(short) +                              // MajorOperatingSystemVersion
 265            sizeof(short) +                              // MinorOperatingSystemVersion
 266            sizeof(short) +                              // MajorImageVersion
 267            sizeof(short) +                              // MinorImageVersion
 268            sizeof(short) +                              // MajorSubsystemVersion
 269            sizeof(short) +                              // MinorSubsystemVersion
 270            sizeof(int) +                                // Win32VersionValue
 271            sizeof(int) +                                // SizeOfImage
 272            sizeof(int);                                 // SizeOfHeaders
 273
 274        internal static int Size(bool is32Bit) =>
 0275            OffsetOfChecksum +
 0276            sizeof(int) +                                // Checksum
 0277            sizeof(short) +                              // Subsystem
 0278            sizeof(short) +                              // DllCharacteristics
 0279            4 * (is32Bit ? sizeof(int) : sizeof(long)) + // SizeOfStackReserve, SizeOfStackCommit, SizeOfHeapReserve, Si
 0280            sizeof(int) +                                // LoaderFlags
 0281            sizeof(int) +                                // NumberOfRvaAndSizes
 0282            16 * sizeof(long);                           // directory entries
 283
 0284        internal PEHeader(ref PEBinaryReader reader)
 0285        {
 0286            PEMagic magic = (PEMagic)reader.ReadUInt16();
 0287            if (magic != PEMagic.PE32 && magic != PEMagic.PE32Plus)
 0288            {
 0289                throw new BadImageFormatException(SR.UnknownPEMagicValue);
 290            }
 291
 0292            Magic = magic;
 0293            MajorLinkerVersion = reader.ReadByte();
 0294            MinorLinkerVersion = reader.ReadByte();
 0295            SizeOfCode = reader.ReadInt32();
 0296            SizeOfInitializedData = reader.ReadInt32();
 0297            SizeOfUninitializedData = reader.ReadInt32();
 0298            AddressOfEntryPoint = reader.ReadInt32();
 0299            BaseOfCode = reader.ReadInt32();
 300
 0301            if (magic == PEMagic.PE32Plus)
 0302            {
 0303                BaseOfData = 0; // not present
 0304            }
 305            else
 0306            {
 0307                Debug.Assert(magic == PEMagic.PE32);
 0308                BaseOfData = reader.ReadInt32();
 0309            }
 310
 0311            if (magic == PEMagic.PE32Plus)
 0312            {
 0313                ImageBase = reader.ReadUInt64();
 0314            }
 315            else
 0316            {
 0317                ImageBase = reader.ReadUInt32();
 0318            }
 319
 320            // NT additional fields:
 0321            SectionAlignment = reader.ReadInt32();
 0322            FileAlignment = reader.ReadInt32();
 0323            MajorOperatingSystemVersion = reader.ReadUInt16();
 0324            MinorOperatingSystemVersion = reader.ReadUInt16();
 0325            MajorImageVersion = reader.ReadUInt16();
 0326            MinorImageVersion = reader.ReadUInt16();
 0327            MajorSubsystemVersion = reader.ReadUInt16();
 0328            MinorSubsystemVersion = reader.ReadUInt16();
 329
 330            // Win32VersionValue (reserved, should be 0)
 0331            reader.ReadUInt32();
 332
 0333            SizeOfImage = reader.ReadInt32();
 0334            SizeOfHeaders = reader.ReadInt32();
 0335            CheckSum = reader.ReadUInt32();
 0336            Subsystem = (Subsystem)reader.ReadUInt16();
 0337            DllCharacteristics = (DllCharacteristics)reader.ReadUInt16();
 338
 0339            if (magic == PEMagic.PE32Plus)
 0340            {
 0341                SizeOfStackReserve = reader.ReadUInt64();
 0342                SizeOfStackCommit = reader.ReadUInt64();
 0343                SizeOfHeapReserve = reader.ReadUInt64();
 0344                SizeOfHeapCommit = reader.ReadUInt64();
 0345            }
 346            else
 0347            {
 0348                SizeOfStackReserve = reader.ReadUInt32();
 0349                SizeOfStackCommit = reader.ReadUInt32();
 0350                SizeOfHeapReserve = reader.ReadUInt32();
 0351                SizeOfHeapCommit = reader.ReadUInt32();
 0352            }
 353
 354            // loader flags
 0355            reader.ReadUInt32();
 356
 0357            NumberOfRvaAndSizes = reader.ReadInt32();
 358
 359            // directory entries:
 0360            ExportTableDirectory = new DirectoryEntry(ref reader);
 0361            ImportTableDirectory = new DirectoryEntry(ref reader);
 0362            ResourceTableDirectory = new DirectoryEntry(ref reader);
 0363            ExceptionTableDirectory = new DirectoryEntry(ref reader);
 0364            CertificateTableDirectory = new DirectoryEntry(ref reader);
 0365            BaseRelocationTableDirectory = new DirectoryEntry(ref reader);
 0366            DebugTableDirectory = new DirectoryEntry(ref reader);
 0367            CopyrightTableDirectory = new DirectoryEntry(ref reader);
 0368            GlobalPointerTableDirectory = new DirectoryEntry(ref reader);
 0369            ThreadLocalStorageTableDirectory = new DirectoryEntry(ref reader);
 0370            LoadConfigTableDirectory = new DirectoryEntry(ref reader);
 0371            BoundImportTableDirectory = new DirectoryEntry(ref reader);
 0372            ImportAddressTableDirectory = new DirectoryEntry(ref reader);
 0373            DelayImportTableDirectory = new DirectoryEntry(ref reader);
 0374            CorHeaderTableDirectory = new DirectoryEntry(ref reader);
 375
 376            // ReservedDirectory (should be 0, 0)
 0377            new DirectoryEntry(ref reader);
 0378        }
 379    }
 380}
 381