/// <inheritdoc />
        public bool Equals(InvalidTypeDefOrRef x, InvalidTypeDefOrRef y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }
            if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
            {
                return(false);
            }

            return(x.Error == y.Error);
        }
        /// <summary>
        /// Determines whether two types are considered equal according to their signature.
        /// </summary>
        /// <param name="type1">The first type to compare.</param>
        /// <param name="type2">The second type to compare.</param>
        /// <returns><c>True</c> if the types are considered equal, <c>False</c> otherwise.</returns>
        public bool Equals(InvalidTypeDefOrRef type1, InvalidTypeDefOrRef type2)
        {
            if (type1 == null && type2 == null)
            {
                return(true);
            }
            if (type1 == null || type2 == null)
            {
                return(false);
            }

            return(type1.Error == type2.Error);
        }
        /// <inheritdoc />
        public bool Equals(ITypeDescriptor x, ITypeDescriptor y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }
            if (x is null || y is null)
            {
                return(false);
            }

            return(x switch
            {
                InvalidTypeDefOrRef invalidType => Equals(invalidType, y as InvalidTypeDefOrRef),
                TypeSpecification specification => Equals(specification, y as TypeSpecification),
                TypeSignature signature => Equals(signature, y as TypeSignature),
                _ => SimpleTypeEquals(x, y)
            });
Beispiel #4
0
        /// <summary>
        /// Reads a single coded index to a type definition or reference and resolves it.
        /// </summary>
        /// <param name="image">The image the type resides in.</param>
        /// <param name="reader">The reader to use.</param>
        /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param>
        /// <returns>The type, or <c>null</c> if recursion was detected.</returns>
        protected static ITypeDefOrRef ReadTypeDefOrRef(MetadataImage image, IBinaryStreamReader reader, RecursionProtection protection)
        {
            var tableStream = image.Header.GetStream <TableStream>();

            if (!reader.TryReadCompressedUInt32(out uint codedIndex))
            {
                return(null);
            }

            // If the resolved type is a TypeSpec, it can be a (malicious) loop to the same blob signature that we
            // were coming from.
            var token = tableStream.GetIndexEncoder(CodedIndex.TypeDefOrRef).DecodeIndex(codedIndex);

            if (token.TokenType == MetadataTokenType.TypeSpec && !protection.TraversedTokens.Add(token))
            {
                return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.MetadataLoop));
            }

            image.TryResolveMember(token, out var type);
            return(type as ITypeDefOrRef);
        }
        public void MaliciousMetadataLoop()
        {
            var spec     = CreateDummyType();
            var image    = spec.Image;
            var importer = new ReferenceImporter(image);

            spec.Signature = new MaliciousTypeSignature(
                importer.ImportType(typeof(object)),
                spec);

            var header  = image.Header;
            var mapping = header.UnlockMetadata();

            var newImage = header.LockMetadata();
            var newSpec  = (TypeSpecification)newImage.ResolveMember(mapping[spec]);

            Assert.Equal(
                InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.MetadataLoop),
                newSpec.Signature.GetElementType(),
                Comparer);
        }
Beispiel #6
0
        /// <summary>
        /// Reads a TypeDefOrRef coded index from the provided blob reader.
        /// </summary>
        /// <param name="module">The module containing the blob signature.</param>
        /// <param name="reader">The blob reader.</param>
        /// <param name="protection">The object responsible for detecting infinite recursion.</param>
        /// <param name="allowTypeSpec">Indicates the coded index to the type is allowed to be decoded to a member in
        /// the type specification table.</param>
        /// <returns>The decoded and resolved type definition or reference.</returns>
        protected static ITypeDefOrRef ReadTypeDefOrRef(ModuleDefinition module, IBinaryStreamReader reader,
                                                        RecursionProtection protection, bool allowTypeSpec)
        {
            if (!reader.TryReadCompressedUInt32(out uint codedIndex))
            {
                return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.BlobTooShort));
            }

            var decoder = module.GetIndexEncoder(CodedIndex.TypeDefOrRef);
            var token   = decoder.DecodeIndex(codedIndex);

            // Check if type specs can be encoded.
            if (token.Table == TableIndex.TypeSpec && !allowTypeSpec)
            {
                return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.IllegalTypeSpec));
            }

            switch (token.Table)
            {
            // Check for infinite recursion.
            case TableIndex.TypeSpec when !protection.TraversedTokens.Add(token):
                return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.MetadataLoop));

            // Any other type is legal.
            case TableIndex.TypeSpec:
            case TableIndex.TypeDef:
            case TableIndex.TypeRef:
                if (module.TryLookupMember(token, out var member) && member is ITypeDefOrRef typeDefOrRef)
                {
                    return(typeDefOrRef);
                }
                break;
            }

            return(InvalidTypeDefOrRef.Get(InvalidTypeSignatureError.InvalidCodedIndex));
        }
 /// <inheritdoc />
 public int GetHashCode(InvalidTypeDefOrRef obj)
 {
     return((int)obj.Error);
 }