/// <summary>
        /// Create a Dynamic Method Definition
        /// </summary>
        /// <param name="module">Target Module</param>
        /// <param name="dynamicMethodObj">Dynamic Method / Delegate / DynamicResolver</param>
        public DynamicMethodDefinition(ModuleDefinition module, object dynamicMethodObj) :
            base(new MetadataToken(TableIndex.Method, 0))
        {
            dynamicMethodObj = DynamicMethodHelper.ResolveDynamicResolver(dynamicMethodObj);
            var methodBase = FieldReader.ReadField <MethodBase>(dynamicMethodObj, "m_method");

            Module        = module;
            Name          = methodBase.Name;
            Attributes    = (MethodAttributes)methodBase.Attributes;
            Signature     = new ReferenceImporter(module).ImportMethodSignature(ResolveSig(methodBase, module));
            CilMethodBody = CilMethodBody.FromDynamicMethod(this, dynamicMethodObj);
        }
        /// <summary>
        /// Defines a new .NET module.
        /// </summary>
        /// <param name="name">The name of the module.</param>
        /// <param name="corLib">The reference to the common object runtime (COR) library that this module will use.</param>
        public ModuleDefinition(string name, AssemblyReference corLib)
            : this(new MetadataToken(TableIndex.Module, 0))
        {
            Name = name;

            var importer = new ReferenceImporter(this);

            corLib = (AssemblyReference)importer.ImportScope(corLib);

            CorLibTypeFactory = new CorLibTypeFactory(corLib);
            AssemblyReferences.Add(corLib);

            OriginalTargetRuntime = DetectTargetRuntime();
            MetadataResolver      = new DefaultMetadataResolver(CreateAssemblyResolver());

            TopLevelTypes.Add(new TypeDefinition(null, "<Module>", 0));
        }
        private MethodSignature ResolveSig(MethodBase methodBase, ModuleDefinition module)
        {
            var imp        = new ReferenceImporter(module);
            var returnType = methodBase is MethodInfo info
                ? imp.ImportTypeSignature(info.ReturnType)
                : module.CorLibTypeFactory.Void;

            var parameters = methodBase.GetParameters();

            var parameterTypes = new TypeSignature[parameters.Length];

            for (int i = 0; i < parameterTypes.Length; i++)
            {
                parameterTypes[i] = imp.ImportTypeSignature(parameters[i].ParameterType);
            }

            return(new MethodSignature(
                       methodBase.IsStatic ? 0 : CallingConventionAttributes.HasThis,
                       returnType, parameterTypes));
        }
Exemple #4
0
        private static void InterpretEHInfo(CilMethodBody methodBody, ReferenceImporter importer, object ehInfo)
        {
            for (int i = 0; i < FieldReader.ReadField <int>(ehInfo, "m_currentCatch"); i++)
            {
                // Get ExceptionHandlerInfo Field Values
                var endFinally   = FieldReader.ReadField <int>(ehInfo, "m_endFinally");
                var instructions = methodBody.Instructions;

                var endFinallyLabel = endFinally >= 0
                    ? instructions.GetByOffset(endFinally)?.CreateLabel() ?? new CilOffsetLabel(endFinally)
                    : null;

                int tryStart      = FieldReader.ReadField <int>(ehInfo, "m_startAddr");
                int tryEnd        = FieldReader.ReadField <int>(ehInfo, "m_endAddr");
                int handlerStart  = FieldReader.ReadField <int[]>(ehInfo, "m_catchAddr")[i];
                int handlerEnd    = FieldReader.ReadField <int[]>(ehInfo, "m_catchEndAddr")[i];
                var exceptionType = FieldReader.ReadField <Type[]>(ehInfo, "m_catchClass")[i];
                var handlerType   = (CilExceptionHandlerType)FieldReader.ReadField <int[]>(ehInfo, "m_type")[i];

                var endTryLabel = instructions.GetByOffset(tryEnd)?.CreateLabel() ?? new CilOffsetLabel(tryEnd);

                // Create the handler
                var handler = new CilExceptionHandler
                {
                    HandlerType   = handlerType,
                    TryStart      = instructions.GetLabel(tryStart),
                    TryEnd        = handlerType == CilExceptionHandlerType.Finally ? endFinallyLabel : endTryLabel,
                    FilterStart   = null,
                    HandlerStart  = instructions.GetLabel(handlerStart),
                    HandlerEnd    = instructions.GetLabel(handlerEnd),
                    ExceptionType = exceptionType != null?importer.ImportType(exceptionType) : null
                };

                methodBody.ExceptionHandlers.Add(handler);
            }
        }
Exemple #5
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();
            }
        }
Exemple #6
0
        public static void ReadReflectionExceptionHandlers(CilMethodBody methodBody,
                                                           IList <object> ehInfos, byte[] ehHeader, ReferenceImporter importer)
        {
            //Sample needed!
            if (ehHeader != null && ehHeader.Length > 4)
            {
                throw new NotImplementedException("Exception handlers from ehHeader not supported yet.");
            }

            if (ehInfos != null && ehInfos.Count > 0)
            {
                foreach (var ehInfo in ehInfos)
                {
                    InterpretEHInfo(methodBody, importer, ehInfo);
                }
            }
        }
Exemple #7
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);
        }
Exemple #8
0
        public static object ResolveOperandReflection(this CilMethodBody methodBody, CilInstruction instruction,
                                                      ICilOperandResolver resolver, List <object> Tokens, ReferenceImporter Importer)
        {
            switch (instruction.OpCode.OperandType)
            {
            case CilOperandType.InlineBrTarget:
            case CilOperandType.ShortInlineBrTarget:
                return(new CilInstructionLabel(
                           methodBody.Instructions.GetByOffset(((ICilLabel)instruction.Operand).Offset)));

            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                return(ReadToken(((MetadataToken)instruction.Operand).ToUInt32(), Tokens, Importer));

            case CilOperandType.InlineString:
                return(ReadToken(((MetadataToken)instruction.Operand).ToUInt32(), Tokens, Importer));

            case CilOperandType.InlineSwitch:
                var result = new List <ICilLabel>();
                var labels = (IEnumerable <ICilLabel>)instruction.Operand;
                foreach (var label in labels)
                {
                    var target = methodBody.Instructions.GetByOffset(label.Offset);
                    result.Add(target == null ? label : new CilInstructionLabel(target));
                }
                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();
            }
        }
Exemple #9
0
        public static void ReadReflectionExceptionHandlers(this CilMethodBody methodBody,
                                                           IList <object> ehInfos, byte[] ehHeader, ReferenceImporter importer)
        {
            if (ehHeader != null && ehHeader.Length > 4)
            {
                //Sample needed!
                throw new NotImplementedException("Exception Handlers From ehHeader Not Supported Yet.");
            }
            if (ehInfos != null && ehInfos.Count > 0)
            {
                foreach (var ehInfo in ehInfos)
                {
                    for (int i = 0; i < FieldReader.ReadField <int>(ehInfo, "m_currentCatch"); i++)
                    {
                        //Get ExceptionHandlerInfo Field Values
                        var endFinally      = FieldReader.ReadField <int>(ehInfo, "m_endFinally");
                        var endFinallyLabel = endFinally < 0
                            ? null
                            : methodBody.Instructions.GetByOffset(endFinally)?.CreateLabel() ??
                                              new CilOffsetLabel(endFinally);
                        var endTry      = FieldReader.ReadField <int>(ehInfo, "m_endAddr");
                        var endTryLabel = methodBody.Instructions.GetByOffset(endTry)?.CreateLabel() ??
                                          new CilOffsetLabel(endTry);
                        var handlerEnd    = FieldReader.ReadField <int[]>(ehInfo, "m_catchEndAddr")[i];
                        var exceptionType = FieldReader.ReadField <Type[]>(ehInfo, "m_catchClass")[i];
                        var handlerStart  = FieldReader.ReadField <int[]>(ehInfo, "m_catchAddr")[i];
                        var tryStart      = FieldReader.ReadField <int>(ehInfo, "m_startAddr");
                        var handlerType   = (CilExceptionHandlerType)FieldReader.ReadField <int[]>(ehInfo, "m_type")[i];

                        //Create the handler
                        var handler = new CilExceptionHandler
                        {
                            HandlerType = handlerType,
                            TryStart    = methodBody.Instructions.GetByOffset(tryStart)?.CreateLabel() ??
                                          new CilOffsetLabel(tryStart),
                            TryEnd       = handlerType == CilExceptionHandlerType.Finally ? endFinallyLabel : endTryLabel,
                            FilterStart  = null,
                            HandlerStart = methodBody.Instructions.GetByOffset(handlerStart)?.CreateLabel() ??
                                           new CilOffsetLabel(handlerStart),
                            HandlerEnd = methodBody.Instructions.GetByOffset(handlerEnd)?.CreateLabel() ??
                                         new CilOffsetLabel(handlerEnd),
                            ExceptionType = exceptionType != null?importer.ImportType(exceptionType) : null
                        };

                        methodBody.ExceptionHandlers.Add(handler);
                    }
                }
            }
        }