Ejemplo n.º 1
0
        private void ProcessAndCacheStreams(MemoryBlock metadataRoot) {
            _metadataStreamKind = MetadataStreamKind.Illegal;

            foreach (StreamHeader streamHeader in _streamHeaders) {
                if ((long)streamHeader.Offset + streamHeader.Size > metadataRoot.Length) {
                    throw new BadImageFormatException();
                }
                MemoryBlock block = metadataRoot.GetRange((int)streamHeader.Offset, (int)streamHeader.Size);

                switch (streamHeader.Name) {
                    case COR20Constants.StringStreamName:
                        if (_stringStream != null) {
                            throw new BadImageFormatException();
                        }
                        // the first and the last byte of the heap must be zero:
                        if (block.Length == 0 || block.ReadByte(0) != 0 || block.ReadByte(block.Length - 1) != 0) {
                            throw new BadImageFormatException();
                        }
                        _stringStream = block;
                        break;

                    case COR20Constants.BlobStreamName:
                        if (_blobStream != null) {
                            throw new BadImageFormatException();
                        }
                        _blobStream = block;
                        break;

                    case COR20Constants.GUIDStreamName:
                        if (_guidStream != null) {
                            throw new BadImageFormatException();
                        }
                        _guidStream = block;
                        break;

                    case COR20Constants.UserStringStreamName:
                        if (_userStringStream != null) {
                            throw new BadImageFormatException();
                        }
                        _userStringStream = block;
                        break;

                    case COR20Constants.CompressedMetadataTableStreamName:
                        if (_metadataStreamKind != MetadataStreamKind.Illegal) {
                            throw new BadImageFormatException();
                        }
                        _metadataStreamKind = MetadataStreamKind.Compressed;
                        _metadataTableStream = block;
                        break;

                    case COR20Constants.UncompressedMetadataTableStreamName:
                        if (_metadataStreamKind != MetadataStreamKind.Illegal) {
                            throw new BadImageFormatException();
                        }
                        _metadataStreamKind = MetadataStreamKind.UnCompressed;
                        _metadataTableStream = block;
                        break;

                    default:
		                throw new BadImageFormatException();
                }
            }

            // mandatory streams:
            if (_stringStream == null || _guidStream == null || _metadataStreamKind == MetadataStreamKind.Illegal) {
                throw new BadImageFormatException();
            }
        }
Ejemplo n.º 2
0
        private void InitializeStreamReaders(ref MemoryBlock metadataRoot, StreamHeader[] streamHeaders, out MemoryBlock metadataTableStream)
        {
            metadataTableStream = default(MemoryBlock);

            foreach (StreamHeader streamHeader in streamHeaders)
            {
                switch (streamHeader.Name)
                {
                    case COR20Constants.StringStreamName:
                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                        {
                            throw new BadImageFormatException(MetadataResources.NotEnoughSpaceForStringStream);
                        }

                        this.StringStream = new StringStreamReader(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size), this.metadataKind);
                        break;

                    case COR20Constants.BlobStreamName:
                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                        {
                            throw new BadImageFormatException(MetadataResources.NotEnoughSpaceForBlobStream);
                        }

                        this.BlobStream = new BlobStreamReader(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size), this.metadataKind);
                        break;

                    case COR20Constants.GUIDStreamName:
                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                        {
                            throw new BadImageFormatException(MetadataResources.NotEnoughSpaceForGUIDStream);
                        }

                        this.GuidStream = new GuidStreamReader(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size));
                        break;

                    case COR20Constants.UserStringStreamName:
                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                        {
                            throw new BadImageFormatException(MetadataResources.NotEnoughSpaceForBlobStream);
                        }

                        this.UserStringStream = new UserStringStreamReader(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size));
                        break;

                    case COR20Constants.CompressedMetadataTableStreamName:
                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                        {
                            throw new BadImageFormatException(MetadataResources.NotEnoughSpaceForMetadataStream);
                        }

                        this.metadataStreamKind = MetadataStreamKind.Compressed;
                        metadataTableStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size);
                        break;

                    case COR20Constants.UncompressedMetadataTableStreamName:
                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                        {
                            throw new BadImageFormatException(MetadataResources.NotEnoughSpaceForMetadataStream);
                        }

                        this.metadataStreamKind = MetadataStreamKind.Uncompressed;
                        metadataTableStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size);
                        break;

                    case COR20Constants.MinimalDeltaMetadataTableStreamName:
                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                        {
                            throw new BadImageFormatException(MetadataResources.NotEnoughSpaceForMetadataStream);
                        }

                        // the content of the stream is ignored
                        this.IsMinimalDelta = true;
                        break;

                    default:
                        // Skip unknown streams. Some obfuscators insert invalid streams.
                        continue;
                }
            }

            if (IsMinimalDelta && metadataStreamKind != MetadataStreamKind.Uncompressed)
            {
                throw new BadImageFormatException(MetadataResources.InvalidMetadataStreamFormat);
            }
        }
Ejemplo n.º 3
0
        internal EnCLogTableReader(
            int numberOfRows,
            MemoryBlock containingBlock,
            int containingBlockOffset,
            MetadataStreamKind metadataStreamKind)
        {
            // EnC tables are not allowed in a compressed stream.
            // However when asked for a snapshot of the current metadata after an EnC change has been applied 
            // the CLR includes the EnCLog table into the snapshot (but not EnCMap). We pretend EnCLog is empty.
            this.NumberOfRows = (metadataStreamKind == MetadataStreamKind.Compressed) ? 0 : numberOfRows;

            _TokenOffset = 0;
            _FuncCodeOffset = _TokenOffset + sizeof(uint);
            this.RowSize = _FuncCodeOffset + sizeof(uint);
            this.Block = containingBlock.GetMemoryBlockAt(containingBlockOffset, (int)(this.RowSize * numberOfRows));
        }
 bool ProcessAndCacheStreams(
   ref MemoryBlock metadataRoot
 )
   //^ requires this.ReaderState >= ReaderState.PEFile;
 {
   foreach (StreamHeader streamHeader in this.StreamHeaders) {
     switch (streamHeader.Name) {
       case COR20Constants.StringStreamName:
         if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size) {
           this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, streamHeader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForStringStream);
           return false;
         }
         this.StringStream.MemoryReader =
           new MemoryReader(
             metadataRoot.Buffer + streamHeader.Offset,
             streamHeader.Size
           );
         break;
       case COR20Constants.BlobStreamName:
         if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size) {
           this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, streamHeader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForBlobStream);
           return false;
         }
         this.BlobStream.MemoryReader =
           new MemoryReader(
             metadataRoot.Buffer + streamHeader.Offset,
             streamHeader.Size
           );
         break;
       case COR20Constants.GUIDStreamName:
         if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size) {
           this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, streamHeader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForGUIDStream);
           return false;
         }
         this.GUIDStream.MemoryReader =
           new MemoryReader(
             metadataRoot.Buffer + streamHeader.Offset,
             streamHeader.Size
           );
         break;
       case COR20Constants.UserStringStreamName:
         if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size) {
           this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, streamHeader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForBlobStream);
           return false;
         }
         this.UserStringStream.MemoryReader =
           new MemoryReader(
             metadataRoot.Buffer + streamHeader.Offset,
             streamHeader.Size
           );
         break;
       case COR20Constants.CompressedMetadataTableStreamName:
         if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size) {
           this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, streamHeader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForMetadataStream);
           return false;
         }
         this.MetadataStreamKind = MetadataStreamKind.Compressed;
         this.MetadataTableStream =
           new MemoryBlock(
             metadataRoot.Buffer + streamHeader.Offset,
             streamHeader.Size
           );
         break;
       case COR20Constants.UncompressedMetadataTableStreamName:
         if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size) {
           this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, streamHeader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForMetadataStream);
           return false;
         }
         this.MetadataStreamKind = MetadataStreamKind.UnCompressed;
         this.MetadataTableStream =
           new MemoryBlock(
             metadataRoot.Buffer + streamHeader.Offset,
             streamHeader.Size
           );
         break;
       default:
         this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, streamHeader.Offset, MetadataReaderErrorKind.UnknownMetadataStream);
         break;
     }
   }
   return true;
 }
Ejemplo n.º 5
0
        private void InitializeStreamReaders(
            ref MemoryBlock metadataRoot,
            StreamHeader[] streamHeaders,
            out MetadataStreamKind metadataStreamKind,
            out MemoryBlock metadataTableStream,
            out MemoryBlock standalonePdbStream)
        {
            metadataTableStream = default(MemoryBlock);
            standalonePdbStream = default(MemoryBlock);
            metadataStreamKind  = MetadataStreamKind.Illegal;

            foreach (StreamHeader streamHeader in streamHeaders)
            {
                switch (streamHeader.Name)
                {
                case COR20Constants.StringStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForStringStream");
                    }

                    break;

                case COR20Constants.BlobStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForBlobStream");
                    }

                    this.BlobHeap = new BlobHeap(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size), _metadataKind);
                    break;

                case COR20Constants.GUIDStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForGUIDStream");
                    }

                    break;

                case COR20Constants.UserStringStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForBlobStream");
                    }

                    break;

                case COR20Constants.CompressedMetadataTableStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForMetadataStream");
                    }

                    metadataStreamKind  = MetadataStreamKind.Compressed;
                    metadataTableStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size);
                    break;

                case COR20Constants.UncompressedMetadataTableStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForMetadataStream");
                    }

                    metadataStreamKind  = MetadataStreamKind.Uncompressed;
                    metadataTableStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size);
                    break;

                case COR20Constants.MinimalDeltaMetadataTableStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForMetadataStream");
                    }

                    // the content of the stream is ignored
                    this.IsMinimalDelta = true;
                    break;

                case COR20Constants.StandalonePdbStreamName:
                    if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
                    {
                        throw new BadImageFormatException("NotEnoughSpaceForMetadataStream");
                    }

                    standalonePdbStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size);
                    break;

                default:
                    // Skip unknown streams. Some obfuscators insert invalid streams.
                    continue;
                }
            }

            if (IsMinimalDelta && metadataStreamKind != MetadataStreamKind.Uncompressed)
            {
                throw new BadImageFormatException("InvalidMetadataStreamFormat");
            }
        }