internal CoffHeader(ref PEBinaryReader reader) { Machine = (Machine)reader.ReadUInt16(); NumberOfSections = reader.ReadInt16(); TimeDateStamp = reader.ReadInt32(); PointerToSymbolTable = reader.ReadInt32(); NumberOfSymbols = reader.ReadInt32(); SizeOfOptionalHeader = reader.ReadInt16(); Characteristics = (Characteristics)reader.ReadUInt16(); }
internal CoffHeader(ref PEBinaryReader reader) { Machine = (Machine)reader.ReadUInt16(); NumberOfSections = reader.ReadInt16(); TimeDateStamp = reader.ReadInt32(); PointerToSymbolTable = reader.ReadInt32(); NumberOfSymbols = reader.ReadInt32(); SizeOfOptionalHeader = reader.ReadInt16(); Characteristics = (Characteristics)reader.ReadUInt16(); }
public void ReadNullPaddedUTF8WorksWithNoNullPadding() { var headerBytes = Encoding.UTF8.GetBytes(".abcdefg"); var stream = new MemoryStream(headerBytes); stream.Position = 0; var reader = new PEBinaryReader(stream, headerBytes.Length); var text = reader.ReadNullPaddedUTF8(PEFileConstants.SizeofSectionName); AssertEx.AreEqual(".abcdefg", text, "PEBinaryReader.ReadNullPaddedUTF8 erroneously truncated a section name"); }
internal SectionHeader(ref PEBinaryReader reader) { name = reader.ReadUTF8(PEFileConstants.SizeofSectionName); virtualSize = reader.ReadInt32(); virtualAddress = reader.ReadInt32(); sizeOfRawData = reader.ReadInt32(); pointerToRawData = reader.ReadInt32(); pointerToRelocations = reader.ReadInt32(); pointerToLineNumbers = reader.ReadInt32(); numberOfRelocations = reader.ReadUInt16(); numberOfLineNumbers = reader.ReadUInt16(); sectionCharacteristics = (SectionCharacteristics)reader.ReadUInt32(); }
public void ReadNullPaddedUTF8RemovesNullPadding() { var headerBytes = new byte[PEFileConstants.SizeofSectionName]; headerBytes[0] = 80; headerBytes[1] = 80; headerBytes[2] = 80; var stream = new MemoryStream(headerBytes); stream.Position = 0; var reader = new PEBinaryReader(stream, headerBytes.Length); var text = reader.ReadNullPaddedUTF8(PEFileConstants.SizeofSectionName); AssertEx.AreEqual(3, text.Length, "PEBinaryReader.ReadNullPaddedUTF8 did not truncate null padding"); AssertEx.AreEqual("PPP", text); }
internal CorHeader(ref PEBinaryReader reader) { // byte count reader.ReadInt32(); MajorRuntimeVersion = reader.ReadUInt16(); MinorRuntimeVersion = reader.ReadUInt16(); MetadataDirectory = new DirectoryEntry(ref reader); Flags = (CorFlags)reader.ReadUInt32(); EntryPointTokenOrRelativeVirtualAddress = reader.ReadInt32(); ResourcesDirectory = new DirectoryEntry(ref reader); StrongNameSignatureDirectory = new DirectoryEntry(ref reader); CodeManagerTableDirectory = new DirectoryEntry(ref reader); VtableFixupsDirectory = new DirectoryEntry(ref reader); ExportAddressTableJumpsDirectory = new DirectoryEntry(ref reader); ManagedNativeHeaderDirectory = new DirectoryEntry(ref reader); }
internal CorHeader(ref PEBinaryReader reader) { // byte count reader.ReadInt32(); MajorRuntimeVersion = reader.ReadUInt16(); MinorRuntimeVersion = reader.ReadUInt16(); MetadataDirectory = new DirectoryEntry(ref reader); Flags = (CorFlags)reader.ReadUInt32(); EntryPointTokenOrRelativeVirtualAddress = reader.ReadInt32(); ResourcesDirectory = new DirectoryEntry(ref reader); StrongNameSignatureDirectory = new DirectoryEntry(ref reader); CodeManagerTableDirectory = new DirectoryEntry(ref reader); VtableFixupsDirectory = new DirectoryEntry(ref reader); ExportAddressTableJumpsDirectory = new DirectoryEntry(ref reader); ManagedNativeHeaderDirectory = new DirectoryEntry(ref reader); }
/// <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); }
private ImmutableArray <SectionHeader> ReadSectionHeaders(ref PEBinaryReader reader) { int numberOfSections = _coffHeader.NumberOfSections; if (numberOfSections < 0) { throw new BadImageFormatException(SR.InvalidNumberOfSections); } var builder = ImmutableArray.CreateBuilder <SectionHeader>(numberOfSections); for (int i = 0; i < numberOfSections; i++) { builder.Add(new SectionHeader(ref reader)); } return(builder.MoveToImmutable()); }
/// <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); }
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); } } }
private PEHeaders(Stream peStream, int?sizeOpt) { if (peStream == null) { throw new ArgumentNullException("peStream"); } if (!peStream.CanRead || !peStream.CanSeek) { throw new ArgumentException(SR.StreamMustSupportReadAndSeek, "peStream"); } int size = PEBinaryReader.GetAndValidateSize(peStream, sizeOpt); var reader = new PEBinaryReader(peStream, size); 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(size, out offset)) { _corHeaderStartOffset = offset; reader.Seek(offset); _corHeader = new CorHeader(ref reader); } } CalculateMetadataLocation(size, out _metadataStartOffset, out _metadataSize); }
private PEHeaders(Stream peStream, int? sizeOpt) { if (peStream == null) { throw new ArgumentNullException("peStream"); } if (!peStream.CanRead || !peStream.CanSeek) { throw new ArgumentException(SR.StreamMustSupportReadAndSeek, "peStream"); } int size = PEBinaryReader.GetAndValidateSize(peStream, sizeOpt); var reader = new PEBinaryReader(peStream, size); 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(size, out offset)) { _corHeaderStartOffset = offset; reader.Seek(offset); _corHeader = new CorHeader(ref reader); } } CalculateMetadataLocation(size, out _metadataStartOffset, out _metadataSize); }
public void Ctor( string name, int virtualSize, int virtualAddress, int sizeOfRawData, int ptrToRawData, int ptrToRelocations, int ptrToLineNumbers, ushort numRelocations, ushort numLineNumbers, SectionCharacteristics characteristics) { var stream = new MemoryStream(); var writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true); writer.Write(PadSectionName(name)); writer.Write(virtualSize); writer.Write(virtualAddress); writer.Write(sizeOfRawData); writer.Write(ptrToRawData); writer.Write(ptrToRelocations); writer.Write(ptrToLineNumbers); writer.Write(numRelocations); writer.Write(numLineNumbers); writer.Write((uint) characteristics); writer.Dispose(); stream.Position = 0; var reader = new PEBinaryReader(stream, (int) stream.Length); var header = new SectionHeader(ref reader); Assert.Equal(name, header.Name); Assert.Equal(virtualSize, header.VirtualSize); Assert.Equal(virtualAddress, header.VirtualAddress); Assert.Equal(sizeOfRawData, header.SizeOfRawData); Assert.Equal(ptrToRawData, header.PointerToRawData); Assert.Equal(ptrToLineNumbers, header.PointerToLineNumbers); Assert.Equal(numRelocations, header.NumberOfRelocations); Assert.Equal(numLineNumbers, header.NumberOfLineNumbers); Assert.Equal(characteristics, header.SectionCharacteristics); }
private unsafe PEReader(Stream peStream, PEStreamOptions options, int?sizeOpt) { if (peStream == null) { throw new ArgumentNullException(nameof(peStream)); } if (!peStream.CanRead || !peStream.CanSeek) { throw new ArgumentException(SR.StreamMustSupportReadAndSeek, nameof(peStream)); } if (!options.IsValid()) { throw new ArgumentOutOfRangeException(nameof(options)); } long start = peStream.Position; int size = PEBinaryReader.GetAndValidateSize(peStream, sizeOpt); bool closeStream = true; try { bool isFileStream = FileStreamReadLightUp.IsFileStream(peStream); if ((options & (PEStreamOptions.PrefetchMetadata | PEStreamOptions.PrefetchEntireImage)) == 0) { _peImage = new StreamMemoryBlockProvider(peStream, start, size, isFileStream, (options & PEStreamOptions.LeaveOpen) != 0); closeStream = false; } else { // Read in the entire image or metadata blob: if ((options & PEStreamOptions.PrefetchEntireImage) != 0) { var imageBlock = StreamMemoryBlockProvider.ReadMemoryBlockNoLock(peStream, isFileStream, 0, (int)Math.Min(peStream.Length, int.MaxValue)); _lazyImageBlock = imageBlock; _peImage = new ExternalMemoryBlockProvider(imageBlock.Pointer, imageBlock.Size); // if the caller asked for metadata initialize the PE headers (calculates metadata offset): if ((options & PEStreamOptions.PrefetchMetadata) != 0) { InitializePEHeaders(); } } else { // The peImage is left null, but the lazyMetadataBlock is initialized up front. _lazyPEHeaders = new PEHeaders(peStream); _lazyMetadataBlock = StreamMemoryBlockProvider.ReadMemoryBlockNoLock(peStream, isFileStream, _lazyPEHeaders.MetadataStartOffset, _lazyPEHeaders.MetadataSize); } // We read all we need, the stream is going to be closed. } } finally { if (closeStream && (options & PEStreamOptions.LeaveOpen) == 0) { peStream.Dispose(); } } }
internal DirectoryEntry(ref PEBinaryReader reader) { RelativeVirtualAddress = reader.ReadInt32(); Size = reader.ReadInt32(); }
internal PEHeader(ref PEBinaryReader reader) { PEMagic magic = (PEMagic)reader.ReadUInt16(); if (magic != PEMagic.PE32 && magic != PEMagic.PE32Plus) { throw new BadImageFormatException(SR.UnknownPEMagicValue); } Magic = magic; MajorLinkerVersion = reader.ReadByte(); MinorLinkerVersion = reader.ReadByte(); SizeOfCode = reader.ReadInt32(); SizeOfInitializedData = reader.ReadInt32(); SizeOfUninitializedData = reader.ReadInt32(); AddressOfEntryPoint = reader.ReadInt32(); BaseOfCode = reader.ReadInt32(); if (magic == PEMagic.PE32Plus) { BaseOfData = 0; // not present } else { Debug.Assert(magic == PEMagic.PE32); BaseOfData = reader.ReadInt32(); } if (magic == PEMagic.PE32Plus) { ImageBase = reader.ReadUInt64(); } else { ImageBase = reader.ReadUInt32(); } // NT additional fields: SectionAlignment = reader.ReadInt32(); FileAlignment = reader.ReadInt32(); MajorOperatingSystemVersion = reader.ReadUInt16(); MinorOperatingSystemVersion = reader.ReadUInt16(); MajorImageVersion = reader.ReadUInt16(); MinorImageVersion = reader.ReadUInt16(); MajorSubsystemVersion = reader.ReadUInt16(); MinorSubsystemVersion = reader.ReadUInt16(); // Win32VersionValue (reserved, should be 0) reader.ReadUInt32(); SizeOfImage = reader.ReadInt32(); SizeOfHeaders = reader.ReadInt32(); CheckSum = reader.ReadUInt32(); Subsystem = (Subsystem)reader.ReadUInt16(); DllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); if (magic == PEMagic.PE32Plus) { SizeOfStackReserve = reader.ReadUInt64(); SizeOfStackCommit = reader.ReadUInt64(); SizeOfHeapReserve = reader.ReadUInt64(); SizeOfHeapCommit = reader.ReadUInt64(); } else { SizeOfStackReserve = reader.ReadUInt32(); SizeOfStackCommit = reader.ReadUInt32(); SizeOfHeapReserve = reader.ReadUInt32(); SizeOfHeapCommit = reader.ReadUInt32(); } // loader flags reader.ReadUInt32(); NumberOfRvaAndSizes = reader.ReadInt32(); // directory entries: ExportTableDirectory = new DirectoryEntry(ref reader); ImportTableDirectory = new DirectoryEntry(ref reader); ResourceTableDirectory = new DirectoryEntry(ref reader); ExceptionTableDirectory = new DirectoryEntry(ref reader); CertificateTableDirectory = new DirectoryEntry(ref reader); BaseRelocationTableDirectory = new DirectoryEntry(ref reader); DebugTableDirectory = new DirectoryEntry(ref reader); CopyrightTableDirectory = new DirectoryEntry(ref reader); GlobalPointerTableDirectory = new DirectoryEntry(ref reader); ThreadLocalStorageTableDirectory = new DirectoryEntry(ref reader); LoadConfigTableDirectory = new DirectoryEntry(ref reader); BoundImportTableDirectory = new DirectoryEntry(ref reader); ImportAddressTableDirectory = new DirectoryEntry(ref reader); DelayImportTableDirectory = new DirectoryEntry(ref reader); CorHeaderTableDirectory = new DirectoryEntry(ref reader); // ReservedDirectory (should be 0, 0) new DirectoryEntry(ref reader); }
private ImmutableArray<SectionHeader> ReadSectionHeaders(ref PEBinaryReader reader) { int numberOfSections = _coffHeader.NumberOfSections; if (numberOfSections < 0) { throw new BadImageFormatException(SR.InvalidNumberOfSections); } var builder = ImmutableArray.CreateBuilder<SectionHeader>(numberOfSections); for (int i = 0; i < numberOfSections; i++) { builder.Add(new SectionHeader(ref reader)); } return builder.ToImmutable(); }
private void SkipDosHeader(ref PEBinaryReader reader, out bool isCOFFOnly) { // Look for DOS Signature "MZ" ushort dosSig = reader.ReadUInt16(); if (dosSig != PEFileConstants.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(PEFileConstants.PESignatureOffsetLocation); int ntHeaderOffset = reader.ReadInt32(); reader.Seek(ntHeaderOffset); // Look for PESignature "PE\0\0" uint ntSignature = reader.ReadUInt32(); if (ntSignature != PEFileConstants.PESignature) { throw new BadImageFormatException(SR.InvalidPESignature); } } }
16 * sizeof(long); // directory entries internal PEHeader(ref PEBinaryReader reader) { PEMagic magic = (PEMagic)reader.ReadUInt16(); if (magic != PEMagic.PE32 && magic != PEMagic.PE32Plus) { throw new BadImageFormatException("UnknownPEMagicValue"); } Magic = magic; MajorLinkerVersion = reader.ReadByte(); MinorLinkerVersion = reader.ReadByte(); SizeOfCode = reader.ReadInt32(); SizeOfInitializedData = reader.ReadInt32(); SizeOfUninitializedData = reader.ReadInt32(); AddressOfEntryPoint = reader.ReadInt32(); BaseOfCode = reader.ReadInt32(); if (magic == PEMagic.PE32Plus) { BaseOfData = 0; // not present } else { Debug.Assert(magic == PEMagic.PE32); BaseOfData = reader.ReadInt32(); } if (magic == PEMagic.PE32Plus) { ImageBase = reader.ReadUInt64(); } else { ImageBase = reader.ReadUInt32(); } // NT additional fields: SectionAlignment = reader.ReadInt32(); FileAlignment = reader.ReadInt32(); MajorOperatingSystemVersion = reader.ReadUInt16(); MinorOperatingSystemVersion = reader.ReadUInt16(); MajorImageVersion = reader.ReadUInt16(); MinorImageVersion = reader.ReadUInt16(); MajorSubsystemVersion = reader.ReadUInt16(); MinorSubsystemVersion = reader.ReadUInt16(); // Win32VersionValue (reserved, should be 0) reader.ReadUInt32(); SizeOfImage = reader.ReadInt32(); SizeOfHeaders = reader.ReadInt32(); CheckSum = reader.ReadUInt32(); Subsystem = (Subsystem)reader.ReadUInt16(); DllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); if (magic == PEMagic.PE32Plus) { SizeOfStackReserve = reader.ReadUInt64(); SizeOfStackCommit = reader.ReadUInt64(); SizeOfHeapReserve = reader.ReadUInt64(); SizeOfHeapCommit = reader.ReadUInt64(); } else { SizeOfStackReserve = reader.ReadUInt32(); SizeOfStackCommit = reader.ReadUInt32(); SizeOfHeapReserve = reader.ReadUInt32(); SizeOfHeapCommit = reader.ReadUInt32(); } // loader flags reader.ReadUInt32(); NumberOfRvaAndSizes = reader.ReadInt32(); // directory entries: ExportTableDirectory = new DirectoryEntry(ref reader); ImportTableDirectory = new DirectoryEntry(ref reader); ResourceTableDirectory = new DirectoryEntry(ref reader); ExceptionTableDirectory = new DirectoryEntry(ref reader); CertificateTableDirectory = new DirectoryEntry(ref reader); BaseRelocationTableDirectory = new DirectoryEntry(ref reader); DebugTableDirectory = new DirectoryEntry(ref reader); CopyrightTableDirectory = new DirectoryEntry(ref reader); GlobalPointerTableDirectory = new DirectoryEntry(ref reader); ThreadLocalStorageTableDirectory = new DirectoryEntry(ref reader); LoadConfigTableDirectory = new DirectoryEntry(ref reader); BoundImportTableDirectory = new DirectoryEntry(ref reader); ImportAddressTableDirectory = new DirectoryEntry(ref reader); DelayImportTableDirectory = new DirectoryEntry(ref reader); CorHeaderTableDirectory = new DirectoryEntry(ref reader); // ReservedDirectory (should be 0, 0) new DirectoryEntry(ref reader); }
internal SectionHeader(ref PEBinaryReader reader) { name = reader.ReadUTF8(PEFileConstants.SizeofSectionName); virtualSize = reader.ReadInt32(); virtualAddress = reader.ReadInt32(); sizeOfRawData = reader.ReadInt32(); pointerToRawData = reader.ReadInt32(); pointerToRelocations = reader.ReadInt32(); pointerToLineNumbers = reader.ReadInt32(); numberOfRelocations = reader.ReadUInt16(); numberOfLineNumbers = reader.ReadUInt16(); sectionCharacteristics = (SectionCharacteristics)reader.ReadUInt32(); }