/// <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); }
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); } } } }
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); }
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); } }
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); }