コード例 #1
0
        public static CustomAttributeSignature FromReader(CustomAttribute parent, IBinaryStreamReader reader)
        {
            long position = reader.Position;

            if (!reader.CanRead(sizeof (ushort)) || reader.ReadUInt16() != 0x0001)
                throw new ArgumentException("Signature doesn't refer to a valid custom attribute signature.");

            var signature = new CustomAttributeSignature()
            {
                StartOffset = position,
            };

            if (parent.Constructor != null)
            {
                var methodSignature = parent.Constructor.Signature as MethodSignature;
                if (methodSignature != null)
                {
                    foreach (var parameter in methodSignature.Parameters)
                    {
                        signature.FixedArguments.Add(CustomAttributeArgument.FromReader(parent.Header,
                            parameter.ParameterType, reader));
                    }
                }
            }

            var namedElementCount = reader.CanRead(sizeof (ushort)) ? reader.ReadUInt16() : 0;
            for (uint i = 0; i < namedElementCount; i++)
            {
                signature.NamedArguments.Add(CustomAttributeNamedArgument.FromReader(parent.Header, reader));
            }

            return signature;
        }
コード例 #2
0
        public static new GenericInstanceTypeSignature FromReader(MetadataHeader header, IBinaryStreamReader reader)
        {
            if (!reader.CanRead(sizeof (byte)))
                return null;

            long position = reader.Position;

            var elementType = (ElementType)reader.ReadByte();

            var type = ReadTypeDefOrRef(header, reader);

            var signature = new GenericInstanceTypeSignature(type)
            {
                StartOffset = position,
                IsValueType = elementType == ElementType.ValueType
            };

            uint count;
            if (!reader.TryReadCompressedUInt32(out count))
                return signature;

            for (int i = 0; i < count; i++)
                signature.GenericArguments.Add(TypeSignature.FromReader(header, reader));

            return signature;
        }
コード例 #3
0
ファイル: MethodSignature.cs プロジェクト: JerreS/AsmResolver
        public static new MethodSignature FromReader(MetadataHeader header, IBinaryStreamReader reader)
        {
            if (!reader.CanRead(sizeof (byte)))
                return null;

            var signature = new MethodSignature
            {
                StartOffset = reader.Position,
                Attributes = (CallingConventionAttributes)reader.ReadByte()
            };

            if (signature.IsGeneric)
            {
                uint genericParameterCount;
                if (!reader.TryReadCompressedUInt32(out genericParameterCount))
                    return signature;
                signature.GenericParameterCount = (int)genericParameterCount;
            }

            uint parameterCount;
            if (!reader.TryReadCompressedUInt32(out parameterCount))
                return signature;

            signature.ReturnType = TypeSignature.FromReader(header, reader);
            for (int i = 0; i < parameterCount; i++)
            {
                signature.Parameters.Add(ParameterSignature.FromReader(header, reader));
            }

            return signature;
        }
コード例 #4
0
        public static CustomAttributeArgument FromReader(MetadataHeader header, TypeSignature typeSignature, IBinaryStreamReader reader)
        {
            var signature = new CustomAttributeArgument()
            {
                StartOffset = reader.Position,
                ArgumentType = typeSignature
            };

            if (typeSignature.ElementType != ElementType.SzArray)
            {
                signature.Elements.Add(ElementSignature.FromReader(header, typeSignature, reader));
            }
            else
            {
                var arrayType = ((SzArrayTypeSignature)typeSignature).BaseType;

                var elementCount = reader.CanRead(sizeof (uint)) ? reader.ReadUInt32() : uint.MaxValue;
                if (elementCount != uint.MaxValue)
                {
                    for (uint i = 0; i < elementCount; i++)
                    {
                        signature.Elements.Add(ElementSignature.FromReader(header, arrayType, reader));
                    }
                }
            }

            return signature;
        }
コード例 #5
0
        public static new SafeArrayMarshalDescriptor FromReader(IBinaryStreamReader reader)
        {
            var descriptor = new SafeArrayMarshalDescriptor()
            {
                StartOffset = reader.Position,
            };

            if (reader.CanRead((sizeof (byte))))
                descriptor.ElementType = (VariantType)reader.ReadByte();

            return descriptor;
        }
コード例 #6
0
 public static CustomAttributeNamedArgument FromReader(MetadataHeader header, IBinaryStreamReader reader)
 {
     var signature = new CustomAttributeNamedArgument
     {
         StartOffset = reader.Position,
         ArgumentMemberType =
             (reader.CanRead(sizeof (byte))
                 ? (CustomAttributeArgumentMemberType)reader.ReadByte()
                 : CustomAttributeArgumentMemberType.Field),
         ArgumentType = TypeSignature.ReadFieldOrPropType(header, reader),
         MemberName = reader.ReadSerString(),
     };
     signature.Argument = CustomAttributeArgument.FromReader(header, signature.ArgumentType, reader);
     return signature;
 }
コード例 #7
0
        public static CustomAttributeSignature FromReader(CustomAttribute parent, IBinaryStreamReader reader)
        {
            long position = reader.Position;

            if (!reader.CanRead(sizeof(ushort)) || reader.ReadUInt16() != 0x0001)
            {
                throw new ArgumentException("Signature doesn't refer to a valid custom attribute signature.");
            }

            var signature = new CustomAttributeSignature()
            {
                StartOffset = position,
            };

            if (parent.Constructor != null)
            {
                var methodSignature = parent.Constructor.Signature as MethodSignature;
                if (methodSignature != null)
                {
                    foreach (var parameter in methodSignature.Parameters)
                    {
                        signature.FixedArguments.Add(CustomAttributeArgument.FromReader(parent.Header,
                                                                                        parameter.ParameterType, reader));
                    }
                }
            }

            var namedElementCount = reader.CanRead(sizeof(ushort)) ? reader.ReadUInt16() : 0;

            for (uint i = 0; i < namedElementCount; i++)
            {
                signature.NamedArguments.Add(CustomAttributeNamedArgument.FromReader(parent.Header, reader));
            }

            return(signature);
        }
コード例 #8
0
        /// <summary>
        /// Reads a metadata directory from an input stream.
        /// </summary>
        /// <param name="context">The reader context.</param>
        /// <param name="directoryReader">The input stream containing the metadata directory.</param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception>
        /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception>
        public SerializedMetadata(PEReaderContext context, IBinaryStreamReader directoryReader)
        {
            if (directoryReader == null)
            {
                throw new ArgumentNullException(nameof(directoryReader));
            }
            _context = context ?? throw new ArgumentNullException(nameof(context));

            _streamContentsReader = directoryReader.Fork();

            var signature = (MetadataSignature)directoryReader.ReadUInt32();

            switch (signature)
            {
            case MetadataSignature.Bsjb:
                // BSJB header is the default header.
                break;

            case MetadataSignature.Moc:
                _context.NotSupported("Old +MOC metadata header format is not supported.");
                return;

            default:
                _context.BadImage($"Invalid metadata header ({(uint) signature:X8}).");
                return;
            }

            MajorVersion = directoryReader.ReadUInt16();
            MinorVersion = directoryReader.ReadUInt16();
            Reserved     = directoryReader.ReadUInt32();

            int versionLength = directoryReader.ReadInt32();

            if (!directoryReader.CanRead(versionLength))
            {
                _context.BadImage($"Invalid version length in metadata header ({versionLength.ToString()} characters).");
                return;
            }

            var versionBytes = new byte[versionLength];

            directoryReader.ReadBytes(versionBytes, 0, versionBytes.Length);
            VersionString = Encoding.ASCII.GetString(versionBytes);

            Flags                = directoryReader.ReadUInt16();
            _numberOfStreams     = directoryReader.ReadInt16();
            _streamEntriesReader = directoryReader.Fork();
        }
コード例 #9
0
        /// <summary>
        /// Reads a serialized UTF8 string from the stream.
        /// </summary>
        /// <param name="reader">The reader to use for reading the data.</param>
        /// <returns>The string that was read from the stream.</returns>
        public static string ReadSerString(this IBinaryStreamReader reader)
        {
            if (!reader.CanRead(1) || reader.ReadByte() == 0xFF)
            {
                return(null);
            }
            reader.FileOffset--;
            if (!reader.TryReadCompressedUInt32(out uint length))
            {
                return(null);
            }
            var data = new byte[length];

            length = (uint)reader.ReadBytes(data, 0, (int)length);
            return(Encoding.UTF8.GetString(data, 0, (int)length));
        }
コード例 #10
0
        public static new FixedArrayMarshalDescriptor FromReader(IBinaryStreamReader reader)
        {
            var descriptor = new FixedArrayMarshalDescriptor()
            {
                StartOffset = reader.Position,
            };

            uint value;
            if (!reader.TryReadCompressedUInt32(out value))
                return descriptor;
            descriptor.NumberOfElements = (int)value;

            if (reader.CanRead(sizeof(byte)))
                descriptor.ElementType = (NativeType)reader.ReadByte();
            return descriptor;
        }
コード例 #11
0
        public static CustomAttributeNamedArgument FromReader(MetadataHeader header, IBinaryStreamReader reader)
        {
            var signature = new CustomAttributeNamedArgument
            {
                StartOffset        = reader.Position,
                ArgumentMemberType =
                    (reader.CanRead(sizeof(byte))
                        ? (CustomAttributeArgumentMemberType)reader.ReadByte()
                        : CustomAttributeArgumentMemberType.Field),
                ArgumentType = TypeSignature.ReadFieldOrPropType(header, reader),
                MemberName   = reader.ReadSerString(),
            };

            signature.Argument = CustomAttributeArgument.FromReader(header, signature.ArgumentType, reader);
            return(signature);
        }
コード例 #12
0
        public new static FixedArrayMarshalDescriptor FromReader(IBinaryStreamReader reader)
        {
            var  descriptor = new FixedArrayMarshalDescriptor();
            uint value;

            if (!reader.TryReadCompressedUInt32(out value))
            {
                return(descriptor);
            }
            descriptor.NumberOfElements = (int)value;

            if (reader.CanRead(sizeof(byte)))
            {
                descriptor.ElementType = (NativeType)reader.ReadByte();
            }
            return(descriptor);
        }
コード例 #13
0
        /// <summary>
        /// Reads a metadata directory from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <param name="metadataStreamReader"></param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception>
        /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception>
        public SerializedMetadata(IBinaryStreamReader reader, IMetadataStreamReader metadataStreamReader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _metadataStreamReader = metadataStreamReader;

            _streamContentsReader = reader.Fork();

            var signature = (MetadataSignature)reader.ReadUInt32();

            switch (signature)
            {
            case MetadataSignature.Bsjb:
                // BSJB header is the default header.
                break;

            case MetadataSignature.Moc:
                throw new NotSupportedException("Old +MOC metadata header format is not supported.");

            default:
                throw new BadImageFormatException($"Invalid metadata header ({(uint) signature:X8}).");
            }

            MajorVersion = reader.ReadUInt16();
            MinorVersion = reader.ReadUInt16();
            Reserved     = reader.ReadUInt32();

            int versionLength = reader.ReadInt32();

            if (!reader.CanRead(versionLength))
            {
                throw new BadImageFormatException($"Invalid version length in metadata header ({versionLength} characters).");
            }

            var versionBytes = new byte[versionLength];

            reader.ReadBytes(versionBytes, 0, versionBytes.Length);
            VersionString = Encoding.ASCII.GetString(versionBytes);

            Flags                = reader.ReadUInt16();
            _numberOfStreams     = reader.ReadInt16();
            _streamEntriesReader = reader.Fork();
        }
コード例 #14
0
        /// <summary>
        /// Reads a single method signature at the current position of the provided stream reader.
        /// </summary>
        /// <param name="image">The image the field is defined in.</param>
        /// <param name="reader">The reader to use.</param>
        /// <param name="readToEnd">Determines whether any extra data after the signature should be read and
        /// put into the <see cref="ExtendableBlobSignature.ExtraData"/> property.</param>
        /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param>
        /// <returns>The read signature.</returns>
        public new static MethodSignature FromReader(
            MetadataImage image,
            IBinaryStreamReader reader,
            bool readToEnd,
            RecursionProtection protection)
        {
            if (!reader.CanRead(sizeof(byte)))
            {
                return(null);
            }

            var signature = new MethodSignature
            {
                Attributes = (CallingConventionAttributes)reader.ReadByte()
            };

            if (signature.IsGeneric)
            {
                if (!reader.TryReadCompressedUInt32(out uint genericParameterCount))
                {
                    return(signature);
                }
                signature.GenericParameterCount = (int)genericParameterCount;
            }

            if (!reader.TryReadCompressedUInt32(out uint parameterCount))
            {
                return(signature);
            }

            signature.ReturnType = TypeSignature.FromReader(image, reader);

            for (int i = 0; i < parameterCount; i++)
            {
                signature.Parameters.Add(ParameterSignature.FromReader(image, reader, protection));
            }

            if (readToEnd)
            {
                signature.ExtraData = reader.ReadToEnd();
            }

            return(signature);
        }
コード例 #15
0
        private static CustomAttributeArgument ReadSzArrayArgument(ModuleDefinition parentModule,
                                                                   TypeSignature argumentType, IBinaryStreamReader reader)
        {
            var result = new CustomAttributeArgument(argumentType);

            var  arrayElementType = ((SzArrayTypeSignature)argumentType).BaseType;
            uint elementCount     = reader.CanRead(sizeof(uint)) ? reader.ReadUInt32() : uint.MaxValue;

            result.IsNullArray = elementCount == uint.MaxValue;

            if (!result.IsNullArray)
            {
                for (uint i = 0; i < elementCount; i++)
                {
                    var element = CustomAttributeArgumentElement.FromReader(parentModule, arrayElementType, reader);
                    result.Elements.Add(element);
                }
            }

            return(result);
        }
コード例 #16
0
        /// <summary>
        /// Reads a permission set signature from the provided input blob stream.
        /// </summary>
        /// <param name="parentModule">The module the permission set resides in.</param>
        /// <param name="reader">The input blob stream.</param>
        /// <returns>The permission set.</returns>
        public static PermissionSetSignature FromReader(ModuleDefinition parentModule, IBinaryStreamReader reader)
        {
            var result = new PermissionSetSignature();

            if (reader.ReadByte() != '.')
            {
                return(result);
            }

            if (!reader.TryReadCompressedUInt32(out uint count))
            {
                return(result);
            }

            for (int i = 0; i < count && reader.CanRead(1); i++)
            {
                result.Attributes.Add(SecurityAttribute.FromReader(parentModule, reader));
            }

            return(result);
        }
コード例 #17
0
        public new static MethodSignature FromReader(MetadataHeader header, IBinaryStreamReader reader)
        {
            if (!reader.CanRead(sizeof(byte)))
            {
                return(null);
            }

            var signature = new MethodSignature
            {
                StartOffset = reader.Position,
                Attributes  = (CallingConventionAttributes)reader.ReadByte()
            };

            if (signature.IsGeneric)
            {
                uint genericParameterCount;
                if (!reader.TryReadCompressedUInt32(out genericParameterCount))
                {
                    return(signature);
                }
                signature.GenericParameterCount = (int)genericParameterCount;
            }

            uint parameterCount;

            if (!reader.TryReadCompressedUInt32(out parameterCount))
            {
                return(signature);
            }

            signature.ReturnType = TypeSignature.FromReader(header, reader);
            for (int i = 0; i < parameterCount; i++)
            {
                signature.Parameters.Add(ParameterSignature.FromReader(header, reader));
            }

            return(signature);
        }
コード例 #18
0
        internal static GenericInstanceMethodSignature FromReader(ModuleDefinition parentModule,
                                                                  IBinaryStreamReader reader, RecursionProtection protection)
        {
            if (!reader.CanRead(sizeof(byte)))
            {
                return(null);
            }

            var attributes = (CallingConventionAttributes)reader.ReadByte();
            var result     = new GenericInstanceMethodSignature(attributes);

            if (!reader.TryReadCompressedUInt32(out uint count))
            {
                return(result);
            }

            for (int i = 0; i < count; i++)
            {
                result.TypeArguments.Add(TypeSignature.FromReader(parentModule, reader, protection));
            }

            return(result);
        }
コード例 #19
0
        /// <summary>
        /// Reads a single safe array marshal descriptor from the provided input stream.
        /// </summary>
        /// <param name="parentModule">The module defining the descriptor.</param>
        /// <param name="reader">The input stream.</param>
        /// <returns>The descriptor.</returns>
        public new static SafeArrayMarshalDescriptor FromReader(ModuleDefinition parentModule, IBinaryStreamReader reader)
        {
            if (!reader.TryReadCompressedUInt32(out uint type))
            {
                return(new SafeArrayMarshalDescriptor(SafeArrayVariantType.NotSet));
            }

            var variantType = (SafeArrayVariantType)type & SafeArrayVariantType.TypeMask;
            var flags       = (SafeArrayTypeFlags)type & ~SafeArrayTypeFlags.Mask;

            var result = new SafeArrayMarshalDescriptor(variantType, flags);

            if (reader.CanRead(1))
            {
                string typeName = reader.ReadSerString();
                if (typeName != null)
                {
                    result.UserDefinedSubType = TypeNameParser.Parse(parentModule, typeName);
                }
            }

            return(result);
        }
        public void ReadValue(TypeSignature valueType)
        {
            if (valueType.IsTypeOf("System", "Type"))
            {
                Elements.Add(TypeNameParser.Parse(_parentModule, _reader.ReadSerString()));
                return;
            }

            switch (valueType.ElementType)
            {
            case ElementType.Boolean:
                Elements.Add(_reader.ReadByte() == 1);
                break;

            case ElementType.Char:
                Elements.Add((char)_reader.ReadUInt16());
                break;

            case ElementType.R4:
                Elements.Add(_reader.ReadSingle());
                break;

            case ElementType.R8:
                Elements.Add(_reader.ReadDouble());
                break;

            case ElementType.I1:
                Elements.Add(_reader.ReadSByte());
                break;

            case ElementType.I2:
                Elements.Add(_reader.ReadInt16());
                break;

            case ElementType.I4:
                Elements.Add(_reader.ReadInt32());
                break;

            case ElementType.I8:
                Elements.Add(_reader.ReadInt64());
                break;

            case ElementType.U1:
                Elements.Add(_reader.ReadByte());
                break;

            case ElementType.U2:
                Elements.Add(_reader.ReadUInt16());
                break;

            case ElementType.U4:
                Elements.Add(_reader.ReadUInt32());
                break;

            case ElementType.U8:
                Elements.Add(_reader.ReadUInt64());
                break;

            case ElementType.String:
                Elements.Add(_reader.ReadSerString());
                break;

            case ElementType.Object:
                var reader = new CustomAttributeArgumentReader(_parentModule, _reader);
                var type   = TypeSignature.ReadFieldOrPropType(_parentModule, _reader);
                reader.ReadValue(type);
                Elements.Add(new BoxedArgument(type, type.ElementType == ElementType.SzArray
                        ? reader.Elements.ToArray()
                        : reader.Elements[0]));
                break;

            case ElementType.SzArray:
                var  arrayElementType = ((SzArrayTypeSignature)valueType).BaseType;
                uint elementCount     = _reader.CanRead(sizeof(uint)) ? _reader.ReadUInt32() : uint.MaxValue;
                IsNullArray = elementCount == uint.MaxValue;

                if (!IsNullArray)
                {
                    for (uint i = 0; i < elementCount; i++)
                    {
                        ReadValue(arrayElementType);
                    }
                }

                break;

            case ElementType.Class:
            case ElementType.Enum:
            case ElementType.ValueType:
                // Value is an enum, resolve it and get underlying type.
                // If that fails, most enums are int32s, assume that is the case in an attempt to recover.

                var enumTypeDef = _parentModule.MetadataResolver.ResolveType(valueType);

                TypeSignature underlyingType;
                if (enumTypeDef is null)
                {
                    underlyingType = _parentModule.CorLibTypeFactory.Int32;
                }
                else if (enumTypeDef.IsEnum)
                {
                    underlyingType = enumTypeDef.GetEnumUnderlyingType() ?? _parentModule.CorLibTypeFactory.Int32;
                }
                else
                {
                    throw new NotSupportedException($"Type {valueType} is not an enum.");
                }

                ReadValue(underlyingType);
                break;

            default:
                throw new NotSupportedException($"Unsupported element type {valueType.ElementType}.");
            }
        }