private void WriteCoffHeader(BlobBuilder builder, ImmutableArray <SerializedSection> sections, out Blob stampFixup) { // Machine builder.WriteUInt16((ushort)(Header.Machine == 0 ? Machine.I386 : Header.Machine)); // NumberOfSections builder.WriteUInt16((ushort)sections.Length); // TimeDateStamp: stampFixup = builder.ReserveBytes(sizeof(uint)); // PointerToSymbolTable (TODO: not supported): // The file pointer to the COFF symbol table, or zero if no COFF symbol table is present. // This value should be zero for a PE image. builder.WriteUInt32(0); // NumberOfSymbols (TODO: not supported): // The number of entries in the symbol table. This data can be used to locate the string table, // which immediately follows the symbol table. This value should be zero for a PE image. builder.WriteUInt32(0); // SizeOfOptionalHeader: // The size of the optional header, which is required for executable files but not for object files. // This value should be zero for an object file (TODO). builder.WriteUInt16((ushort)PEHeader.Size(Header.Is32Bit)); // Characteristics builder.WriteUInt16((ushort)Header.ImageCharacteristics); }
/// <summary> /// Reads PE headers from the current location in the stream. /// </summary> /// <param name="peStream">Stream containing PE image of the given size starting at its current position.</param> /// <param name="size">Size of the PE image.</param> /// <param name="isLoadedImage">True if the PE image has been loaded into memory by the OS loader.</param> /// <exception cref="BadImageFormatException">The data read from stream have invalid format.</exception> /// <exception cref="IOException">Error reading from the stream.</exception> /// <exception cref="ArgumentException">The stream doesn't support seek operations.</exception> /// <exception cref="ArgumentNullException"><paramref name="peStream"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException">Size is negative or extends past the end of the stream.</exception> public PEHeaders(Stream peStream, int size, bool isLoadedImage) { if (peStream == null) { throw new ArgumentNullException(nameof(peStream)); } if (!peStream.CanRead || !peStream.CanSeek) { throw new ArgumentException(SR.StreamMustSupportReadAndSeek, nameof(peStream)); } _isLoadedImage = isLoadedImage; int actualSize = StreamExtensions.GetAndValidateSize(peStream, size, nameof(peStream)); var reader = new PEBinaryReader(peStream, actualSize); bool isCoffOnly; SkipDosHeader(ref reader, out isCoffOnly); _coffHeaderStartOffset = reader.CurrentOffset; _coffHeader = new CoffHeader(ref reader); if (!isCoffOnly) { _peHeaderStartOffset = reader.CurrentOffset; _peHeader = new PEHeader(ref reader); } _sectionHeaders = this.ReadSectionHeaders(ref reader); if (!isCoffOnly) { int offset; if (TryCalculateCorHeaderOffset(actualSize, out offset)) { _corHeaderStartOffset = offset; reader.Seek(offset); _corHeader = new CorHeader(ref reader); } } CalculateMetadataLocation(actualSize, out _metadataStartOffset, out _metadataSize); }
internal int ComputeSizeOfPEHeaders(int sectionCount) => PEBuilder.DosHeaderSize + PEHeaders.PESignatureSize + CoffHeader.Size + PEHeader.Size(Is32Bit) + SectionHeader.Size * sectionCount;