Beispiel #1
0
        private void SkipDosHeader(ref PEBinaryReader reader, out bool isCOFFOnly)
        {
            // Look for DOS Signature "MZ"
            ushort dosSig = reader.ReadUInt16();

            if (dosSig != DosSignature)
            {
                // If image doesn't start with DOS signature, let's assume it is a 
                // COFF (Common Object File Format), aka .OBJ file. 
                // See CLiteWeightStgdbRW::FindObjMetaData in ndp\clr\src\MD\enc\peparse.cpp

                if (dosSig != 0 || reader.ReadUInt16() != 0xffff)
                {
                    isCOFFOnly = true;
                    reader.Seek(0);
                }
                else
                {
                    // Might need to handle other formats. Anonymous or LTCG objects, for example.
                    throw new BadImageFormatException(SR.UnknownFileFormat);
                }
            }
            else
            {
                isCOFFOnly = false;
            }

            if (!isCOFFOnly)
            {
                // Skip the DOS Header
                reader.Seek(PESignatureOffsetLocation);

                int ntHeaderOffset = reader.ReadInt32();
                reader.Seek(ntHeaderOffset);

                // Look for PESignature "PE\0\0"
                uint ntSignature = reader.ReadUInt32();
                if (ntSignature != PESignature)
                {
                    throw new BadImageFormatException(SR.InvalidPESignature);
                }
            }
        }
Beispiel #2
0
        /// <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);
        }