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