/// <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);
        }
Example #2
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);
                    }
                }
            }
        }
Example #3
0
        public static object ResolveDynamicResolver(object dynamicMethodObj)
        {
            //Convert dynamicMethodObj to DynamicResolver
            if (dynamicMethodObj is Delegate del)
            {
                dynamicMethodObj = del.Method;
            }

            if (dynamicMethodObj is null)
            {
                throw new ArgumentNullException(nameof(dynamicMethodObj));
            }

            //We use GetType().FullName just to avoid the System.Reflection.Emit.LightWeight Dll
            if (dynamicMethodObj.GetType().FullName == "System.Reflection.Emit.DynamicMethod+RTDynamicMethod")
            {
                dynamicMethodObj = FieldReader.ReadField <object>(dynamicMethodObj, "m_owner");
            }

            if (dynamicMethodObj.GetType().FullName == "System.Reflection.Emit.DynamicMethod")
            {
                var resolver = FieldReader.ReadField <object>(dynamicMethodObj, "m_resolver");
                if (resolver != null)
                {
                    dynamicMethodObj = resolver;
                }
            }
            //Create Resolver if it does not exist.
            if (dynamicMethodObj.GetType().FullName == "System.Reflection.Emit.DynamicMethod")
            {
                var dynamicResolver = typeof(OpCode).Module.GetTypes()
                                      .First(t => t.Name == "DynamicResolver");

                var ilGenerator = dynamicMethodObj.GetType().GetRuntimeMethods().First(q => q.Name == "GetILGenerator")
                                  .Invoke(dynamicMethodObj, null);

                //Create instance of dynamicResolver
                dynamicMethodObj = Activator.CreateInstance(dynamicResolver, (BindingFlags)(-1), null, new[]
                {
                    ilGenerator
                }, null);
            }
            return(dynamicMethodObj);
        }
Example #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);
            }
        }
Example #5
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);
        }