private static void ReadSectionData(EndianAwareBinaryReader reader, PEImageSection result) { long oldLocation = reader.BaseStream.Position; reader.BaseStream.Seek(result.pointerToRawData, SeekOrigin.Begin); int dataLength; byte[] data; if (result.VirtualSize != 0) { if (result.VirtualSize > result.sizeOfRawData) { data = new byte[result.virtualSize]; reader.Read(data, 0, (int)result.sizeOfRawData); } else { dataLength = (int)result.virtualSize; data = new byte[dataLength]; reader.Read(data, 0, dataLength); } } else { data = new byte[result.sizeOfRawData]; reader.Read(data, 0, data.Length); } reader.BaseStream.Seek(oldLocation, SeekOrigin.Begin); result.sectionData = new MemoryStream(data, 0, data.Length, false, true); }
private void Read(EndianAwareBinaryReader reader, bool keepImageOpen) { this.reader = reader; this.dosHeader.Read(reader); if ((dosHeader.PEHeaderPointer - reader.BaseStream.Position) < 0) { throw new BadImageFormatException(); } byte[] dosStub = new byte[msDosStubProgram.Length]; reader.Read(dosStub, 0, dosStub.Length); /* * * ToDo: Handle alternate stub programs that are valid. * */ if (!msDosStubProgram.SequenceEqual(dosStub)) { throw new BadImageFormatException(); } reader.BaseStream.Seek(dosHeader.PEHeaderPointer, SeekOrigin.Begin); coffHeader.Read(reader); extendedHeader.Read(reader); CoffSection[] sections = new CoffSection[this.coffHeader.SectionCount]; for (int i = 0; i < sections.Length; i++) { sections[i] = CoffSection.Read(reader, keepImageOpen); } this.sections = new ControlledCollection <CoffSection>(sections); this.keepImageOpen = keepImageOpen; }
private byte[] LoadBlobDataGeneral(uint index, _ICliMetadataBlobEntry result) { if (result.BlobData == null) { this.reader.BaseStream.Seek(index + result.LengthByteCount, SeekOrigin.Begin); byte[] resultBlob = new byte[result.Length]; reader.Read(resultBlob, 0, result.Length); result.BlobData = resultBlob; return(resultBlob); } else { return(result.BlobData); } }
internal static CoffSection Read(EndianAwareBinaryReader reader, bool keepImageOpen) { byte[] name = new byte[sizeOfName]; reader.Read(name, 0, sizeOfName); var actualName = GetNameFor(name); CoffSection result; switch (actualName) { case ".reloc": result = new CoffRelocSection(); break; default: result = new CoffSection(); break; } result.name = name; result._name = actualName; result.virtualSize = reader.ReadUInt32(); result.virtualAddress = reader.ReadUInt32(); result.sizeOfRawData = reader.ReadUInt32(); result.pointerToRawData = reader.ReadUInt32(); result.pointerToRelocations = reader.ReadUInt32(); result.pointerToLineNumbers = reader.ReadUInt32(); result.numberOfRelocations = reader.ReadUInt16(); result.numberOfLineNumbers = reader.ReadUInt16(); result.characteristics = (CoffSectionCharacteristics)reader.ReadUInt32(); result.sectionData = new Substream(reader.BaseStream, result.pointerToRawData, result.virtualSize); result.keepImageOpen = keepImageOpen; if (result.HasCustomRead) { using (var subReader = new EndianAwareBinaryReader(result.sectionData, reader.TargetEndianess, reader.BitEndianness, true)) result.CustomRead(subReader); } //if (bufferSectionData) //{ // if (!reader.BaseStream.CanSeek) // throw new InvalidOperationException(); // ReadSectionData(reader, result); //} //else // result.sectionDataReader = reader; return(result); }
internal void Read(EndianAwareBinaryReader reader) { this.syncObject = this.metadataRoot.SourceImage.SyncObject; lock (this.syncObject) { byte[] blobSectionData = new byte[this.Size]; reader.Read(blobSectionData, 0, blobSectionData.Length); MemoryStream blobStream = new MemoryStream(blobSectionData); this.reader = new EndianAwareBinaryReader(blobStream, Endianness.LittleEndian, false); this.blobStream = blobStream; //this.reader = new EndianAwareBinaryReader(reader.BaseStream, Endianness.LittleEndian, false); byte firstNull = (byte)(this.reader.PeekByte() & 0xFF); if (firstNull != 0) { throw new BadImageFormatException(string.Format("The first item of a {0} heap must be null.", this.Name)); } this.smallEntries.Add(0, new SmallBlobEntry(1) { BlobData = new byte[this.reader.ReadByte()] }); byte currentItemLengthWidth; long currentPosition = 1; while (currentPosition < this.Size) { int currentLength = CliMetadataFixedRoot.ReadCompressedUnsignedInt(this.reader, out currentItemLengthWidth); if (currentItemLengthWidth == 1) { this.smallEntries.Add((uint)currentPosition, new SmallBlobEntry((sbyte)currentLength)); } else if (currentItemLengthWidth == 2) { this.mediumEntries.Add((uint)currentPosition, new MediumBlobEntry((short)currentLength)); } else { this.largEntries.Add((uint)currentPosition, new LargeBlobEntry(currentLength)); } if (currentPosition + currentItemLengthWidth + currentLength > this.Size) { break; } currentPosition += currentItemLengthWidth + currentLength; this.reader.BaseStream.Seek(currentLength, SeekOrigin.Current); } } }
internal void Read(EndianAwareBinaryReader reader) { lock (syncObject) { if ((base.Size & 0xF) != 0) { throw new BadImageFormatException("GUIDs are 16 bytes long, heap size not properly aligned."); } int sizeShift = (int)base.Size >> 4; for (int i = 0; i < sizeShift; i++) { byte[] current = new byte[16]; reader.Read(current, 0, current.Length); this.Add(new Guid(current)); } } }
/// <summary> /// Reads the root structure from the metadata. /// </summary> /// <param name="header">The <see cref="CliHeader"/> which denotes the location of the information.</param> /// <param name="originalStream">The <see cref="FileStream"/> being read from.</param> /// <param name="reader">The <see cref="EndianAwareBinaryReader"/> which handles reads.</param> /// <param name="relativeVirtualAddress">The <see cref="UInt32"/> value which denotes the relative /// virtual address of the metadata header.</param> /// <param name="sourceImage"></param> internal void Read(CliHeader header, FileStream originalStream, EndianAwareBinaryReader reader, uint relativeVirtualAddress, PEImage sourceImage) { this.originalStream = originalStream; this.header = header; this.streamPosition = relativeVirtualAddress; this.signature = reader.ReadUInt32(); if (this.signature != metadataSignature) { throw new BadImageFormatException(); } this.depreciatedVersion.Read(reader); this.reserved = reader.ReadUInt32(); this.realVersionLength = reader.ReadInt32(); byte[] version = new byte[(this.realVersionLength + 3) & ~3];//Make it a multiple of four. reader.Read(version, 0, version.Length); this.version = version; this.reservedFlags = reader.ReadUInt16(); int streamCount = 0; streamCount = reader.ReadUInt16(); this.sourceImage = sourceImage; for (int i = 0; i < streamCount; i++) { var currentHeader = new CliMetadataStreamHeader(); currentHeader.Read(reader, sourceImage); switch (currentHeader.Name) { case "#Strings": if (this.strings != null) { goto sectionExists; } this.strings = new CliMetadataStringsHeaderAndHeap(currentHeader, sourceImage.SyncObject); this.ScanAndReadSection(sourceImage, strings, this.strings.Read); break; case "#Blob": if (this.blob != null) { goto sectionExists; } this.blob = new CliMetadataBlobHeaderAndHeap(currentHeader, this); this.ScanAndReadSection(sourceImage, blob, this.blob.Read); break; case "#US": if (this.userStrings != null) { goto sectionExists; } this.userStrings = new CliMetadataUserStringsHeaderAndHeap(currentHeader, sourceImage.SyncObject); this.ScanAndReadSection(sourceImage, this.userStrings, this.userStrings.Read); break; case "#GUID": if (this.guids != null) { goto sectionExists; } this.guids = new CliMetadataGuidHeaderAndHeap(currentHeader, sourceImage.SyncObject); this.ScanAndReadSection(sourceImage, guids, this.guids.Read); break; case "#-": //https://github.com/jbevain/cecil/blob/8b689ecdc890cbf3715ba8775de1d713d71f09f3/Mono.Cecil.PE/ImageReader.cs#L359 case "#~": if (this.tableStream != null) { goto sectionExists; } this.tableStream = new CliMetadataTableStreamAndHeader(currentHeader); this.ScanAndReadSection(sourceImage, tableStream, sdReader => this.tableStream.Read(sdReader, this)); break; } continue; sectionExists: throw new BadImageFormatException(string.Format("Duplicate {0} section encountered.", currentHeader.Name)); } if (this.tableStream == null) { throw new BadImageFormatException("#~ or #- stream not present in image."); } }