示例#1
0
        /// <summary>
        /// Reads a metadata directory from an input stream.
        /// </summary>
        /// <param name="context">The reader context.</param>
        /// <param name="directoryReader">The input stream containing the metadata directory.</param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception>
        /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception>
        public SerializedMetadata(PEReaderContext context, IBinaryStreamReader directoryReader)
        {
            if (directoryReader == null)
            {
                throw new ArgumentNullException(nameof(directoryReader));
            }
            _context = context ?? throw new ArgumentNullException(nameof(context));

            _streamContentsReader = directoryReader.Fork();

            var signature = (MetadataSignature)directoryReader.ReadUInt32();

            switch (signature)
            {
            case MetadataSignature.Bsjb:
                // BSJB header is the default header.
                break;

            case MetadataSignature.Moc:
                _context.NotSupported("Old +MOC metadata header format is not supported.");
                return;

            default:
                _context.BadImage($"Invalid metadata header ({(uint) signature:X8}).");
                return;
            }

            MajorVersion = directoryReader.ReadUInt16();
            MinorVersion = directoryReader.ReadUInt16();
            Reserved     = directoryReader.ReadUInt32();

            int versionLength = directoryReader.ReadInt32();

            if (!directoryReader.CanRead(versionLength))
            {
                _context.BadImage($"Invalid version length in metadata header ({versionLength.ToString()} characters).");
                return;
            }

            var versionBytes = new byte[versionLength];

            directoryReader.ReadBytes(versionBytes, 0, versionBytes.Length);
            VersionString = Encoding.ASCII.GetString(versionBytes);

            Flags                = directoryReader.ReadUInt16();
            _numberOfStreams     = directoryReader.ReadInt16();
            _streamEntriesReader = directoryReader.Fork();
        }
示例#2
0
        /// <summary>
        /// Reads a metadata directory from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <param name="metadataStreamReader"></param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception>
        /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception>
        public SerializedMetadata(IBinaryStreamReader reader, IMetadataStreamReader metadataStreamReader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _metadataStreamReader = metadataStreamReader;

            _streamContentsReader = reader.Fork();

            var signature = (MetadataSignature)reader.ReadUInt32();

            switch (signature)
            {
            case MetadataSignature.Bsjb:
                // BSJB header is the default header.
                break;

            case MetadataSignature.Moc:
                throw new NotSupportedException("Old +MOC metadata header format is not supported.");

            default:
                throw new BadImageFormatException($"Invalid metadata header ({(uint) signature:X8}).");
            }

            MajorVersion = reader.ReadUInt16();
            MinorVersion = reader.ReadUInt16();
            Reserved     = reader.ReadUInt32();

            int versionLength = reader.ReadInt32();

            if (!reader.CanRead(versionLength))
            {
                throw new BadImageFormatException($"Invalid version length in metadata header ({versionLength} characters).");
            }

            var versionBytes = new byte[versionLength];

            reader.ReadBytes(versionBytes, 0, versionBytes.Length);
            VersionString = Encoding.ASCII.GetString(versionBytes);

            Flags                = reader.ReadUInt16();
            _numberOfStreams     = reader.ReadInt16();
            _streamEntriesReader = reader.Fork();
        }
        /// <inheritdoc />
        protected override IList <X64RuntimeFunction> GetEntries()
        {
            var reader = _reader.Fork();
            var result = new List <X64RuntimeFunction>();

            while (reader.CanRead(X64RuntimeFunction.EntrySize))
            {
                result.Add(X64RuntimeFunction.FromReader(_context, reader));
            }

            return(result);
        }
示例#4
0
        /// <inheritdoc />
        protected override IList <IMetadataStream> GetStreams()
        {
            if (_numberOfStreams == 0)
            {
                return(base.GetStreams());
            }

            return(new MetadataStreamList(
                       _streamContentsReader.Fork(),
                       _streamEntriesReader.Fork(),
                       _numberOfStreams,
                       _metadataStreamReader));
        }
        /// <inheritdoc />
        protected override IList <TRow> GetRows()
        {
            var result = new List <TRow>();

            var reader = _reader.Fork();

            for (int i = 0; i < _rowCount; i++)
            {
                result.Add(_readRow(reader, _originalLayout));
            }

            return(result);
        }
示例#6
0
        /// <inheritdoc />
        protected override void Initialize()
        {
            var headers = new MetadataStreamHeader[_numberOfStreams];

            for (int i = 0; i < _numberOfStreams; i++)
            {
                headers[i] = MetadataStreamHeader.FromReader(_entriesReader);
            }

            for (int i = 0; i < _numberOfStreams; i++)
            {
                var header       = headers[i];
                var streamReader = _metadataReader.Fork(_metadataReader.FileOffset + header.Offset, headers[i].Size);
                Items.Add(_metadataStreamReader.ReadStream(header, streamReader));
            }
        }
示例#7
0
        /// <summary>
        /// Reads a PE file from the provided input stream.
        /// </summary>
        /// <param name="reader">The input stream to read from.</param>
        /// <returns>The PE file that was read.</returns>
        /// <exception cref="BadImageFormatException">Occurs when the file does not follow the PE file format.</exception>
        public static PEFile FromReader(IBinaryStreamReader reader)
        {
            // DOS header.
            var dosHeader = DosHeader.FromReader(reader);

            reader.FileOffset = dosHeader.NextHeaderOffset;

            uint signature = reader.ReadUInt32();

            if (signature != ValidPESignature)
            {
                throw new BadImageFormatException();
            }

            // Read NT headers.
            var peFile = new PEFile(
                dosHeader,
                FileHeader.FromReader(reader),
                OptionalHeader.FromReader(reader));

            // Section headers.
            reader.FileOffset = peFile.OptionalHeader.FileOffset + peFile.FileHeader.SizeOfOptionalHeader;
            for (int i = 0; i < peFile.FileHeader.NumberOfSections; i++)
            {
                var header = SectionHeader.FromReader(reader);

                var contentsReader = reader.Fork(header.PointerToRawData, header.SizeOfRawData);
                var contents       = DataSegment.FromReader(contentsReader);
                contents.UpdateOffsets(header.PointerToRawData, header.VirtualAddress);

                peFile.Sections.Add(new PESection(header, new VirtualSegment(contents, header.VirtualSize)));
            }

            // Data between section headers and sections.
            int extraSectionDataLength = (int)(peFile.OptionalHeader.SizeOfHeaders - reader.FileOffset);

            if (extraSectionDataLength != 0)
            {
                peFile.ExtraSectionData = DataSegment.FromReader(reader, extraSectionDataLength);
            }

            return(peFile);
        }
 /// <summary>
 /// Forks the reader by creating a new instance of a binary stream reader, using the same data source, but a different address.
 /// </summary>
 /// <param name="reader">The reader to fork.</param>
 /// <param name="address">The address of the forked reader to start at.</param>
 /// <returns>A forked binary stream reader with the same data source, but a different address.</returns>
 public static IBinaryStreamReader Fork(this IBinaryStreamReader reader, uint address)
 {
     return(reader.Fork(address, reader.Length - (address - reader.StartPosition)));
 }
        /// <summary>
        /// Forks the reader at th current position by creating a new instance of a binary stream reader, using the same data source.
        /// </summary>
        /// <param name="reader">The reader to fork.</param>
        /// <returns>A forked binary stream reader with the same data source.</returns>
        public static IBinaryStreamReader Fork(this IBinaryStreamReader reader)
        {
            uint address = reader.FileOffset;

            return(reader.Fork(address, reader.Length - (address - reader.StartPosition)));
        }
示例#10
0
 /// <summary>
 /// Forks the reader by creating a new instance of a binary stream reader, using the same data source, but a different address.
 /// </summary>
 /// <param name="reader">The reader to fork.</param>
 /// <param name="address">The address of the forked reader to start at.</param>
 /// <returns>A forked binary stream reader with the same data source, but a different address.</returns>
 public static IBinaryStreamReader Fork(this IBinaryStreamReader reader, ulong address)
 {
     return(reader.Fork(address, (uint)(reader.Length - (address - reader.StartOffset))));
 }
示例#11
0
 /// <summary>
 /// Forks the reader at th current position by creating a new instance of a binary stream reader, using the same data source.
 /// </summary>
 /// <param name="reader">The reader to fork.</param>
 /// <returns>A forked binary stream reader with the same data source.</returns>
 public static IBinaryStreamReader Fork(this IBinaryStreamReader reader)
 {
     return(reader.Fork(reader.Offset, (uint)(reader.Length - reader.RelativeOffset)));
 }