/// <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."); }
/// <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); } }
/// <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); }
/// <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); }
/// <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)); }
/// <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)); }
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); } }
/// <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))); } }
/// <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); }
/// <inheritdoc /> public IDebugDataSegment ReadDebugData(PEReaderContext context, DebugDataType type, IBinaryStreamReader reader) { return(new CustomDebugDataSegment(type, DataSegment.FromReader(reader))); }