/// <inheritdoc />
 public DynamicCilOperandResolver(SerializedModuleDefinition contextModule, CilMethodBody methodBody, IList <object> tokens)
     : base(contextModule, methodBody)
 {
     _tokens        = tokens ?? throw new ArgumentNullException(nameof(tokens));
     _readerContext = contextModule.ReaderContext;
     _importer      = new ReferenceImporter(contextModule);
 }
示例#2
0
        public static object ResolveOperandReflection(ModuleReaderContext context, CilMethodBody methodBody, CilInstruction instruction,
                                                      ICilOperandResolver resolver, List <object> tokens, ReferenceImporter importer)
        {
            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineBrTarget:
            case CilOperandType.ShortInlineBrTarget:
                return(methodBody.Instructions
                       .GetByOffset(((ICilLabel)instruction.Operand).Offset)
                       ?.CreateLabel());

            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                return(ReadToken(context, ((MetadataToken)instruction.Operand).ToUInt32(), tokens, importer));

            case CilOperandType.InlineString:
                return(ReadToken(context, ((MetadataToken)instruction.Operand).ToUInt32(), tokens, importer));

            case CilOperandType.InlineSwitch:
                var result = new List <ICilLabel>();
                var labels = (IList <ICilLabel>)instruction.Operand;
                for (int i = 0; i < labels.Count; i++)
                {
                    var label  = labels[i];
                    var target = methodBody.Instructions.GetByOffset(label.Offset);
                    result.Add(target != null
                            ? new CilInstructionLabel(target)
                            : label);
                }

                return(result);

            case CilOperandType.InlineVar:
            case CilOperandType.ShortInlineVar:
                return(resolver.ResolveLocalVariable(Convert.ToInt32(instruction.Operand)));

            case CilOperandType.InlineArgument:
            case CilOperandType.ShortInlineArgument:
                return(resolver.ResolveParameter(Convert.ToInt32(instruction.Operand)));

            case CilOperandType.InlineI:
            case CilOperandType.InlineI8:
            case CilOperandType.InlineNone:
            case CilOperandType.InlineR:
            case CilOperandType.ShortInlineI:
            case CilOperandType.ShortInlineR:
                return(instruction.Operand);

            case CilOperandType.InlinePhi:
                throw new NotSupportedException();

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#3
0
        /// <summary>
        /// Creates a CIL method body from a raw CIL method body.
        /// </summary>
        /// <param name="context">The reader context.</param>
        /// <param name="method">The method that owns the method body.</param>
        /// <param name="rawBody">The raw method body.</param>
        /// <param name="operandResolver">The object instance to use for resolving operands of an instruction in the
        ///     method body.</param>
        /// <returns>The method body.</returns>
        public static CilMethodBody FromRawMethodBody(
            ModuleReaderContext context,
            MethodDefinition method,
            CilRawMethodBody rawBody,
            ICilOperandResolver operandResolver = null)
        {
            var result = new CilMethodBody(method);

            if (operandResolver is null)
            {
                operandResolver = new CilOperandResolver(context.ParentModule, result);
            }

            // Read raw instructions.
            var reader       = new ByteArrayReader(rawBody.Code);
            var disassembler = new CilDisassembler(reader);

            result.Instructions.AddRange(disassembler.ReadAllInstructions());

            // Read out extra metadata.
            if (rawBody is CilRawFatMethodBody fatBody)
            {
                result.MaxStack         = fatBody.MaxStack;
                result.InitializeLocals = fatBody.InitLocals;

                ReadLocalVariables(method.Module, result, fatBody);
                ReadExceptionHandlers(fatBody, result);
            }
            else
            {
                result.MaxStack         = 8;
                result.InitializeLocals = false;
            }

            // Resolve operands.
            foreach (var instruction in result.Instructions)
            {
                instruction.Operand = ResolveOperand(result, instruction, operandResolver) ?? instruction.Operand;
            }

            return(result);
        }
示例#4
0
        private static object ReadToken(ModuleReaderContext readerContext, MetadataToken token, IList <object> tokens, ReferenceImporter importer)
        {
            switch (token.Table)
            {
            case TableIndex.TypeDef:
                var type = tokens[(int)token.Rid];
                if (type is RuntimeTypeHandle runtimeTypeHandle)
                {
                    return(importer.ImportType(Type.GetTypeFromHandle(runtimeTypeHandle)));
                }
                break;

            case TableIndex.Field:
                var field = tokens[(int)token.Rid];
                if (field is null)
                {
                    return(null);
                }
                if (field is RuntimeFieldHandle runtimeFieldHandle)
                {
                    return(importer.ImportField(FieldInfo.GetFieldFromHandle(runtimeFieldHandle)));
                }

                if (field.GetType().FullName == "System.Reflection.Emit.GenericFieldInfo")
                {
                    var result = FieldReader.TryReadField <RuntimeFieldHandle>(field, "m_field", out var mField);
                    var ctx    = FieldReader.ReadField <RuntimeTypeHandle>(field, "m_context");
                    return(importer.ImportField(FieldInfo.GetFieldFromHandle(result
                            ? mField
                            : FieldReader.ReadField <RuntimeFieldHandle>(field, "m_fieldHandle"), ctx)));
                }

                break;

            case TableIndex.Method:
            case TableIndex.MemberRef:
                var obj = tokens[(int)token.Rid];
                if (obj is RuntimeMethodHandle methodHandle)
                {
                    return(importer.ImportMethod(MethodBase.GetMethodFromHandle(methodHandle)));
                }
                if (obj.GetType().FullName == "System.Reflection.Emit.GenericMethodInfo")
                {
                    var context =
                        FieldReader.ReadField <RuntimeTypeHandle>(obj, "m_context");
                    var res      = FieldReader.TryReadField <RuntimeMethodHandle>(obj, "m_method", out var m_method);
                    var m_handle = FieldReader.ReadField <RuntimeMethodHandle>(obj, "m_methodHandle");
                    var method   = MethodBase.GetMethodFromHandle(
                        res
                                ? m_method
                                : m_handle, context);
                    return(importer.ImportMethod(method));
                }

                if (obj.GetType().FullName == "System.Reflection.Emit.VarArgMethod")
                {
                    return(importer.ImportMethod(FieldReader.ReadField <MethodInfo>(obj, "m_method")));
                }
                break;

            case TableIndex.StandAloneSig:
                return(CallingConventionSignature.FromReader(
                           new BlobReadContext(readerContext),
                           new ByteArrayReader((byte[])tokens[(int)token.Rid])));

            case (TableIndex)112:
                return(tokens[(int)token.Rid] as string);
            }

            return(null);
        }
示例#5
0
 /// <summary>
 /// Creates a new instance of the <see cref="BlobReadContext"/> structure.
 /// </summary>
 /// <param name="readerContext">The original read context.</param>
 /// <param name="traversedTokens">A collection of traversed metadata tokens.</param>
 public BlobReadContext(ModuleReaderContext readerContext, IEnumerable <MetadataToken> traversedTokens)
 {
     ReaderContext   = readerContext;
     TraversedTokens = new HashSet <MetadataToken>(traversedTokens);
 }
示例#6
0
 /// <summary>
 /// Creates a new instance of the <see cref="BlobReadContext"/> structure.
 /// </summary>
 /// <param name="readerContext">The original read context.</param>
 public BlobReadContext(ModuleReaderContext readerContext)
     : this(readerContext, Enumerable.Empty <MetadataToken>())
 {
 }