예제 #1
0
        internal TType DecodeFieldSignature <TType>(ISignatureTypeProvider <TType> provider)
        {
            var decoder    = new SignatureDecoder <TType>(provider, _reader);
            var blobReader = _reader.GetBlobReader(Signature);

            return(decoder.DecodeFieldSignature(ref blobReader));
        }
예제 #2
0
        public MethodSignature <TType> DecodeMethodSignature <TType>(ISignatureTypeProvider <TType> provider)
        {
            var decoder    = new SignatureDecoder <TType>(provider, _reader);
            var blobReader = _reader.GetBlobReader(Signature);

            return(decoder.DecodeMethodSignature(ref blobReader));
        }
예제 #3
0
        public TType DecodeFieldSignature <TType, TGenericContext>(ISignatureTypeProvider <TType, TGenericContext> provider, TGenericContext genericContext)
        {
            var decoder    = new SignatureDecoder <TType, TGenericContext>(provider, _reader, genericContext);
            var blobReader = _reader.GetBlobReader(Signature);

            return(decoder.DecodeFieldSignature(ref blobReader));
        }
예제 #4
0
        TType DecodeFieldSignature <TType>(ISignatureTypeProvider <TType> provider, SignatureDecoderOptions options = SignatureDecoderOptions.None)
        {
            var decoder    = new SignatureDecoder <TType>(provider, _reader, options);
            var blobReader = _reader.GetBlobReader(Signature);

            return(decoder.DecodeFieldSignature(ref blobReader));
        }
예제 #5
0
        /// <summary>
        /// Gets the fixed (required) string arguments of a custom attribute.
        /// Only attributes that have only fixed string arguments.
        /// </summary>
        private static List<string> GetFixedStringArguments(MetadataReader reader, CustomAttribute attribute)
        {
            // TODO: Nick Guerrera ([email protected]) hacked this method for temporary use.
            // There is a blob decoder feature in progress but it won't ship in time for our milestone.
            // Replace this method with the blob decoder feature when later it is availale.

            var signature = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature;
            var signatureReader = reader.GetBlobReader(signature);
            var valueReader = reader.GetBlobReader(attribute.Value);
            var arguments = new List<string>();

            var prolog = valueReader.ReadUInt16();
            if (prolog != 1)
            {
                // Invalid custom attribute prolog
                return arguments;
            }

            var header = signatureReader.ReadSignatureHeader();
            if (header.Kind != SignatureKind.Method || header.IsGeneric)
            {
                // Invalid custom attribute constructor signature
                return arguments;
            }

            int parameterCount;
            if (!signatureReader.TryReadCompressedInteger(out parameterCount))
            {
                // Invalid custom attribute constructor signature
                return arguments;
            }

            var returnType = signatureReader.ReadSignatureTypeCode();
            if (returnType != SignatureTypeCode.Void)
            {
                // Invalid custom attribute constructor signature
                return arguments;
            }

            for (int i = 0; i < parameterCount; i++)
            {
                var signatureTypeCode = signatureReader.ReadSignatureTypeCode();
                if (signatureTypeCode == SignatureTypeCode.String)
                {
                    // Custom attribute constructor must take only strings
                    arguments.Add(valueReader.ReadSerializedString());
                }
            }

            return arguments;
        }
예제 #6
0
        internal ImmutableArray <TType> DecodeSignature <TType>(ISignatureTypeProvider <TType> provider)
        {
            var decoder    = new Ecma335.SignatureDecoder <TType>(provider, _reader);
            var blobReader = _reader.GetBlobReader(Signature);

            return(decoder.DecodeMethodSpecificationSignature(ref blobReader));
        }
예제 #7
0
        public ImmutableArray <TType> DecodeSignature <TType, TGenericContext>(ISignatureTypeProvider <TType, TGenericContext> provider, TGenericContext genericContext)
        {
            var decoder    = new Ecma335.SignatureDecoder <TType, TGenericContext>(provider, _reader, genericContext);
            var blobReader = _reader.GetBlobReader(Signature);

            return(decoder.DecodeMethodSpecificationSignature(ref blobReader));
        }
예제 #8
0
        public ImmutableArray <TType> DecodeSignature <TType>(ISignatureTypeProvider <TType> provider, SignatureDecoderOptions options = SignatureDecoderOptions.None)
        {
            var decoder    = new SignatureDecoder <TType>(provider, _reader, options);
            var blobReader = _reader.GetBlobReader(Signature);

            return(decoder.DecodeMethodSpecificationSignature(ref blobReader));
        }
예제 #9
0
        /// <summary>
        /// Construct the strong assembly name from metadata
        /// </summary>
        internal static string GetAssemblyStrongName(MetadataReader metadataReader)
        {
            AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();
            string asmName = metadataReader.GetString(assemblyDefinition.Name);
            string asmVersion = assemblyDefinition.Version.ToString();
            string asmCulture = metadataReader.GetString(assemblyDefinition.Culture);
            asmCulture = (asmCulture == string.Empty) ? "neutral" : asmCulture;

            AssemblyHashAlgorithm hashAlgorithm = assemblyDefinition.HashAlgorithm;
            BlobHandle blobHandle = assemblyDefinition.PublicKey;
            BlobReader blobReader = metadataReader.GetBlobReader(blobHandle);

            string publicKeyTokenString = "null";
            // Extract public key token only if PublicKey exists in the metadata
            if (blobReader.Length > 0)
            {
                byte[] publickey = blobReader.ReadBytes(blobReader.Length);

                HashAlgorithm hashImpl = null;
                switch (hashAlgorithm)
                {
                    case AssemblyHashAlgorithm.Sha1:
                        hashImpl = SHA1.Create();
                        break;
                    case AssemblyHashAlgorithm.MD5:
                        hashImpl = MD5.Create();
                        break;
                    case AssemblyHashAlgorithm.Sha256:
                        hashImpl = SHA256.Create();
                        break;
                    case AssemblyHashAlgorithm.Sha384:
                        hashImpl = SHA384.Create();
                        break;
                    case AssemblyHashAlgorithm.Sha512:
                        hashImpl = SHA512.Create();
                        break;
                    default:
                        throw new NotSupportedException();
                }

                byte[] publicKeyHash = hashImpl.ComputeHash(publickey);
                byte[] publicKeyTokenBytes = new byte[8];
                // Note that, the low 8 bytes of the hash of public key in reverse order is the public key tokens.
                for (int i = 1; i <= 8; i++)
                {
                    publicKeyTokenBytes[i - 1] = publicKeyHash[publicKeyHash.Length - i];
                }

                // Convert bytes to hex format strings in lower case.
                publicKeyTokenString = BitConverter.ToString(publicKeyTokenBytes).Replace("-", string.Empty).ToLowerInvariant();
            }

            string strongAssemblyName = string.Format(CultureInfo.InvariantCulture,
                                                      "{0}, Version={1}, Culture={2}, PublicKeyToken={3}",
                                                      asmName, asmVersion, asmCulture, publicKeyTokenString);

            return strongAssemblyName;
        }
예제 #10
0
        private BlobHandle GetProjectedValue(CustomAttributeValueTreatment treatment)
        {
            BlobHandle.VirtualIndex virtualIndex;
            bool isVersionOrDeprecated;

            switch (treatment)
            {
            case CustomAttributeValueTreatment.AttributeUsageVersionAttribute:
            case CustomAttributeValueTreatment.AttributeUsageDeprecatedAttribute:
                virtualIndex          = BlobHandle.VirtualIndex.AttributeUsage_AllowMultiple;
                isVersionOrDeprecated = true;
                break;

            case CustomAttributeValueTreatment.AttributeUsageAllowMultiple:
                virtualIndex          = BlobHandle.VirtualIndex.AttributeUsage_AllowMultiple;
                isVersionOrDeprecated = false;
                break;

            case CustomAttributeValueTreatment.AttributeUsageAllowSingle:
                virtualIndex          = BlobHandle.VirtualIndex.AttributeUsage_AllowSingle;
                isVersionOrDeprecated = false;
                break;

            default:
                Debug.Assert(false);
                return(default(BlobHandle));
            }

            // Raw blob format:
            //    01 00        - Fixed prolog for CA's
            //    xx xx xx xx  - The Windows.Foundation.Metadata.AttributeTarget value
            //    00 00        - Indicates 0 name/value pairs following.
            var rawBlob       = _reader.CustomAttributeTable.GetValue(Handle);
            var rawBlobReader = _reader.GetBlobReader(rawBlob);

            if (rawBlobReader.Length != 8)
            {
                return(rawBlob);
            }

            if (rawBlobReader.ReadInt16() != 1)
            {
                return(rawBlob);
            }

            AttributeTargets projectedValue = ProjectAttributeTargetValue(rawBlobReader.ReadUInt32());

            if (isVersionOrDeprecated)
            {
                projectedValue |= AttributeTargets.Constructor | AttributeTargets.Property;
            }

            return(BlobHandle.FromVirtualIndex(virtualIndex, (ushort)projectedValue));
        }
예제 #11
0
        private static string GetFileName(MetadataReader reader, DocumentHandle documentHandle)
        {
            var document = reader.GetDocument(documentHandle);

            if (document.Name.IsNil)
            {
                return null;
            }

            var nameReader = reader.GetBlobReader(document.Name);

            int separator = nameReader.ReadByte();
            if (!FileNameUtilities.IsDirectorySeparator((char)separator))
            {
                return FileNameUtilities.GetFileName(reader.GetString(document.Name));
            }

            // find the last part handle:
            BlobHandle partHandle = default(BlobHandle);
            while (nameReader.RemainingBytes > 0)
            {
                partHandle = nameReader.ReadBlobHandle();
            }

            if (partHandle.IsNil)
            {
                return string.Empty;
            }

            var partReader = reader.GetBlobReader(partHandle);
            var part = partReader.ReadUTF8(partReader.Length);
            if (part.IndexOf('\0') >= 0)
            {
                // bad metadata
                return null;
            }

            // it is valid to encode document name so that the parts contain directory separators:
            return FileNameUtilities.GetFileName(part);
        }
예제 #12
0
        private static string GetMetadataNameWithoutBackticks(MetadataReader reader, StringHandle name)
        {
            var blobReader = reader.GetBlobReader(name);
            var backtickIndex = blobReader.IndexOf((byte)'`');
            if (backtickIndex == -1)
            {
                return reader.GetString(name);
            }

            unsafe
            {
                return MetadataStringDecoder.DefaultUTF8.GetString(
                    blobReader.CurrentPointer, backtickIndex);
            }
        }
예제 #13
0
        /// <summary>
        /// Determines if the member reference is to a method or field.
        /// </summary>
        public MemberReferenceKind GetKind()
        {
            BlobReader      blobReader = reader.GetBlobReader(this.Signature);
            SignatureHeader header     = blobReader.ReadSignatureHeader();

            switch (header.Kind)
            {
            case SignatureKind.Method:
                return(MemberReferenceKind.Method);

            case SignatureKind.Field:
                return(MemberReferenceKind.Field);

            default:
                throw new BadImageFormatException();
            }
        }
예제 #14
0
        private string GetPublicKeyToken()
        {
            string publicKeyToken = null;

            AssemblyDefinition ad = _reader.GetAssemblyDefinition();
            BlobReader         br = _reader.GetBlobReader(ad.PublicKey);

            byte[] pk = br.ReadBytes(br.Length);
            if (pk.Length != 0)
            {
                AssemblyName an = new AssemblyName();
                an.SetPublicKey(pk);
                byte[] pkt = an.GetPublicKeyToken();

                publicKeyToken = BitConverter.ToString(pkt).Replace("-", "");
            }

            if (!String.IsNullOrEmpty(publicKeyToken))
            {
                publicKeyToken = publicKeyToken.ToUpperInvariant();
            }

            return(publicKeyToken);
        }
        /// <summary>Gets the string argument value of an attribute with a single fixed string argument.</summary>
        /// <param name="reader">The metadata reader.</param>
        /// <param name="attr">The attribute.</param>
        /// <param name="value">The value parsed from the attribute, if it could be retrieved; otherwise, the value is left unmodified.</param>
        private static void GetStringAttributeArgumentValue(MetadataReader reader, CustomAttribute attr, ref string value)
        {
            EntityHandle ctorHandle = attr.Constructor;
            BlobHandle signature;
            switch (ctorHandle.Kind)
            {
                case HandleKind.MemberReference:
                    signature = reader.GetMemberReference((MemberReferenceHandle)ctorHandle).Signature;
                    break;
                case HandleKind.MethodDefinition:
                    signature = reader.GetMethodDefinition((MethodDefinitionHandle)ctorHandle).Signature;
                    break;
                default:
                    // Unusual case, potentially invalid IL
                    return;
            }

            BlobReader signatureReader = reader.GetBlobReader(signature);
            BlobReader valueReader = reader.GetBlobReader(attr.Value);

            const ushort Prolog = 1; // two-byte "prolog" defined by ECMA-335 (II.23.3) to be at the beginning of attribute value blobs
            if (valueReader.ReadUInt16() == Prolog)
            {
                SignatureHeader header = signatureReader.ReadSignatureHeader();
                int parameterCount;
                if (header.Kind == SignatureKind.Method &&                               // attr ctor must be a method
                    !header.IsGeneric &&                                                 // attr ctor must be non-generic
                    signatureReader.TryReadCompressedInteger(out parameterCount) &&      // read parameter count
                    parameterCount == 1 &&                                               // attr ctor must have 1 parameter
                    signatureReader.ReadSignatureTypeCode() == SignatureTypeCode.Void && // attr ctor return type must be void
                    signatureReader.ReadSignatureTypeCode() == SignatureTypeCode.String) // attr ctor first parameter must be string
                {
                    value = valueReader.ReadSerializedString();
                }
            }
        }
예제 #16
0
        private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property)
        {
            Ecma.MetadataReader reader = module.MetadataReader;

            Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property);

            Ecma.PropertyAccessors acc          = propDef.GetAccessors();
            Cts.MethodDesc         getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter);
            Cts.MethodDesc         setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter);

            bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod);
            bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod);

            // Policy: If neither the getter nor setter have metadata, property doesn't have metadata
            if (!getterHasMetadata && !setterHasMetadata)
            {
                return(null);
            }

            Ecma.BlobReader       sigBlobReader = reader.GetBlobReader(propDef.Signature);
            Cts.PropertySignature sig           = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader, Cts.NotFoundBehavior.Throw).ParsePropertySignature();

            Property result = new Property
            {
                Name      = HandleString(reader.GetString(propDef.Name)),
                Flags     = propDef.Attributes,
                Signature = new PropertySignature
                {
                    CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis,
                    Type = HandleType(sig.ReturnType)
                },
            };

            result.Signature.Parameters.Capacity = sig.Length;
            for (int i = 0; i < sig.Length; i++)
            {
                result.Signature.Parameters.Add(HandleType(sig[i]));
            }

            if (getterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Getter,
                    Method     = HandleMethodDefinition(getterMethod),
                });
            }

            if (setterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Setter,
                    Method     = HandleMethodDefinition(setterMethod),
                });
            }

            Ecma.ConstantHandle defaultValue = propDef.GetDefaultValue();
            if (!defaultValue.IsNil)
            {
                result.DefaultValue = HandleConstant(module, defaultValue);
            }

            Ecma.CustomAttributeHandleCollection customAttributes = propDef.GetCustomAttributes();
            if (customAttributes.Count > 0)
            {
                result.CustomAttributes = HandleCustomAttributes(module, customAttributes);
            }

            return(result);
        }
예제 #17
0
        private string GetAttributeArgument(CustomAttribute attribute, MetadataReader metadataReader)
        {
            var signature = metadataReader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature;
            var signatureReader = metadataReader.GetBlobReader(signature);
            var valueReader = metadataReader.GetBlobReader(attribute.Value);

            valueReader.ReadUInt16(); // Skip prolog
            signatureReader.ReadSignatureHeader(); // Skip header

            int parameterCount;
            signatureReader.TryReadCompressedInteger(out parameterCount);

            signatureReader.ReadSignatureTypeCode(); // Skip return type

            for (int i = 0; i < parameterCount; i++)
            {
                var signatureTypeCode = signatureReader.ReadSignatureTypeCode();
                if (signatureTypeCode == SignatureTypeCode.String)
                {
                    return valueReader.ReadSerializedString();
                }
            }

            return string.Empty;
        }
예제 #18
0
        private MetadataRecord HandleConstant(Cts.Ecma.EcmaModule module, Ecma.ConstantHandle constantHandle)
        {
            Ecma.MetadataReader reader   = module.MetadataReader;
            Ecma.Constant       constant = reader.GetConstant(constantHandle);

            Ecma.BlobReader blob = reader.GetBlobReader(constant.Value);

            switch (constant.TypeCode)
            {
            case ConstantTypeCode.Boolean:
                return(new ConstantBooleanValue {
                    Value = blob.ReadBoolean()
                });

            case ConstantTypeCode.Byte:
                return(new ConstantByteValue {
                    Value = blob.ReadByte()
                });

            case ConstantTypeCode.Char:
                return(new ConstantCharValue {
                    Value = blob.ReadChar()
                });

            case ConstantTypeCode.Double:
                return(new ConstantDoubleValue {
                    Value = blob.ReadDouble()
                });

            case ConstantTypeCode.Int16:
                return(new ConstantInt16Value {
                    Value = blob.ReadInt16()
                });

            case ConstantTypeCode.Int32:
                return(new ConstantInt32Value {
                    Value = blob.ReadInt32()
                });

            case ConstantTypeCode.Int64:
                return(new ConstantInt64Value {
                    Value = blob.ReadInt64()
                });

            case ConstantTypeCode.SByte:
                return(new ConstantSByteValue {
                    Value = blob.ReadSByte()
                });

            case ConstantTypeCode.Single:
                return(new ConstantSingleValue {
                    Value = blob.ReadSingle()
                });

            case ConstantTypeCode.String:
                return(HandleString(blob.ReadUTF16(blob.Length)));

            case ConstantTypeCode.UInt16:
                return(new ConstantUInt16Value {
                    Value = blob.ReadUInt16()
                });

            case ConstantTypeCode.UInt32:
                return(new ConstantUInt32Value {
                    Value = blob.ReadUInt32()
                });

            case ConstantTypeCode.UInt64:
                return(new ConstantUInt64Value {
                    Value = blob.ReadUInt64()
                });

            case ConstantTypeCode.NullReference:
                return(new ConstantReferenceValue());

            default:
                throw new BadImageFormatException();
            }
        }
예제 #19
0
        private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property)
        {
            Ecma.MetadataReader reader = module.MetadataReader;

            Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property);

            Ecma.PropertyAccessors acc          = propDef.GetAccessors();
            Cts.MethodDesc         getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter);
            Cts.MethodDesc         setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter);

            bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod);
            bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod);

            // Policy: If neither the getter nor setter have metadata, property doesn't have metadata
            if (!getterHasMetadata && !setterHasMetadata)
            {
                return(null);
            }

            Ecma.BlobReader       sigBlobReader = reader.GetBlobReader(propDef.Signature);
            Cts.PropertySignature sig           = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader).ParsePropertySignature();

            List <ParameterTypeSignature> parameters;

            if (sig.Length == 0)
            {
                parameters = null;
            }
            else
            {
                parameters = new List <ParameterTypeSignature>(sig.Length);
                for (int i = 0; i < parameters.Count; i++)
                {
                    parameters.Add(HandleParameterTypeSignature(sig[i]));
                }
            }

            Property result = new Property
            {
                Name      = HandleString(reader.GetString(propDef.Name)),
                Flags     = propDef.Attributes,
                Signature = new PropertySignature
                {
                    CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis,
                    // TODO: CustomModifiers
                    Type       = HandleType(sig.ReturnType),
                    Parameters = parameters,
                },
            };

            if (getterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Getter,
                    Method     = HandleMethodDefinition(getterMethod),
                });
            }

            if (setterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Setter,
                    Method     = HandleMethodDefinition(setterMethod),
                });
            }

            // TODO: DefaultValue
            // TODO: CustomAttributes

            return(result);
        }