예제 #1
0
        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);
        }
예제 #2
0
        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);
     }
 }
예제 #4
0
        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);
         }
     }
 }
예제 #6
0
 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));
         }
     }
 }
예제 #7
0
        /// <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.");
            }
        }