/// <inheritdoc />
        public ISegment ResolveFieldData(IMetadata metadata, FieldRvaRow fieldRvaRow)
        {
            if (fieldRvaRow.Data is null)
            {
                return(null);
            }

            if (fieldRvaRow.Data.IsBounded)
            {
                return(fieldRvaRow.Data.GetSegment());
            }

            if (fieldRvaRow.Data.CanRead)
            {
                var table = metadata
                            .GetStream <TablesStream>()
                            .GetTable <FieldDefinitionRow>(TableIndex.Field);

                if (fieldRvaRow.Field > table.Count)
                {
                    throw new ArgumentException("Invalid Field column value.");
                }

                var field     = table.GetByRid(fieldRvaRow.Field);
                int valueSize = DetermineFieldSize(metadata, field);

                var reader = fieldRvaRow.Data.CreateReader();
                return(DataSegment.FromReader(reader, valueSize));
            }

            throw new NotSupportedException("Invalid or unsupported data column.");
        }
Example #2
0
        /// <inheritdoc />
        protected override IList <PESection> GetSections()
        {
            var result = new PESectionCollection(this);

            for (int i = 0; i < _sectionHeaders.Count; i++)
            {
                var header = _sectionHeaders[i];

                (ulong offset, uint size) = MappingMode switch
                {
                    PEMappingMode.Unmapped => (header.PointerToRawData, header.SizeOfRawData),
                    PEMappingMode.Mapped => (_reader.StartOffset + header.VirtualAddress, header.VirtualSize),
                    _ => throw new ArgumentOutOfRangeException()
                };

                _reader.Offset = offset;

                ISegment physicalContents = null;
                if (size > 0)
                {
                    physicalContents = DataSegment.FromReader(_reader, (int)size);
                }

                var virtualSegment = new VirtualSegment(physicalContents, header.VirtualSize);
                virtualSegment.UpdateOffsets(offset, header.VirtualAddress);
                result.Add(new PESection(header, virtualSegment));
            }

            return(result);
        }
    }
Example #3
0
        /// <inheritdoc />
        public IMetadataStream ReadStream(PEReaderContext context, MetadataStreamHeader header,
                                          ref BinaryStreamReader reader)
        {
            switch (header.Name)
            {
            case TablesStream.CompressedStreamName:
            case TablesStream.EncStreamName:
                return(new SerializedTableStream(context, header.Name, reader));

            case StringsStream.DefaultName:
                return(new SerializedStringsStream(header.Name, reader));

            case UserStringsStream.DefaultName:
                return(new SerializedUserStringsStream(header.Name, reader));

            case BlobStream.DefaultName:
                return(new SerializedBlobStream(header.Name, reader));

            case GuidStream.DefaultName:
                return(new SerializedGuidStream(header.Name, reader));

            default:
                return(new CustomMetadataStream(header.Name, DataSegment.FromReader(ref reader)));
            }
        }
 /// <summary>
 /// Creates a new instance of the <see cref="SerializedDotNetResourcesDirectory"/> using an input stream as
 /// raw contents of the directory.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 public SerializedDotNetResourcesDirectory(IBinaryStreamReader reader)
 {
     if (reader == null)
     {
         throw new ArgumentNullException(nameof(reader));
     }
     _contents = DataSegment.FromReader(reader);
 }
Example #5
0
 /// <inheritdoc />
 public IDebugDataSegment ReadDebugData(PEReaderContext context, DebugDataType type,
                                        IBinaryStreamReader reader)
 {
     return(type switch
     {
         DebugDataType.CodeView => CodeViewDataSegment.FromReader(context, reader),
         _ => new CustomDebugDataSegment(type, DataSegment.FromReader(reader))
     });
        /// <inheritdoc />
        protected override ISegment GetContents()
        {
            if (!_context.File.TryCreateReaderAtRva(_contentsRva, _contentsSize, out var reader))
            {
                _context.BadImage("Resource data entry contains an invalid RVA and/or size.");
                return(null);
            }

            return(DataSegment.FromReader(ref reader));
        }
        /// <inheritdoc />
        protected override ISegment GetEmbeddedDataSegment()
        {
            if (_row.Implementation != 0)
            {
                return(null);
            }

            var reader = _parentModule.DotNetDirectory.DotNetResources.CreateManifestResourceReader(_row.Offset);

            return(reader is null ? null : DataSegment.FromReader(reader));
        }
        /// <inheritdoc />
        protected override IReadableSegment GetCodeManagerTable()
        {
            if (_codeManagerDirectory.IsPresentInPE &&
                _peFile.TryCreateDataDirectoryReader(_codeManagerDirectory, out var directoryReader))
            {
                // TODO: interpretation instead of raw contents.
                return(DataSegment.FromReader(directoryReader));
            }

            return(null);
        }
Example #9
0
        /// <inheritdoc />
        public IDebugDataSegment ReadDebugData(DebugDataType type, uint rva, uint size)
        {
            var reference = _resolver.GetReferenceToRva(rva);

            if (reference is null || !reference.CanRead)
            {
                return(null);
            }

            var reader = reference.CreateReader();

            reader.ChangeSize(size);

            return(new CustomDebugDataSegment(type, DataSegment.FromReader(reader)));
        }
        /// <inheritdoc />
        protected override IReadableSegment GetStrongName()
        {
            if (!_strongNameDirectory.IsPresentInPE)
            {
                return(null);
            }

            if (!_context.File.TryCreateDataDirectoryReader(_strongNameDirectory, out var directoryReader))
            {
                _context.BadImage(".NET data directory contains an invalid strong name directory RVA and/or size.");
                return(null);
            }

            // TODO: interpretation instead of raw contents.
            return(DataSegment.FromReader(ref directoryReader));
        }
Example #11
0
        /// <inheritdoc />
        protected override IReadableSegment GetManagedNativeHeader()
        {
            if (!_nativeHeaderDirectory.IsPresentInPE)
            {
                return(null);
            }

            if (!_context.File.TryCreateDataDirectoryReader(_nativeHeaderDirectory, out var directoryReader))
            {
                _context.BadImage(".NET data directory contains an invalid native header directory RVA and/or size.");
                return(null);
            }

            // TODO: interpretation instead of raw contents.
            return(DataSegment.FromReader(directoryReader));
        }
Example #12
0
        public CopiedProcessModule(Process process, IntPtr baseAddress, int size)
        {
            BaseAddress = baseAddress;
            using (var memoryReader = new MemoryReader(process))
            {
                var copiedBytes = memoryReader.ReadMemory(baseAddress, size, out var bytesRead);
                if (bytesRead != size)
                {
                    throw new AccessViolationException("Could not copy entire module into memory.");
                }
                var reader = new ByteArrayReader(copiedBytes);

                // DOS header.
                var dosHeader = DosHeader.FromReader(reader);
                reader.FileOffset = dosHeader.NextHeaderOffset;

                uint signature = reader.ReadUInt32();
                if (signature != 0x4550) //PE\0\0
                {
                    throw new BadImageFormatException();
                }

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

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

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

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

                Image = PEImage.FromFile(peFile);
            }
        }
Example #13
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);
        }
        /// <inheritdoc />
        public IMetadataStream ReadStream(MetadataStreamHeader header, IBinaryStreamReader reader)
        {
            switch (header.Name)
            {
            case TablesStream.CompressedStreamName:
            case TablesStream.EncStreamName:
                return(new SerializedTableStream(header.Name, DataSegment.FromReader(reader), _referenceResolver));

            case StringsStream.DefaultName:
                return(new SerializedStringsStream(header.Name, DataSegment.FromReader(reader)));

            case UserStringsStream.DefaultName:
                return(new SerializedUserStringsStream(header.Name, DataSegment.FromReader(reader)));

            case BlobStream.DefaultName:
                return(new SerializedBlobStream(header.Name, DataSegment.FromReader(reader)));

            case GuidStream.DefaultName:
                return(new SerializedGuidStream(header.Name, DataSegment.FromReader(reader)));

            default:
                return(new CustomMetadataStream(header.Name, DataSegment.FromReader(reader)));
            }
        }
Example #15
0
        /// <summary>
        /// Reads a PE file from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <param name="mode">Indicates how the input PE file is mapped.</param>
        /// <exception cref="BadImageFormatException">Occurs when the input stream is malformed.</exception>
        public SerializedPEFile(IBinaryStreamReader reader, PEMappingMode mode)
        {
            _reader     = reader ?? throw new ArgumentNullException(nameof(reader));
            MappingMode = mode;

            // DOS header.
            DosHeader     = DosHeader.FromReader(reader);
            reader.Offset = DosHeader.Offset + DosHeader.NextHeaderOffset;

            uint signature = reader.ReadUInt32();

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

            // Read NT headers.
            FileHeader     = FileHeader.FromReader(reader);
            OptionalHeader = OptionalHeader.FromReader(reader);

            // Read section headers.
            reader.Offset   = OptionalHeader.Offset + FileHeader.SizeOfOptionalHeader;
            _sectionHeaders = new List <SectionHeader>(FileHeader.NumberOfSections);
            for (int i = 0; i < FileHeader.NumberOfSections; i++)
            {
                _sectionHeaders.Add(SectionHeader.FromReader(reader));
            }

            // Data between section headers and sections.
            int extraSectionDataLength = (int)(DosHeader.Offset + OptionalHeader.SizeOfHeaders - reader.Offset);

            if (extraSectionDataLength != 0)
            {
                ExtraSectionData = DataSegment.FromReader(reader, extraSectionDataLength);
            }
        }
 /// <inheritdoc />
 protected override ISegment GetContents()
 {
     return(_peFile.TryCreateReaderAtRva(_contentsRva, _contentsSize, out var reader)
         ? DataSegment.FromReader(reader)
         : null);
 }
Example #17
0
 /// <inheritdoc />
 public IDebugDataSegment ReadDebugData(PEReaderContext context, DebugDataType type,
                                        IBinaryStreamReader reader)
 {
     return(new CustomDebugDataSegment(type, DataSegment.FromReader(reader)));
 }