예제 #1
0
        protected override ExceptionHandler readExceptionHandler()
        {
            var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadInt32());

            int tryOffset = reader.ReadInt32();
            eh.TryStart = getInstruction(tryOffset);
            eh.TryEnd = getInstructionOrNull(tryOffset + reader.ReadInt32());

            int handlerOffset = reader.ReadInt32();
            eh.HandlerStart = getInstruction(handlerOffset);
            eh.HandlerEnd = getInstructionOrNull(handlerOffset + reader.ReadInt32());

            switch (eh.HandlerType) {
            case ExceptionHandlerType.Catch:
                eh.CatchType = (TypeReference)module.LookupToken(reader.ReadInt32());
                break;

            case ExceptionHandlerType.Filter:
                eh.FilterStart = getInstruction(reader.ReadInt32());
                break;

            case ExceptionHandlerType.Finally:
            case ExceptionHandlerType.Fault:
            default:
                reader.ReadInt32();
                break;
            }

            return eh;
        }
        public void InitForm(MethodDefinition md, int ehIndex)
        {
            if (_method == md && _ehIndex == ehIndex) return;

            _method = md;
            _ehIndex = ehIndex;
            if (_ehIndex < 0)
            {
                _eh = new ExceptionHandler(ExceptionHandlerType.Catch);
                _eh.CatchType = _method.Module.Import(typeof(System.Exception));                
                InitTypes(ExceptionHandlerType.Catch);
            }
            else
            {
                _eh = _method.Body.ExceptionHandlers[_ehIndex];
                if(_eh.CatchType == null)
                    _eh.CatchType = _method.Module.Import(typeof(System.Exception));                
                InitTypes(_eh.HandlerType);
            }

            txtCatchType.Text = _eh.CatchType.FullName;

            InsUtils.InitInstructionsCombobox(cboTryStart, _method, _eh.TryStart, ref instructionsStr);
            InsUtils.InitInstructionsCombobox(cboTryEnd, _method, _eh.TryEnd, ref instructionsStr);

            InsUtils.InitInstructionsCombobox(cboHandlerStart, _method, _eh.HandlerStart, ref instructionsStr);
            InsUtils.InitInstructionsCombobox(cboHandlerEnd, _method, _eh.HandlerEnd, ref instructionsStr);

            InsUtils.InitInstructionsCombobox(cboFilterStart, _method, _eh.FilterStart, ref instructionsStr);
            //InsUtils.InitInstructionsCombobox(cboFilterEnd, _method, _eh.FilterEnd, ref instructionsStr);

        }
		private bool ThrowsGeneralException (ExceptionHandler exceptionHandler) 
		{
			for (Instruction currentInstruction = exceptionHandler.HandlerStart; currentInstruction != exceptionHandler.HandlerEnd; currentInstruction = currentInstruction.Next) {
				if (currentInstruction.OpCode.Code == Code.Rethrow)
					return true;
			}
			return false;
		}
예제 #4
0
 public ILBlock(ILBlockType type, int startOffset, int endOffset, Mono.Cecil.Cil.ExceptionHandler handler = null)
 {
     this.Children = new List <ILBlock>();
     base();
     this.Type             = type;
     this.StartOffset      = startOffset;
     this.EndOffset        = endOffset;
     this.ExceptionHandler = handler;
     return;
 }
예제 #5
0
 internal void Debug_RemoveExceptionHandler(ExceptionHandler eh, MethodBody mb)
 {
     var catchStart = mb.Instructions.IndexOf(eh.HandlerStart) - 1;
     var catchEnd = mb.Instructions.IndexOf(eh.HandlerEnd);
     for (var i = catchEnd - 1; i >= catchStart; i--)
     {
         mb.Instructions.RemoveAt(i);
     }
     mb.ExceptionHandlers.Remove(eh);
 }
 private void ComputeExceptionHandlerData(Dictionary<int, ExceptionHandlerData> datas, ExceptionHandler handler)
 {
     ExceptionHandlerData data;
     if (!datas.TryGetValue(handler.TryStart.Offset, out data))
     {
         data = new ExceptionHandlerData(this.ComputeRange(handler.TryStart, handler.TryEnd));
         datas.Add(handler.TryStart.Offset, data);
     }
     this.ComputeExceptionHandlerData(data, handler);
 }
예제 #7
0
        private static void ProcessMethod(AssemblyDefinition def, TypeDefinition type, MethodDefinition method)
        {
            if (!method.HasBody || method.Body.Instructions.Count < 1)
                return;

            var newHandler = new ExceptionHandler(ExceptionHandlerType.Catch);
            newHandler.TryStart = method.Body.Instructions[0];
            newHandler.TryEnd = method.Body.Instructions[method.Body.Instructions.Count - 1];
            // todo: add handler to body (create new static class to avoid code bloat) and register bounds with newHandler
            method.Body.ExceptionHandlers.Add(newHandler);
        }
예제 #8
0
 string getExceptionString(ExceptionHandler ex)
 {
     var sb = new StringBuilder();
     if (ex.TryStart != null)
         sb.Append(string.Format("TRY: {0}-{1}", getLabel(ex.TryStart), getLabel(ex.TryEnd)));
     if (ex.FilterStart != null)
         sb.Append(string.Format(", FILTER: {0}", getLabel(ex.FilterStart)));
     if (ex.HandlerStart != null)
         sb.Append(string.Format(", HANDLER: {0}-{1}", getLabel(ex.HandlerStart), getLabel(ex.HandlerEnd)));
     sb.Append(string.Format(", TYPE: {0}", ex.HandlerType));
     if (ex.CatchType != null)
         sb.Append(string.Format(", CATCH: {0}", ex.CatchType));
     return sb.ToString();
 }
예제 #9
0
파일: Formatter.cs 프로젝트: jbevain/cecil
        static string FormatHandlerType(ExceptionHandler handler)
        {
            var handler_type = handler.HandlerType;
            var type = handler_type.ToString ().ToLowerInvariant ();

            switch (handler_type) {
            case ExceptionHandlerType.Catch:
                return string.Format ("{0} {1}", type, handler.CatchType.FullName);
            case ExceptionHandlerType.Filter:
                throw new NotImplementedException ();
            default:
                return type;
            }
        }
        private void ComputeExceptionHandlerData(ExceptionHandlerData data, ExceptionHandler handler)
        {
            BlockRange range = this.ComputeRange(handler.HandlerStart, handler.HandlerEnd);
            switch (handler.HandlerType)
            {
                case ExceptionHandlerType.Catch:
                    data.Catches.Add(new CatchHandlerData(handler.CatchType, range));
                    break;

                case ExceptionHandlerType.Filter:
                    throw new NotImplementedException();

                case ExceptionHandlerType.Finally:
                    data.FinallyRange = range;
                    break;

                case ExceptionHandlerType.Fault:
                    data.FaultRange = range;
                    break;
            }
        }
예제 #11
0
        static void patchXamarinFormsCoreDll(string path, string typeName, string methodName)
        {
            var assembly = AssemblyDefinition.ReadAssembly (path);
            ModuleDefinition module = assembly.MainModule;
            TypeDefinition mainClass = module.GetType (typeName);
            MethodDefinition method = mainClass.Methods.Single (m => m.Name == methodName);

            var printPath = Path.GetFileName (path.Replace ("\\", "/").Replace ("../", ""));
            Console.WriteLine (string.Format ("Patch {0}.dll: {1}: {2}", printPath, methodName, method.Body.ExceptionHandlers.Count > 0 ? "already done" : "patch now"));
            if (method.Body.ExceptionHandlers.Count == 0) {

                var il = method.Body.GetILProcessor ();

                var write = il.Create (OpCodes.Call, module.Import (typeof(Console).GetMethod ("WriteLine", new [] { typeof(object) })));
                var ret = il.Create (OpCodes.Ret);
                var leave = il.Create (OpCodes.Leave, ret);

                il.InsertAfter (method.Body.Instructions.Last (), write);
                il.InsertAfter (write, leave);
                il.InsertAfter (leave, ret);

                var handler = new ExceptionHandler (ExceptionHandlerType.Catch) {
                    TryStart = method.Body.Instructions.First (),
                    TryEnd = write,
                    HandlerStart = write,
                    HandlerEnd = ret,
                    CatchType = module.Import (typeof(Exception)),
                };

                method.Body.ExceptionHandlers.Add (handler);

                string pathPatched = path + ".patched.dll";
                assembly.Write (pathPatched);
                File.Copy (pathPatched, path, true);
                File.Delete (pathPatched);
            }
        }
        private void _CopyMethodToDefinition()
        {
            MethodBase method     = OriginalMethod;
            Module     moduleFrom = method.Module;

            System.Reflection.MethodBody bodyFrom = method.GetMethodBody();
            byte[] data = bodyFrom?.GetILAsByteArray();
            if (data == null)
            {
                throw new NotSupportedException("Body-less method");
            }

            MethodDefinition def      = Definition;
            ModuleDefinition moduleTo = def.Module;

            Mono.Cecil.Cil.MethodBody bodyTo = def.Body;
            ILProcessor processor            = bodyTo.GetILProcessor();

            Type[] typeArguments = null;
            if (method.DeclaringType.IsGenericType)
            {
                typeArguments = method.DeclaringType.GetGenericArguments();
            }

            Type[] methodArguments = null;
            if (method.IsGenericMethod)
            {
                methodArguments = method.GetGenericArguments();
            }

            foreach (LocalVariableInfo info in bodyFrom.LocalVariables)
            {
                TypeReference type = moduleTo.ImportReference(info.LocalType);
                if (info.IsPinned)
                {
                    type = new PinnedType(type);
                }
                bodyTo.Variables.Add(new VariableDefinition(type));
            }

            using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) {
                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    int         offset = (int)reader.BaseStream.Position;
                    Instruction instr  = Instruction.Create(OpCodes.Nop);
                    byte        op     = reader.ReadByte();
                    instr.OpCode = op != 0xfe ? _CecilOpCodes1X[op] : _CecilOpCodes2X[reader.ReadByte()];
                    instr.Offset = offset;
                    ReadOperand(reader, instr);
                    bodyTo.Instructions.Add(instr);
                }
            }

            foreach (Instruction instr in bodyTo.Instructions)
            {
                switch (instr.OpCode.OperandType)
                {
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                    instr.Operand = GetInstruction((int)instr.Operand);
                    break;

                case OperandType.InlineSwitch:
                    int[]         offsets = (int[])instr.Operand;
                    Instruction[] targets = new Instruction[offsets.Length];
                    for (int i = 0; i < offsets.Length; i++)
                    {
                        targets[i] = GetInstruction(offsets[i]);
                    }
                    instr.Operand = targets;
                    break;
                }
            }

            foreach (ExceptionHandlingClause clause in bodyFrom.ExceptionHandlingClauses)
            {
                ExceptionHandler handler = new ExceptionHandler((ExceptionHandlerType)clause.Flags);
                bodyTo.ExceptionHandlers.Add(handler);

                handler.TryStart = GetInstruction(clause.TryOffset);
                handler.TryEnd   = GetInstruction(clause.TryOffset + clause.TryLength);

                handler.FilterStart  = handler.HandlerType != ExceptionHandlerType.Filter ? null : GetInstruction(clause.FilterOffset);
                handler.HandlerStart = GetInstruction(clause.HandlerOffset);
                handler.HandlerEnd   = GetInstruction(clause.HandlerOffset + clause.HandlerLength);

                handler.CatchType = handler.HandlerType != ExceptionHandlerType.Catch ? null : clause.CatchType == null ? null : moduleTo.ImportReference(clause.CatchType);
            }

            void ReadOperand(BinaryReader reader, Instruction instr)
            {
                int index, offs, length;

                switch (instr.OpCode.OperandType)
                {
                case OperandType.InlineNone:
                    instr.Operand = null;
                    break;

                case OperandType.InlineSwitch:
                    length = reader.ReadInt32();
                    offs   = (int)reader.BaseStream.Position + (4 * length);
                    int[] targets = new int[length];
                    for (int i = 0; i < length; i++)
                    {
                        targets[i] = reader.ReadInt32() + offs;
                    }
                    instr.Operand = targets;
                    break;

                case OperandType.ShortInlineBrTarget:
                    offs          = reader.ReadSByte();
                    instr.Operand = (int)reader.BaseStream.Position + offs;
                    break;

                case OperandType.InlineBrTarget:
                    offs          = reader.ReadInt32();
                    instr.Operand = (int)reader.BaseStream.Position + offs;
                    break;

                case OperandType.ShortInlineI:
                    instr.Operand = instr.OpCode == OpCodes.Ldc_I4_S ? reader.ReadSByte() : (object)reader.ReadByte();
                    break;

                case OperandType.InlineI:
                    instr.Operand = reader.ReadInt32();
                    break;

                case OperandType.ShortInlineR:
                    instr.Operand = reader.ReadSingle();
                    break;

                case OperandType.InlineR:
                    instr.Operand = reader.ReadDouble();
                    break;

                case OperandType.InlineI8:
                    instr.Operand = reader.ReadInt64();
                    break;

                case OperandType.InlineSig:
                    throw new NotSupportedException("Parsing CallSites at runtime currently not supported");

                case OperandType.InlineString:
                    instr.Operand = moduleFrom.ResolveString(reader.ReadInt32());
                    break;

                case OperandType.InlineTok:
                    switch (moduleFrom.ResolveMember(reader.ReadInt32(), typeArguments, methodArguments))
                    {
                    case Type i:
                        instr.Operand = moduleTo.ImportReference(i);
                        break;

                    case FieldInfo i:
                        instr.Operand = moduleTo.ImportReference(i);
                        break;

                    case MethodBase i:
                        instr.Operand = moduleTo.ImportReference(i);
                        break;
                    }
                    break;

                case OperandType.InlineType:
                    instr.Operand = moduleTo.ImportReference(moduleFrom.ResolveType(reader.ReadInt32(), typeArguments, methodArguments));
                    break;

                case OperandType.InlineMethod:
                    instr.Operand = moduleTo.ImportReference(moduleFrom.ResolveMethod(reader.ReadInt32(), typeArguments, methodArguments));
                    break;

                case OperandType.InlineField:
                    instr.Operand = moduleTo.ImportReference(moduleFrom.ResolveField(reader.ReadInt32(), typeArguments, methodArguments));
                    break;

                case OperandType.ShortInlineVar:
                case OperandType.InlineVar:
                    index         = instr.OpCode.OperandType == OperandType.ShortInlineVar ? reader.ReadByte() : reader.ReadInt16();
                    instr.Operand = bodyTo.Variables[index];
                    break;

                case OperandType.InlineArg:
                case OperandType.ShortInlineArg:
                    index         = instr.OpCode.OperandType == OperandType.ShortInlineArg ? reader.ReadByte() : reader.ReadInt16();
                    instr.Operand = def.Parameters[index];
                    break;

                case OperandType.InlinePhi:     // No opcode seems to use this
                default:
                    throw new NotSupportedException($"Unsupported opcode ${instr.OpCode.Name}");
                }
            }

            Instruction GetInstruction(int offset)
            {
                int last = bodyTo.Instructions.Count - 1;

                if (offset < 0 || offset > bodyTo.Instructions[last].Offset)
                {
                    return(null);
                }

                int min = 0;
                int max = last;

                while (min <= max)
                {
                    int         mid   = min + ((max - min) / 2);
                    Instruction instr = bodyTo.Instructions[mid];

                    if (offset == instr.Offset)
                    {
                        return(instr);
                    }

                    if (offset < instr.Offset)
                    {
                        max = mid - 1;
                    }
                    else
                    {
                        min = mid + 1;
                    }
                }

                return(null);
            }
        }
    void InjectUsingStatement(MethodBody methodBody, Instruction bodyStart,
      OpCode loadLocation, Instruction handlerEnd, Instruction leave)
    {
      var startFinally = Instruction.Create(loadLocation);
      var endFinally = Instruction.Create(OpCodes.Endfinally);

      methodBody.Instructions.Add(leave);
      methodBody.Instructions.Add(startFinally);
      methodBody.Instructions.Add(Instruction.Create(OpCodes.Brfalse_S, endFinally));

      methodBody.Instructions.Add(Instruction.Create(loadLocation));
      methodBody.Instructions.Add(Instruction.Create(OpCodes.Callvirt,
        ModuleDefinition.ImportReference(typeof(IDisposable).GetMethod("Dispose"))));

      methodBody.Instructions.Add(endFinally);

      var handler = new ExceptionHandler(ExceptionHandlerType.Finally)
      {
        TryStart = bodyStart,
        TryEnd = startFinally,
        HandlerStart = startFinally,
        HandlerEnd = handlerEnd
      };

      methodBody.ExceptionHandlers.Add(handler);
    }
예제 #14
0
 private void CopyExceptionHandlers(ExceptionHandler sourceHandler, Dictionary<Instruction, Instruction> instMap, MethodBody destBody)
 {
     var destHandler = new ExceptionHandler(sourceHandler.HandlerType)
     {
         CatchType = sourceHandler.CatchType != null ? Import(sourceHandler.CatchType) : null,
         FilterStart = MapInstructionSafe(instMap, sourceHandler.FilterStart),
         HandlerStart = MapInstructionSafe(instMap, sourceHandler.HandlerStart),
         HandlerEnd = MapInstructionSafe(instMap, sourceHandler.HandlerEnd),
         TryStart = MapInstructionSafe(instMap, sourceHandler.TryStart),
         TryEnd = MapInstructionSafe(instMap, sourceHandler.TryEnd)
     };
     destBody.ExceptionHandlers.Add(destHandler);
 }
예제 #15
0
        internal static void EncapsulateMethodBodyWithTryFinallyBlock(this ILProcessor ilProcessor,
                                                                      Instruction firstInstruction, Action <ILProcessor, Instruction> insertBeforReturn)
        {
            var body = ilProcessor.Body;

            if (body.Method.IsConstructor && !body.Method.IsStatic)
            {
                var ctor = GetFirstConstructorInstruction(body);
                if (ctor != null)
                {
                    if (body.Instructions.IndexOf(ctor) > 2)
                    {
                        var lastInstruction      = body.Instructions.Last();
                        var firtLDarg0BeforeCtor = ctor.GetFirstPreviousLdarg_0();
                        if (firstInstruction != firtLDarg0BeforeCtor)
                        {
                            EncapsulateWithTryCatch(ilProcessor, firstInstruction, firtLDarg0BeforeCtor);
                        }

                        if (ctor.GetFirstNotNopInstruction().Equals(lastInstruction))
                        {
                            insertBeforReturn(ilProcessor, lastInstruction);
                            return;
                        }
                    }

                    if (firstInstruction.Next.OpCode != OpCodes.Nop)
                    {
                        firstInstruction = Instruction.Create(OpCodes.Nop);
                        ilProcessor.InsertAfter(ctor, firstInstruction);
                    }
                }
            }

            var returnStart = ilProcessor.FixReturns();

            var beforeReturn = Instruction.Create(OpCodes.Endfinally);

            ilProcessor.InsertBefore(returnStart, beforeReturn);

            if (body.Instructions.First().Equals(firstInstruction))
            {
                Instruction tryStart = Instruction.Create(OpCodes.Nop);
                ilProcessor.InsertBefore(firstInstruction, tryStart);
            }

            Instruction finallyStart = Instruction.Create(OpCodes.Nop);

            ilProcessor.InsertBefore(beforeReturn, finallyStart);
            insertBeforReturn(ilProcessor, beforeReturn);

            var handler = new ExceptionHandler(ExceptionHandlerType.Finally)
            {
                TryStart     = firstInstruction,
                TryEnd       = finallyStart,
                HandlerStart = finallyStart,
                HandlerEnd   = returnStart,
            };

            body.ExceptionHandlers.Add(handler);
        }
		void ReadSection (MethodBody body, BinaryReader br)
		{
			br.BaseStream.Position += 3;
			br.BaseStream.Position &= ~3;

			byte flags = br.ReadByte ();
			if ((flags & (byte) MethodDataSection.FatFormat) == 0) {
				int length = br.ReadByte () / 12;
				br.ReadBytes (2);

				for (int i = 0; i < length; i++) {
					ExceptionHandler eh = new ExceptionHandler (
						(ExceptionHandlerType) (br.ReadInt16 () & 0x7));
					eh.TryStart = GetInstruction (body, Convert.ToInt32 (br.ReadInt16 ()));
					eh.TryEnd = GetInstruction (body, eh.TryStart.Offset + Convert.ToInt32 (br.ReadByte ()));
					eh.HandlerStart = GetInstruction (body, Convert.ToInt32 (br.ReadInt16 ()));
					eh.HandlerEnd = GetInstruction (body, eh.HandlerStart.Offset + Convert.ToInt32 (br.ReadByte ()));
					ReadExceptionHandlerEnd (eh, br, body);
					body.ExceptionHandlers.Add (eh);
				}
			} else {
				br.BaseStream.Position--;
				int length = (br.ReadInt32 () >> 8) / 24;
				if ((flags & (int) MethodDataSection.EHTable) == 0)
					br.ReadBytes (length * 24);
				for (int i = 0; i < length; i++) {
					ExceptionHandler eh = new ExceptionHandler (
						(ExceptionHandlerType) (br.ReadInt32 () & 0x7));
					eh.TryStart = GetInstruction (body, br.ReadInt32 ());
					eh.TryEnd = GetInstruction (body, eh.TryStart.Offset + br.ReadInt32 ());
					eh.HandlerStart = GetInstruction (body, br.ReadInt32 ());
					eh.HandlerEnd = GetInstruction (body, eh.HandlerStart.Offset + br.ReadInt32 ());
					ReadExceptionHandlerEnd (eh, br, body);
					body.ExceptionHandlers.Add (eh);
				}
			}

			if ((flags & (byte) MethodDataSection.MoreSects) != 0)
				ReadSection (body, br);
		}
예제 #17
0
        // inline ?
        void ReadExceptionHandlers(int count, Func<int> read_entry, Func<int> read_length)
        {
            for (int i = 0; i < count; i++) {
                var handler = new ExceptionHandler (
                    (ExceptionHandlerType) (read_entry () & 0x7));

                handler.TryStart = GetInstruction (read_entry ());
                handler.TryEnd = GetInstruction (GetInstructionOffset (handler.TryStart) + read_length ());

                handler.HandlerStart = GetInstruction (read_entry ());
                handler.HandlerEnd = GetInstruction (GetInstructionOffset (handler.HandlerStart) + read_length ());

                ReadExceptionHandlerSpecific (handler);

                if (handler.TryStart != null && handler.HandlerStart != null)
                    this.body.ExceptionHandlers.Add (handler);
            }
        }
예제 #18
0
		void WriteExceptionHandlerSpecific (ExceptionHandler handler)
		{
			switch (handler.HandlerType) {
			case ExceptionHandlerType.Catch:
				WriteMetadataToken (metadata.LookupToken (handler.CatchType));
				break;
			case ExceptionHandlerType.Filter:
				WriteInt32 (handler.FilterStart.Offset);
				break;
			default:
				WriteInt32 (0);
				break;
			}
		}
예제 #19
0
		protected ExceptionHandler CreateExceptionHandler()
		{
			try
			{
				var eh = new ExceptionHandler((ExceptionHandlerType) Types.SelectedItem);
				if (eh.HandlerType == ExceptionHandlerType.Filter)
					eh.FilterStart = FilterStart.SelectedOperand;

				eh.TryStart = TryStart.SelectedOperand;
				eh.TryEnd = TryEnd.SelectedOperand;
				eh.HandlerStart = HandlerStart.SelectedOperand;
				eh.HandlerEnd = HandlerEnd.SelectedOperand;

				if (CatchType.SelectedOperand != null)
					eh.CatchType = MethodDefinition.DeclaringType.Module.Import(CatchType.SelectedOperand);

				return eh;
			}
			catch (Exception)
			{
				MessageBox.Show(@"Reflexil is unable to create this exception handler");
				return null;
			}
		}
예제 #20
0
 void addExceptionHandler(ExceptionHandler handler)
 {
     if (handler == null)
         return;
     pushMember(handler.CatchType);
 }
예제 #21
0
        public void Inject()
        {
            if (!IsInjected)
            {
                string logEndpoint = ConfigurationManager.AppSettings.AllKeys.Contains("Endpoint") ? ConfigurationManager.AppSettings["Endpoint"].Trim() : string.Empty;
                string logName     = ConfigurationManager.AppSettings.AllKeys.Contains("LogName") ? ConfigurationManager.AppSettings["LogName"].Trim() : string.Empty;
                string environment = ConfigurationManager.AppSettings.AllKeys.Contains("Environment") ? ConfigurationManager.AppSettings["Environment"].Trim() : string.Empty;
                string ipaddress   = "127.0.0.1";
                //string applicationName,string logEndpoint,string logName,string environment,string ipaddress

                //DynamicMethod dynamicMethod=new DynamicMethod();


                var il     = _methodDefinition.Body.GetILProcessor();
                var module = _methodDefinition.Module;

                var sourceInstructions   = _methodDefinition.Body.Instructions.ToList();
                int sourceInstCount      = sourceInstructions.Count;
                var copyInstructionCount = _methodDefinition.ReturnType.FullName == typeof(void).FullName?sourceInstCount - 1:sourceInstCount - 2;
                var destInstructions     = new List <Instruction>();

                destInstructions.Add(il.Create(OpCodes.Nop));
                destInstructions.Add(il.Create(OpCodes.Nop));

                for (int i = 0; i < copyInstructionCount; i++)
                {
                    if (sourceInstructions[i].OpCode != OpCodes.Br_S)
                    {
                        destInstructions.Add(sourceInstructions[i]);
                    }
                }

                var startCatch = destInstructions.Count;
                //destInstructions.Add(il.Create(OpCodes.Leave_S, destInstructions[startCatch - 1]));
                destInstructions.Add(il.Create(OpCodes.Pop));
                destInstructions.Add(il.Create(OpCodes.Nop));

                if (_methodDefinition.ReturnType.FullName != typeof(void).FullName)
                {
                    var defval = il.Create(OpCodes.Ldnull);
                    var stloc  = il.Create(OpCodes.Stloc_0);
                    //var leaves = il.Create(OpCodes.Leave_S, stloc);

                    destInstructions.Add(defval);
                    destInstructions.Add(stloc);
                }
                else
                {
                    destInstructions.Add(il.Create(OpCodes.Nop));
                }
                //destInstructions.Add(leaves);

                int endCatchPos = destInstructions.Count;

                destInstructions.Add(il.Create(OpCodes.Nop));
                if (_methodDefinition.ReturnType.FullName != typeof(void).FullName)
                {
                    destInstructions.Add(sourceInstructions[sourceInstCount - 2]);
                }

                destInstructions.Add(sourceInstructions[sourceInstCount - 1]);
                var leaveInst = destInstructions[endCatchPos];

                destInstructions.Insert(startCatch, il.Create(OpCodes.Leave_S, leaveInst));
                destInstructions.Insert(endCatchPos + 1, il.Create(OpCodes.Leave_S, leaveInst));


                //var write = il.Create(OpCodes.Call, module.Import(typeof(ExceptionExtension).GetMethod("WriteToLog")));


                //il.InsertAfter(_methodDefinition.Body.Instructions.Last(), firstParam);

                //il.InsertAfter(firstParam, secondParam);
                //il.InsertAfter(secondParam, thirdParam);
                //il.InsertAfter(thirdParam, forthParam);
                //il.InsertAfter(forthParam, fifthParam);
                //il.InsertAfter(fifthParam, write);

                //il.InsertAfter(write, leave);


                var handler = new Mono.Cecil.Cil.ExceptionHandler(ExceptionHandlerType.Catch)
                {
                    TryStart     = destInstructions[1],
                    TryEnd       = destInstructions[startCatch + 1],
                    HandlerStart = destInstructions[startCatch + 1],
                    HandlerEnd   = destInstructions[endCatchPos + 2],
                    CatchType    = module.Import(typeof(Exception)),
                };

                _methodDefinition.Body.Instructions.Clear();

                foreach (var destInstruction in destInstructions)
                {
                    _methodDefinition.Body.Instructions.Add(destInstruction);
                }


                _methodDefinition.Body.ExceptionHandlers.Add(handler);
            }
        }
        internal static MethodBody Clone(MethodBody body, MethodDefinition parent, ImportContext context)
        {
            MethodBody nb = new MethodBody(parent);

            nb.MaxStack   = body.MaxStack;
            nb.InitLocals = body.InitLocals;
            nb.CodeSize   = body.CodeSize;

            CilWorker worker = nb.CilWorker;

            if (body.HasVariables)
            {
                foreach (VariableDefinition var in body.Variables)
                {
                    nb.Variables.Add(new VariableDefinition(
                                         var.Name, var.Index, parent,
                                         context.Import(var.VariableType)));
                }
            }

            foreach (Instruction instr in body.Instructions)
            {
                Instruction ni = new Instruction(instr.OpCode);

                switch (instr.OpCode.OperandType)
                {
                case OperandType.InlineParam:
                case OperandType.ShortInlineParam:
                    if (instr.Operand == body.Method.This)
                    {
                        ni.Operand = nb.Method.This;
                    }
                    else
                    {
                        int param = body.Method.Parameters.IndexOf((ParameterDefinition)instr.Operand);
                        ni.Operand = parent.Parameters [param];
                    }
                    break;

                case OperandType.InlineVar:
                case OperandType.ShortInlineVar:
                    int var = body.Variables.IndexOf((VariableDefinition)instr.Operand);
                    ni.Operand = nb.Variables [var];
                    break;

                case OperandType.InlineField:
                    ni.Operand = context.Import((FieldReference)instr.Operand);
                    break;

                case OperandType.InlineMethod:
                    ni.Operand = context.Import((MethodReference)instr.Operand);
                    break;

                case OperandType.InlineType:
                    ni.Operand = context.Import((TypeReference)instr.Operand);
                    break;

                case OperandType.InlineTok:
                    if (instr.Operand is TypeReference)
                    {
                        ni.Operand = context.Import((TypeReference)instr.Operand);
                    }
                    else if (instr.Operand is FieldReference)
                    {
                        ni.Operand = context.Import((FieldReference)instr.Operand);
                    }
                    else if (instr.Operand is MethodReference)
                    {
                        ni.Operand = context.Import((MethodReference)instr.Operand);
                    }
                    break;

                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                case OperandType.InlineSwitch:
                    break;

                default:
                    ni.Operand = instr.Operand;
                    break;
                }

                worker.Append(ni);
            }

            for (int i = 0; i < body.Instructions.Count; i++)
            {
                Instruction instr = nb.Instructions [i];
                Instruction oldi  = body.Instructions [i];

                if (instr.OpCode.OperandType == OperandType.InlineSwitch)
                {
                    Instruction [] olds    = (Instruction [])oldi.Operand;
                    Instruction [] targets = new Instruction [olds.Length];

                    for (int j = 0; j < targets.Length; j++)
                    {
                        targets [j] = GetInstruction(body, nb, olds [j]);
                    }

                    instr.Operand = targets;
                }
                else if (instr.OpCode.OperandType == OperandType.ShortInlineBrTarget || instr.OpCode.OperandType == OperandType.InlineBrTarget)
                {
                    instr.Operand = GetInstruction(body, nb, (Instruction)oldi.Operand);
                }
            }

            if (!body.HasExceptionHandlers)
            {
                return(nb);
            }

            foreach (ExceptionHandler eh in body.ExceptionHandlers)
            {
                ExceptionHandler neh = new ExceptionHandler(eh.Type);
                neh.TryStart     = GetInstruction(body, nb, eh.TryStart);
                neh.TryEnd       = GetInstruction(body, nb, eh.TryEnd);
                neh.HandlerStart = GetInstruction(body, nb, eh.HandlerStart);
                neh.HandlerEnd   = GetInstruction(body, nb, eh.HandlerEnd);

                switch (eh.Type)
                {
                case ExceptionHandlerType.Catch:
                    neh.CatchType = context.Import(eh.CatchType);
                    break;

                case ExceptionHandlerType.Filter:
                    neh.FilterStart = GetInstruction(body, nb, eh.FilterStart);
                    neh.FilterEnd   = GetInstruction(body, nb, eh.FilterEnd);
                    break;
                }

                nb.ExceptionHandlers.Add(neh);
            }

            return(nb);
        }
예제 #23
0
파일: Program.cs 프로젝트: RockyTV/opentk
        static void EmitDebugEpilogue(MethodDefinition wrapper, ILProcessor il, DebugVariables vars)
        {
            if (vars != null)
            {
                var disposeMethod = vars.ErrorHelperType.Methods.First(
                    method => method.Name == "Dispose");

                // Store then reload the result from the call
                var resultLocal = new VariableDefinition(wrapper.ReturnType);
                if (resultLocal.VariableType.FullName != Program.TypeVoid.FullName)
                {
                    il.Body.Variables.Add(resultLocal);
                    il.Emit(OpCodes.Stloc, resultLocal);
                }

                // Special case End to turn on error checking.
                if (il.Body.Method.Name == "End")
                {
                    il.Emit(OpCodes.Call, vars.Get_CurrentContext);
                    il.Emit(OpCodes.Ldc_I4_1);
                    il.Emit(OpCodes.Conv_I1);
                    il.Emit(OpCodes.Call, vars.Set_ErrorChecking);
                }

                // We need a NOP to set up the finally handler range correctly.
                var nopInstruction = Instruction.Create(OpCodes.Nop);
                var loadInstruction = Instruction.Create(OpCodes.Ldloca, vars.ErrorHelperLocal);
                var disposeInstruction = Instruction.Create(OpCodes.Call, disposeMethod);
                var endFinallyInstruction = Instruction.Create(OpCodes.Endfinally);
                var endTryInstruction = Instruction.Create(OpCodes.Leave, nopInstruction);

                il.Append(endTryInstruction);
                il.Append(loadInstruction);
                il.Append(disposeInstruction);
                il.Append(endFinallyInstruction);
                il.Append(nopInstruction);

                var finallyHandler = new ExceptionHandler(ExceptionHandlerType.Finally);
                finallyHandler.TryStart = vars.BeginTry;
                finallyHandler.TryEnd = loadInstruction;
                finallyHandler.HandlerStart = loadInstruction;
                finallyHandler.HandlerEnd = nopInstruction;

                il.Body.ExceptionHandlers.Add(finallyHandler);

                if (resultLocal.VariableType.FullName != Program.TypeVoid.FullName)
                {
                    il.Emit(OpCodes.Ldloc, resultLocal);
                }
            }
        }
예제 #24
0
파일: Program.cs 프로젝트: RockyTV/opentk
        static void EmitStringBuilderEpilogue(MethodDefinition wrapper, MethodDefinition native, ParameterDefinition parameter, MethodBody body, ILProcessor il)
        {
            var p = parameter.ParameterType;
            if (p.Name == "StringBuilder")
            {
                // void GetShaderInfoLog(..., StringBuilder foo)
                // try {
                //  foo_sb_ptr = Marshal.AllocHGlobal(sb.Capacity + 1); -- already emitted
                //  glGetShaderInfoLog(..., foo_sb_ptr); -- already emitted
                //  MarshalPtrToStringBuilder(foo_sb_ptr, foo);
                // }
                // finally {
                //  Marshal.FreeHGlobal(foo_sb_ptr);
                // }

                // Make sure we have imported BindingsBase::MasrhalPtrToStringBuilder and Marshal::FreeHGlobal
                var ptr_to_sb = wrapper.Module.Import(TypeBindingsBase.Methods.First(m => m.Name == "MarshalPtrToStringBuilder"));
                var free_hglobal = wrapper.Module.Import(TypeMarshal.Methods.First(m => m.Name == "FreeHGlobal"));

                var block = new ExceptionHandler(ExceptionHandlerType.Finally);
                block.TryStart = body.Instructions[0];

                var variable_name = parameter.Name + " _sb_ptr";
                var v = body.Variables.First(m => m.Name == variable_name);
                il.Emit(OpCodes.Ldloc, v.Index);
                il.Emit(OpCodes.Ldarg, parameter.Index);
                il.Emit(OpCodes.Call, ptr_to_sb);

                block.TryEnd = body.Instructions.Last();
                block.HandlerStart = body.Instructions.Last();

                il.Emit(OpCodes.Ldloc, v.Index);
                il.Emit(OpCodes.Call, free_hglobal);

                block.HandlerEnd = body.Instructions.Last();
            }
        }
예제 #25
0
        // FIXME: Clean up.. factor out functionality into smaller, better pieces? Remove some generated nops?
        protected virtual void CreateCoroutine()
        {
            // create coroutine method
            coroutine = new MethodDefinition ("Resume", Mono.Cecil.MethodAttributes.HideBySig | Mono.Cecil.MethodAttributes.Public |
                                                  Mono.Cecil.MethodAttributes.Virtual, module.TypeSystem.Void);

            var il = coroutine.Body.GetILProcessor ();

            // process the method we want to transform and...
            //  1) Replace all Ldarg, Starg opcodes with Ldfld, Stfld (argsFields)
            //  2) Replace all Ldloc, Stloc opcodes with Ldfld, Stfld (localsFields)
            //  3) Before Ret, add Future<T>.Value = ...; or Future.Status = FutureStatus.Fulfilled;
            //  4) Replace calls to Future.Wait or Thread.Yield with continuation
            //  5) Remove calls to Future<T>.op_Implicit preceeding Ret
            Visit (method);

            // remap the jumps- pass 1 (required because exception handling extracts some of these)
            MapAllInstructions (method.Body);

            // the whole body of the method must be an exception handler
            var exceptionType = module.Import (getException.ReturnType);
            var exception = new VariableDefinition (exceptionType);
            coroutine.Body.Variables.Add (exception);

            VariableDefinition skipFinallyBlocks = null;

            // add exception handlers
            int i = 0;
            var catchBlocks = new List<IList<Instruction>> ();
            var finallyBlocks = new List<IList<Instruction>> ();
            MethodDefinition finallyMethod = null;
            foreach (var eh in method.Body.ExceptionHandlers.OrderBy (e => e.TryStart.Offset).OrderBy (e => e.TryEnd.Offset)) {

                // set the next ePC to this handler block
                // we can get away with just setting an exception block selector (epc)
                //  at the beginning of the block because jumps into the middle of a try block are not allowed
                //  (see ECMA-335 12.4.2.8.2.7)
                InsertBefore (eh.TryStart, new Instruction [] {
                    il.Create (OpCodes.Ldarg_0),
                    il.Create (OpCodes.Ldarg_0),
                    il.Create (OpCodes.Ldfld, epcFld),
                    il.Create (OpCodes.Ldc_I8, 1L << i),
                    il.Create (OpCodes.Or),
                    il.Create (OpCodes.Stfld, epcFld)
                });

                // clear the bit for this handler at end of try block
                // This awkward bit of code below is necessary because one handler's end can be another's start
                var clearEpc = new List<Instruction> () {
                    il.Create (OpCodes.Ldarg_0),
                    il.Create (OpCodes.Ldarg_0),
                    il.Create (OpCodes.Ldfld, epcFld),
                    il.Create (OpCodes.Ldc_I8, ~(1L << i)),
                    il.Create (OpCodes.And),
                    il.Create (OpCodes.Stfld, epcFld)
                };

                if (eh.HandlerType == ExceptionHandlerType.Finally) {
                    finallyMethod = new MethodDefinition ("$finally" + i, Mono.Cecil.MethodAttributes.Private, module.TypeSystem.Void);
                    coroutineType.Methods.Add (finallyMethod);
                    clearEpc.Add (il.Create (OpCodes.Ldarg_0));
                    clearEpc.Add (il.Create (OpCodes.Call, finallyMethod));
                }
                InstructionMap.Insert (InstructionMap.IndexOfKey (eh.HandlerEnd), clearEpc [0], clearEpc);

                // have to fixup leaves from catch blocks to unset our epcs for handlers that are all in the same spot
                var lastHandler = method.Body.ExceptionHandlers.OrderBy (h => h.HandlerStart.Offset).LastOrDefault ((l, c) => l.HandlerEnd == c.HandlerStart, eh);
                var subsequent = lastHandler.HandlerEnd;//InstructionMap [lastHandler.HandlerEnd].FirstOrDefault ();
                //if (subsequent != null)
                MapInstructions (subsequent, clearEpc [0]);

                // extract the handler block
                var handlerBody = ExtractInstructionRange (eh.HandlerStart, clearEpc [0]);
                var block = new List<Instruction> ();

                //fixup common issue
                // FIXME: this solution is a kludge
                if (handlerBody [0].OpCode == OpCodes.Stfld) {
                    handlerBody.Insert (0, il.Create (OpCodes.Stloc, exception));
                    handlerBody.Insert (1, il.Create (OpCodes.Ldarg_0));
                    handlerBody.Insert (2, il.Create (OpCodes.Ldloc, exception));
                    if (eh.CatchType.FullName != "System.Exception")
                        handlerBody.Insert (3, il.Create (OpCodes.Isinst, eh.CatchType));
                }

                var skip = il.Create (OpCodes.Nop);

                // check if our epc bit is set
                block.Add (il.Create (OpCodes.Ldarg_0));
                block.Add (il.Create (OpCodes.Ldfld, epcFld));
                block.Add (il.Create (OpCodes.Ldc_I8, 1L << i));
                block.Add (il.Create (OpCodes.And));
                block.Add (il.Create (OpCodes.Brfalse, skip));

                // clear epc bits as we go
                block.Add (il.Create (OpCodes.Ldarg_0));
                block.Add (il.Create (OpCodes.Ldarg_0));
                block.Add (il.Create (OpCodes.Ldfld, epcFld));
                block.Add (il.Create (OpCodes.Ldc_I8, ~(1L << i)));
                block.Add (il.Create (OpCodes.And));
                block.Add (il.Create (OpCodes.Stfld, epcFld));

                switch (eh.HandlerType) {

                case ExceptionHandlerType.Catch:

                    // guard by exception type (only if it's more specifc than System.Exception)
                    if (eh.CatchType.FullName != "System.Exception") {
                        block.Add (il.Create (OpCodes.Dup));
                        block.Add (il.Create (OpCodes.Isinst, eh.CatchType));
                        block.Add (il.Create (OpCodes.Brfalse, skip));
                        block.Add (il.Create (OpCodes.Isinst, eh.CatchType));
                    }

                    block.AddRange (handlerBody);

                    block.Add (skip);
                    catchBlocks.Add (block);
                    break;

                //FIXME: Finally blocks need to be surrounded in try..catch!
                case ExceptionHandlerType.Finally:

                    if (skipFinallyBlocks == null) {
                        skipFinallyBlocks = new VariableDefinition (module.TypeSystem.Boolean);
                        coroutine.Body.Variables.Add (skipFinallyBlocks);
                    }

                    // replace the endfinally with a ret (patching jumps of course :)
                    subsequent = il.Create (OpCodes.Ret);
                    handlerBody.RedirectJumps (handlerBody [handlerBody.Count - 1], subsequent);
                    handlerBody.RemoveAt (handlerBody.Count - 1);
                    handlerBody.Add (subsequent);

                    // finalize our finally method
                    var fil = finallyMethod.Body.GetILProcessor ();
                    foreach (var inst in handlerBody) {
                        fil.Append (inst);
                        if (inst.OpCode == OpCodes.Dup && dupLoc != null)
                            finallyMethod.Body.Variables.Add (dupLoc);
                    }

                    block.Add (il.Create (OpCodes.Ldarg_0));
                    block.Add (il.Create (OpCodes.Call, finallyMethod));
                    block.Add (skip);
                    finallyBlocks.Add (block);
                    break;

                default:
                    throw new NotImplementedException ("Exception handler blocks of type: " + eh.HandlerType.ToString ());
                }

                method.Body.ExceptionHandlers.Remove (eh);
                i++;
            }

            // add state machine
            var firstInst = il.Create (OpCodes.Ldarg_0);
            var loadPC = il.Create (OpCodes.Ldfld, pcFld);

            il.Append (firstInst);
            il.Append (loadPC);

            // add continuation jump table
            var jumpTable = new Mono.Cecil.Cil.Instruction [continuations.Count + 1];
            jumpTable [0] = InstructionMap.First (kv => kv.Value.Count != 0).Value [0];

            // add mapped new instructions
            foreach (var ci in InstructionMap) {
                foreach (var inst in ci.Value)
                    il.Append (inst);
            }

            // create global catch/fault blocks
            var ehFirst = il.Create (OpCodes.Nop);
            il.Append (ehFirst);

            foreach (var block in catchBlocks)
                foreach (var inst in block)
                    il.Append (inst);

            il.Emit (OpCodes.Stloc, exception);
            il.Emit (OpCodes.Ldarg_0);
            il.Emit (OpCodes.Ldloc, exception);
            il.Emit (OpCodes.Callvirt, module.Import (setException));

            // if method is void-returning, we gotta throw it
            if (method.ReturnType.IsVoid ()) {
                il.Emit (OpCodes.Ldloc, exception);
                il.Emit (OpCodes.Throw);

            }

            il.Emit (OpCodes.Leave, ret);

            var globalEh = new ExceptionHandler (ExceptionHandlerType.Catch) {
                CatchType = exceptionType,
                TryStart = firstInst,
                TryEnd = ehFirst,
                HandlerStart = ehFirst
            };
            coroutine.Body.ExceptionHandlers.Add (globalEh);

            var catchEhFirst = il.Create (OpCodes.Stloc, exception);

            var catchEh = new ExceptionHandler (ExceptionHandlerType.Catch) {
                CatchType = exceptionType,
                TryStart = ehFirst,
                TryEnd = catchEhFirst,
                HandlerStart = catchEhFirst,
            };
            coroutine.Body.ExceptionHandlers.Add (catchEh);

            il.Append (catchEhFirst);
            il.Emit (OpCodes.Ldarg_0);
            il.Emit (OpCodes.Ldloc, exception);
            il.Emit (OpCodes.Callvirt, module.Import (setException));

            // if method is void-returning, we gotta throw it
            if (method.ReturnType.IsVoid ()) {
                il.Emit (OpCodes.Ldloc, exception);
                il.Emit (OpCodes.Throw);

            }

            il.Emit (OpCodes.Leave, ret);

            if (finallyBlocks.Any ()) {

                ehFirst = il.Create (OpCodes.Ldloc, skipFinallyBlocks);
                il.Append (ehFirst);
                globalEh.HandlerEnd = ehFirst;
                catchEh.HandlerEnd = ehFirst;

                var endFinally = il.Create (OpCodes.Endfinally);
                il.Emit (OpCodes.Brtrue, endFinally);

                foreach (var block in finallyBlocks)
                    foreach (var inst in block)
                        il.Append (inst);

                il.Append (endFinally);
                globalEh = new ExceptionHandler (ExceptionHandlerType.Finally) {
                    TryStart = firstInst,
                    TryEnd = ehFirst,
                    HandlerStart = ehFirst
                };
                coroutine.Body.ExceptionHandlers.Add (globalEh);
            } else {
                catchEh.HandlerEnd = ret;
            }

            globalEh.HandlerEnd = ret;
            il.Append (ret);

            // add continuations
            i = 1;
            foreach (var continuation in continuations) {
                // set the next PC before the jump
                var inst = il.Create (OpCodes.Ldarg_0);

                // FIXME: Not as efficient as possible.. since continuation is a Ret we inserted, we had to redir jumps to it previously
                MapInstructions (continuation, inst);

                il.InsertBefore (continuation, inst);
                il.InsertBefore (continuation, il.Create (OpCodes.Ldc_I4, i));
                il.InsertBefore (continuation, il.Create (OpCodes.Stfld, pcFld));
                jumpTable [i++] = continuation.Next;

                if (skipFinallyBlocks != null) {
                    il.InsertBefore (continuation, il.Create (OpCodes.Ldc_I4_1));
                    il.InsertBefore (continuation, il.Create (OpCodes.Stloc, skipFinallyBlocks));
                }
                il.Replace (continuation, il.Create (OpCodes.Leave, ret));
            }
            il.InsertAfter (loadPC, il.Create (OpCodes.Switch, jumpTable));

            coroutine.Body.InitLocals = true;
            coroutine.Body.ComputeOffsetsAndMaxStack ();
        }
예제 #26
0
 void ReadExceptionHandlerSpecific(ExceptionHandler handler)
 {
     switch (handler.HandlerType) {
     case ExceptionHandlerType.Catch:
         handler.CatchType = reader.LookupToken (ReadToken ()) as TypeReference;
         break;
     case ExceptionHandlerType.Filter:
         handler.FilterStart = GetInstruction (ReadInt32 ());
         break;
     default:
         Advance (4);
         break;
     }
 }
예제 #27
0
        /// <summary>
        /// Clone the given method body.
        /// </summary>
        /// <param name="bo">The original method body.</param>
        /// <param name="m">The method which will own the newly cloned method body.</param>
        /// <returns>A clone of the original method body.</returns>
        public static MethodBody Clone(this MethodBody bo, MethodDefinition m)
        {
            if (bo == null)
            {
                return(null);
            }

            MethodBody bc = new MethodBody(m);

            bc.MaxStackSize  = bo.MaxStackSize;
            bc.InitLocals    = bo.InitLocals;
            bc.LocalVarToken = bo.LocalVarToken;

            bc.Instructions.AddRange(bo.Instructions.Select(o => {
                Instruction c = Instruction.Create(OpCodes.Nop);
                c.OpCode      = o.OpCode;
                c.Operand     = o.Operand;
                c.Offset      = o.Offset;
                return(c);
            }));

            foreach (Instruction c in bc.Instructions)
            {
                if (c.Operand is Instruction target)
                {
                    c.Operand = bc.Instructions[bo.Instructions.IndexOf(target)];
                }
                else if (c.Operand is Instruction[] targets)
                {
                    c.Operand = targets.Select(i => bc.Instructions[bo.Instructions.IndexOf(i)]).ToArray();
                }
            }

            bc.ExceptionHandlers.AddRange(bo.ExceptionHandlers.Select(o => {
                ExceptionHandler c = new ExceptionHandler(o.HandlerType);
                c.TryStart         = o.TryStart == null ? null : bc.Instructions[bo.Instructions.IndexOf(o.TryStart)];
                c.TryEnd           = o.TryEnd == null ? null : bc.Instructions[bo.Instructions.IndexOf(o.TryEnd)];
                c.FilterStart      = o.FilterStart == null ? null : bc.Instructions[bo.Instructions.IndexOf(o.FilterStart)];
                c.HandlerStart     = o.HandlerStart == null ? null : bc.Instructions[bo.Instructions.IndexOf(o.HandlerStart)];
                c.HandlerEnd       = o.HandlerEnd == null ? null : bc.Instructions[bo.Instructions.IndexOf(o.HandlerEnd)];
                c.CatchType        = o.CatchType;
                return(c);
            }));

            bc.Variables.AddRange(bo.Variables.Select(o => {
                VariableDefinition c = new VariableDefinition(o.VariableType);
                return(c);
            }));

#if !CECIL0_9
            m.CustomDebugInformations.AddRange(bo.Method.CustomDebugInformations); // Abstract. TODO: Implement deep CustomDebugInformations copy.
            m.DebugInformation.SequencePoints.AddRange(bo.Method.DebugInformation.SequencePoints.Select(o => {
                SequencePoint c = new SequencePoint(bc.Instructions.FirstOrDefault(i => i.Offset == o.Offset), o.Document);
                c.StartLine     = o.StartLine;
                c.StartColumn   = o.StartColumn;
                c.EndLine       = o.EndLine;
                c.EndColumn     = o.EndColumn;
                return(c);
            }));
#endif

            return(bc);
        }
예제 #28
0
		public virtual DialogResult ShowDialog(MethodDefinition mdef, ExceptionHandler selected)
		{
			MethodDefinition = mdef;
			SelectedExceptionHandler = selected;
			return ShowDialog();
		}
예제 #29
0
        /// <summary>
        /// Generate a new DynamicMethod with which you can invoke the previous state.
        /// If the NativeDetour holds a reference to a managed method, a copy of the original method is returned.
        /// If the NativeDetour holds a reference to a native function, an "undo-call-redo" trampoline with a matching signature is returned.
        /// </summary>
        public MethodBase GenerateTrampoline(MethodBase signature = null)
        {
            MethodBase remoteTrampoline = OnGenerateTrampoline?.InvokeWhileNull <MethodBase>(this, signature);

            if (remoteTrampoline != null)
            {
                return(remoteTrampoline);
            }

            if (!IsValid)
            {
                throw new ObjectDisposedException(nameof(NativeDetour));
            }

            if (_BackupMethod != null)
            {
                // If we're detouring an IL method and have an IL copy, invoke the IL copy.
                // Note that this ignores the passed signature.
                return(_BackupMethod);
            }

            /*
             * if (signature == null)
             *  signature = _BackupMethod;
             */
            if (signature == null)
            {
                throw new ArgumentNullException("A signature must be given if the NativeDetour doesn't hold a reference to a managed method.");
            }

            // Otherwise, undo the detour, call the method and reapply the detour.

            MethodBase methodCallable = Method;

            if (methodCallable == null)
            {
                methodCallable = DetourHelper.GenerateNativeProxy(Data.Method, signature);
            }

            Type returnType = (signature as MethodInfo)?.ReturnType ?? typeof(void);

            ParameterInfo[] args     = signature.GetParameters();
            Type[]          argTypes = new Type[args.Length];
            for (int i = 0; i < args.Length; i++)
            {
                argTypes[i] = args[i].ParameterType;
            }

            using (DynamicMethodDefinition dmd = new DynamicMethodDefinition(
                       $"Trampoline:Native<{Method?.GetID(simple: true) ?? ((long) Data.Method).ToString("X16")}>?{GetHashCode()}",
                       returnType, argTypes
                       )) {
                ILProcessor il = dmd.GetILProcessor();

                ExceptionHandler eh = new ExceptionHandler(ExceptionHandlerType.Finally);
                il.Body.ExceptionHandlers.Add(eh);

                il.EmitDetourCopy(_BackupNative, Data.Method, Data.Type);

                // Store the return value in a local as we can't preserve the stack across exception block boundaries.
                VariableDefinition localResult = null;
                if (returnType != typeof(void))
                {
                    il.Body.Variables.Add(localResult = new VariableDefinition(il.Import(returnType)));
                }

                // Label blockTry = il.BeginExceptionBlock();
                int instriTryStart = il.Body.Instructions.Count;

                for (int i = 0; i < argTypes.Length; i++)
                {
                    il.Emit(OpCodes.Ldarg, i);
                }

                if (methodCallable is MethodInfo)
                {
                    il.Emit(OpCodes.Call, (MethodInfo)methodCallable);
                }
                else if (methodCallable is ConstructorInfo)
                {
                    il.Emit(OpCodes.Call, (ConstructorInfo)methodCallable);
                }
                else
                {
                    throw new NotSupportedException($"Method type {methodCallable.GetType().FullName} not supported.");
                }

                if (localResult != null)
                {
                    il.Emit(OpCodes.Stloc, localResult);
                }

                il.Emit(OpCodes.Leave, (object)null);
                Instruction instrLeave = il.Body.Instructions[il.Body.Instructions.Count - 1];

                // il.BeginFinallyBlock();
                int instriTryEnd       = il.Body.Instructions.Count;
                int instriFinallyStart = il.Body.Instructions.Count;

                // Reapply the detour even if the method threw an exception.
                il.EmitDetourApply(Data);

                // il.EndExceptionBlock();
                int instriFinallyEnd = il.Body.Instructions.Count;

                Instruction instrLeaveTarget = null;

                if (localResult != null)
                {
                    il.Emit(OpCodes.Ldloc, localResult);
                    instrLeaveTarget = il.Body.Instructions[il.Body.Instructions.Count - 1];
                }

                il.Emit(OpCodes.Ret);
                instrLeaveTarget   = instrLeaveTarget ?? il.Body.Instructions[il.Body.Instructions.Count - 1];
                instrLeave.Operand = instrLeaveTarget;

                // TODO: Are the exception handler indices correct?
                eh.TryStart     = il.Body.Instructions[instriTryStart];
                eh.TryEnd       = il.Body.Instructions[instriTryEnd];
                eh.HandlerStart = il.Body.Instructions[instriTryEnd];
                eh.HandlerEnd   = il.Body.Instructions[instriFinallyEnd];

                return(dmd.Generate());
            }
        }
예제 #30
0
		internal static MethodBody Clone (MethodBody body, MethodDefinition parent, ImportContext context)
		{
			MethodBody nb = new MethodBody (parent);
			nb.MaxStack = body.MaxStack;
			nb.InitLocals = body.InitLocals;
			nb.CodeSize = body.CodeSize;

			foreach (VariableDefinition var in body.Variables)
				nb.Variables.Add (new VariableDefinition (
					context.Import (var.VariableType)));

			foreach (Instruction instr in body.Instructions) {
				Instruction ni = new Instruction (instr.OpCode);

				switch (instr.OpCode.OperandType) {
				case OperandType.InlineParam :
				case OperandType.ShortInlineParam :
					int param = body.Method.Parameters.IndexOf ((ParameterDefinition) instr.Operand);
					ni.Operand = parent.Parameters [param];
					break;
				case OperandType.InlineVar :
				case OperandType.ShortInlineVar :
					int var = body.Variables.IndexOf ((VariableDefinition) instr.Operand);
					ni.Operand = nb.Variables [var];
					break;
				case OperandType.InlineField :
					ni.Operand = context.Import ((FieldReference) instr.Operand);
					break;
				case OperandType.InlineMethod :
					ni.Operand = context.Import ((MethodReference) instr.Operand);
					break;
				case OperandType.InlineType :
					ni.Operand = context.Import ((TypeReference) instr.Operand);
					break;
				case OperandType.InlineTok :
					if (instr.Operand is TypeReference)
						ni.Operand = context.Import ((TypeReference) instr.Operand);
					else if (instr.Operand is FieldReference)
						ni.Operand = context.Import ((FieldReference) instr.Operand);
					else if (instr.Operand is MethodReference)
						ni.Operand = context.Import ((MethodReference) instr.Operand);
					break;
				case OperandType.ShortInlineBrTarget :
				case OperandType.InlineBrTarget :
					break;
				default :
					ni.Operand = instr.Operand;
					break;
				}

				nb.Instructions.Add (ni);
			}

			for (int i = 0; i < body.Instructions.Count; i++) {
				Instruction instr = nb.Instructions [i];
				if (instr.OpCode.OperandType != OperandType.ShortInlineBrTarget &&
					instr.OpCode.OperandType != OperandType.InlineBrTarget)
					continue;

				instr.Operand = GetInstruction (body, nb, (Instruction) body.Instructions [i].Operand);
			}

			foreach (ExceptionHandler eh in body.ExceptionHandlers) {
				ExceptionHandler neh = new ExceptionHandler (eh.Type);
				neh.TryStart = GetInstruction (body, nb, eh.TryStart);
				neh.TryEnd = GetInstruction (body, nb, eh.TryEnd);
				neh.HandlerStart = GetInstruction (body, nb, eh.HandlerStart);
				neh.HandlerEnd = GetInstruction (body, nb, eh.HandlerEnd);

				switch (eh.Type) {
				case ExceptionHandlerType.Catch :
					neh.CatchType = context.Import (eh.CatchType);
					break;
				case ExceptionHandlerType.Filter :
					neh.FilterStart = GetInstruction (body, nb, eh.FilterStart);
					neh.FilterEnd = GetInstruction (body, nb, eh.FilterEnd);
					break;
				}

				nb.ExceptionHandlers.Add (neh);
			}

			return nb;
		}
        private void _CopyMethodToDefinition()
        {
            MethodBase method     = OriginalMethod;
            Module     moduleFrom = method.Module;

            System.Reflection.MethodBody bodyFrom = method.GetMethodBody();
            byte[] data = bodyFrom?.GetILAsByteArray();
            if (data == null)
            {
                throw new NotSupportedException("Body-less method");
            }

            MethodDefinition def      = Definition;
            ModuleDefinition moduleTo = def.Module;

            Mono.Cecil.Cil.MethodBody bodyTo = def.Body;
            ILProcessor processor            = bodyTo.GetILProcessor();

            Type[] typeArguments = null;
            if (method.DeclaringType.IsGenericType)
            {
                typeArguments = method.DeclaringType.GetGenericArguments();
            }

            Type[] methodArguments = null;
            if (method.IsGenericMethod)
            {
                methodArguments = method.GetGenericArguments();
            }

            foreach (LocalVariableInfo info in bodyFrom.LocalVariables)
            {
                TypeReference type = moduleTo.ImportReference(info.LocalType);
                if (info.IsPinned)
                {
                    type = new PinnedType(type);
                }
                bodyTo.Variables.Add(new VariableDefinition(type));
            }

            using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) {
                for (Instruction instr = null, prev = null; reader.BaseStream.Position < reader.BaseStream.Length; prev = instr)
                {
                    int offset = (int)reader.BaseStream.Position;
                    instr = Instruction.Create(OpCodes.Nop);
                    byte op = reader.ReadByte();
                    instr.OpCode = op != 0xfe ? _CecilOpCodes1X[op] : _CecilOpCodes2X[reader.ReadByte()];
                    instr.Offset = offset;
                    if (prev != null)
                    {
                        prev.Next = instr;
                    }
                    instr.Previous = prev;
                    ReadOperand(reader, instr);
                    bodyTo.Instructions.Add(instr);
                }
            }

            foreach (Instruction instr in bodyTo.Instructions)
            {
                switch (instr.OpCode.OperandType)
                {
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                    instr.Operand = GetInstruction((int)instr.Operand);
                    break;

                case OperandType.InlineSwitch:
                    int[]         offsets = (int[])instr.Operand;
                    Instruction[] targets = new Instruction[offsets.Length];
                    for (int i = 0; i < offsets.Length; i++)
                    {
                        targets[i] = GetInstruction(offsets[i]);
                    }
                    instr.Operand = targets;
                    break;
                }
            }

            foreach (ExceptionHandlingClause clause in bodyFrom.ExceptionHandlingClauses)
            {
                ExceptionHandler handler = new ExceptionHandler((ExceptionHandlerType)clause.Flags);
                bodyTo.ExceptionHandlers.Add(handler);

                handler.TryStart = GetInstruction(clause.TryOffset);
                handler.TryEnd   = GetInstruction(clause.TryOffset + clause.TryLength);

                handler.FilterStart  = handler.HandlerType != ExceptionHandlerType.Filter ? null : GetInstruction(clause.FilterOffset);
                handler.HandlerStart = GetInstruction(clause.HandlerOffset);
                handler.HandlerEnd   = GetInstruction(clause.HandlerOffset + clause.HandlerLength);

                handler.CatchType = handler.HandlerType != ExceptionHandlerType.Catch ? null : clause.CatchType == null ? null : moduleTo.ImportReference(clause.CatchType);
            }

            void ReadOperand(BinaryReader reader, Instruction instr)
            {
                int index, offs, length;

                switch (instr.OpCode.OperandType)
                {
                case OperandType.InlineNone:
                    instr.Operand = null;
                    break;

                case OperandType.InlineSwitch:
                    length = reader.ReadInt32();
                    offs   = (int)reader.BaseStream.Position + (4 * length);
                    int[] targets = new int[length];
                    for (int i = 0; i < length; i++)
                    {
                        targets[i] = reader.ReadInt32() + offs;
                    }
                    instr.Operand = targets;
                    break;

                case OperandType.ShortInlineBrTarget:
                    offs          = reader.ReadSByte();
                    instr.Operand = (int)reader.BaseStream.Position + offs;
                    break;

                case OperandType.InlineBrTarget:
                    offs          = reader.ReadInt32();
                    instr.Operand = (int)reader.BaseStream.Position + offs;
                    break;

                case OperandType.ShortInlineI:
                    instr.Operand = instr.OpCode == OpCodes.Ldc_I4_S ? reader.ReadSByte() : (object)reader.ReadByte();
                    break;

                case OperandType.InlineI:
                    instr.Operand = reader.ReadInt32();
                    break;

                case OperandType.ShortInlineR:
                    instr.Operand = reader.ReadSingle();
                    break;

                case OperandType.InlineR:
                    instr.Operand = reader.ReadDouble();
                    break;

                case OperandType.InlineI8:
                    instr.Operand = reader.ReadInt64();
                    break;

                case OperandType.InlineSig:
                    instr.Operand = moduleTo.ImportCallSite(moduleFrom, moduleFrom.ResolveSignature(reader.ReadInt32()));
                    break;

                case OperandType.InlineString:
                    instr.Operand = moduleFrom.ResolveString(reader.ReadInt32());
                    break;

                case OperandType.InlineTok:
                    instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Any);
                    break;

                case OperandType.InlineType:
                    instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Type);
                    break;

                case OperandType.InlineMethod:
                    instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Method);
                    break;

                case OperandType.InlineField:
                    instr.Operand = ResolveTokenAs(reader.ReadInt32(), TokenResolutionMode.Field);
                    break;

                case OperandType.ShortInlineVar:
                case OperandType.InlineVar:
                    index         = instr.OpCode.OperandType == OperandType.ShortInlineVar ? reader.ReadByte() : reader.ReadInt16();
                    instr.Operand = bodyTo.Variables[index];
                    break;

                case OperandType.InlineArg:
                case OperandType.ShortInlineArg:
                    index         = instr.OpCode.OperandType == OperandType.ShortInlineArg ? reader.ReadByte() : reader.ReadInt16();
                    instr.Operand = def.Parameters[index];
                    break;

                case OperandType.InlinePhi:     // No opcode seems to use this
                default:
                    throw new NotSupportedException($"Unsupported opcode ${instr.OpCode.Name}");
                }
            }

            MemberReference ResolveTokenAs(int token, TokenResolutionMode resolveMode)
            {
                try {
                    switch (resolveMode)
                    {
                    case TokenResolutionMode.Type:
                        return(moduleTo.ImportReference(moduleFrom.ResolveType(token, typeArguments, methodArguments)));

                    case TokenResolutionMode.Method:
                        return(moduleTo.ImportReference(moduleFrom.ResolveMethod(token, typeArguments, methodArguments)));

                    case TokenResolutionMode.Field:
                        return(moduleTo.ImportReference(moduleFrom.ResolveField(token, typeArguments, methodArguments)));

                    case TokenResolutionMode.Any:
                        switch (moduleFrom.ResolveMember(token, typeArguments, methodArguments))
                        {
                        case Type i:
                            return(moduleTo.ImportReference(i));

                        case MethodBase i:
                            return(moduleTo.ImportReference(i));

                        case FieldInfo i:
                            return(moduleTo.ImportReference(i));

                        case var resolved:
                            throw new NotSupportedException($"Invalid resolved member type {resolved.GetType()}");
                        }

                    default:
                        throw new NotSupportedException($"Invalid TokenResolutionMode {resolveMode}");
                    }
                } catch (MissingMemberException) {
                    // we could not resolve the method normally, so lets read the import table
                    // but we can only do that if the module was loaded from disk
                    // this can still throw if the assembly is a dynamic one, but if that's broken, you have bigger issues
                    string filePath = moduleFrom.Assembly.Location;
                    if (!File.Exists(filePath))
                    {
                        // in this case, the fallback cannot be followed, and so throwing the original error gives the user information
                        throw;
                    }

                    // TODO: make this cached somehow so its not read and re-opened a bunch
                    using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(filePath, new ReaderParameters {
                        ReadingMode = ReadingMode.Deferred
                    })) {
                        ModuleDefinition module = assembly.Modules.First(m => m.Name == moduleFrom.Name);
                        // this should only fail if the token itself is somehow wrong
                        MemberReference reference = (MemberReference)module.LookupToken(token);
                        // the explicit casts here are to throw if they are incorrect
                        // normally the references would need to be imported, but moduleTo isn't written to anywhere
                        switch (resolveMode)
                        {
                        case TokenResolutionMode.Type:
                            return((TypeReference)reference);

                        case TokenResolutionMode.Method:
                            return((MethodReference)reference);

                        case TokenResolutionMode.Field:
                            return((FieldReference)reference);

                        case TokenResolutionMode.Any:
                            return(reference);

                        default:
                            throw new NotSupportedException($"Invalid TokenResolutionMode {resolveMode}");
                        }
                    }
                }
            }

            Instruction GetInstruction(int offset)
            {
                int last = bodyTo.Instructions.Count - 1;

                if (offset < 0 || offset > bodyTo.Instructions[last].Offset)
                {
                    return(null);
                }

                int min = 0;
                int max = last;

                while (min <= max)
                {
                    int         mid   = min + ((max - min) / 2);
                    Instruction instr = bodyTo.Instructions[mid];

                    if (offset == instr.Offset)
                    {
                        return(instr);
                    }

                    if (offset < instr.Offset)
                    {
                        max = mid - 1;
                    }
                    else
                    {
                        min = mid + 1;
                    }
                }

                return(null);
            }
        }
예제 #32
0
        /// <summary>
        /// CopyMethod copies a method definition into a new copy which can be added
        /// to another module.
        /// </summary>
        /// <param name="method">The MethodDefinition to copy</param>
        /// <returns>A copy of the MethodDefinition</returns>
        public static MethodDefinition CopyMethod(MethodDefinition method)
        {
            MethodDefinition newMethod = new MethodDefinition(method.Name, method.Attributes, method.ReturnType);
            foreach (ParameterDefinition param in method.Parameters)
            {
                ParameterDefinition newParam = new ParameterDefinition(param.Name, param.Attributes, param.ParameterType);
                newMethod.Parameters.Add(newParam);
            }

            foreach (CustomAttribute attr in method.CustomAttributes)
            {
                CustomAttribute newAttr = new CustomAttribute(attr.Constructor);
                foreach (CustomAttributeArgument arg in attr.ConstructorArguments)
                {
                    CustomAttributeArgument newArg = new CustomAttributeArgument(arg.Type, arg.Value);
                    newAttr.ConstructorArguments.Add(newArg);
                }
                foreach (CustomAttributeNamedArgument arg in attr.Fields)
                {
                    CustomAttributeNamedArgument newArg = new CustomAttributeNamedArgument(arg.Name, new CustomAttributeArgument(arg.Argument.Type, arg.Argument.Value));
                    newAttr.Fields.Add(newArg);
                }
                newMethod.CustomAttributes.Add(newAttr);
            }

            if (method.Body != null)
            {
                if (newMethod.Body == null)
                    newMethod.Body = new MethodBody(newMethod);
                foreach (Instruction inst in method.Body.Instructions)
                {
                    newMethod.Body.Instructions.Add(inst);
                }

                foreach (VariableDefinition var in method.Body.Variables)
                {
                    VariableDefinition newVar = new VariableDefinition(var.Name, var.VariableType);
                    newMethod.Body.Variables.Add(newVar);
                }

                foreach (ExceptionHandler handler in method.Body.ExceptionHandlers)
                {
                    ExceptionHandler newHandler = new ExceptionHandler(handler.HandlerType);
                    newHandler.HandlerStart = handler.HandlerStart;
                    newHandler.HandlerEnd = handler.HandlerEnd;
                    newHandler.TryStart = handler.TryStart;
                    newHandler.TryEnd = handler.TryEnd;
                    newHandler.FilterStart = handler.FilterStart;
                    newHandler.CatchType = handler.CatchType;
                    newMethod.Body.ExceptionHandlers.Add(newHandler);
                }

                newMethod.Body.InitLocals = method.Body.InitLocals;
            }
            return newMethod;
        }
예제 #33
0
        bool JumpToErr(CodeBody body, StackFrame frame, Exception err)
        {
            var posnow = frame.GetCode();
            List <Mono.Cecil.Cil.ExceptionHandler> ehs = new List <ExceptionHandler>();

            Mono.Cecil.Cil.ExceptionHandler ehNear = null;
            int ehNearB = -1;

            foreach (var eh in body.bodyNative.ExceptionHandlers)
            {
                if (eh.HandlerType == ExceptionHandlerType.Catch)
                {
                    Type ehtype = GetType(eh.CatchType).TypeForSystem;
                    if (ehtype == err.GetType() || err.GetType().IsSubclassOf(ehtype))
                    //if(GetType(eh.CatchType)== environment.GetType(err.GetType()))
                    {
                        if (eh.TryStart.Offset <= posnow.Offset && eh.TryEnd.Offset >= posnow.Offset)
                        {
                            if (ehNear == null)
                            {
                                ehNear  = eh;//第一个
                                ehNearB = GetBaseCount(ehtype, err.GetType());
                            }
                            else
                            {
                                if (eh.TryStart.Offset > ehNear.TryStart.Offset || eh.TryEnd.Offset < ehNear.TryEnd.Offset)//范围更小
                                {
                                    ehNear  = eh;
                                    ehNearB = GetBaseCount(ehtype, err.GetType());
                                }
                                else if (eh.TryStart.Offset == ehNear.TryStart.Offset || eh.TryEnd.Offset == ehNear.TryEnd.Offset) //范围相等
                                {
                                    if (ehtype == err.GetType())                                                                   //类型一致,没有比这个更牛的了
                                    {
                                        ehNear  = eh;
                                        ehNearB = GetBaseCount(ehtype, err.GetType());
                                    }
                                    else if (GetType(ehNear.CatchType).TypeForSystem == err.GetType())//上次找到的就是第一,不用比了
                                    {
                                        continue;
                                    }
                                    else //比较上次找到的类型,和这次找到的类型的亲缘性;
                                    {
                                        int newehNearB = GetBaseCount(ehtype, err.GetType());
                                        if (newehNearB == -1)
                                        {
                                            continue;
                                        }
                                        if (newehNearB < ehNearB)
                                        {
                                            ehNear  = eh;
                                            ehNearB = newehNearB;
                                        }
                                    }
                                }
                            }
                            ehs.Add(eh);
                        }
                    }
                }
            }
            if (ehNear != null)
            {
                frame.stackCalc.Push(err);
                frame.SetCodePos(ehNear.HandlerStart.Offset);// ._pos = ehNear.HandlerStart;
                RunCodeWithTry(body, frame);
                return(true);
            }
            return(false);
        }
예제 #34
0
		internal ControlFlowNode(int blockIndex, ExceptionHandler exceptionHandler, ControlFlowNode endFinallyOrFaultNode)
		{
			BlockIndex = blockIndex;
			NodeType = endFinallyOrFaultNode != null ? ControlFlowNodeType.FinallyOrFaultHandler : ControlFlowNodeType.CatchHandler;
			ExceptionHandler = exceptionHandler;
			EndFinallyOrFaultNode = endFinallyOrFaultNode;
			Debug.Assert((exceptionHandler.HandlerType == ExceptionHandlerType.Finally || exceptionHandler.HandlerType == ExceptionHandlerType.Fault) == (endFinallyOrFaultNode != null));
			Offset = exceptionHandler.HandlerStart.Offset;
		}
예제 #35
0
파일: TypeWeaver.cs 프로젝트: tritao/flood
        private ExceptionHandler Copy(DeepCopier copier, ExceptionHandler def)
        {
            var ret= new ExceptionHandler(def.HandlerType);
            if(def.CatchType != null)
                ret.CatchType = CopyReference(copier,def.CatchType);

            copier.Log("< ExceptionHandler ");
            copier.CopyAll(def,ret,ret,"CatchType");

            return ret;
        }
예제 #36
0
		void WriteHandlerSpecific (ExceptionHandler eh)
		{
			switch (eh.Type) {
			case ExceptionHandlerType.Catch :
				WriteToken (eh.CatchType.MetadataToken);
				break;
			case ExceptionHandlerType.Filter :
				m_codeWriter.Write ((uint) eh.FilterStart.Offset);
				break;
			default :
				m_codeWriter.Write (0);
				break;
			}
		}
예제 #37
0
        public static MethodDefinition Inject(ModuleDefinition mod, MethodDefinition mtd)
        {
            MethodDefinition ret = new MethodDefinition(mtd.Name, mtd.Attributes, mod.TypeSystem.Void);
            ret.Attributes = mtd.Attributes;
            ret.ImplAttributes = mtd.ImplAttributes;

            if (mtd.IsPInvokeImpl)
            {
                ret.PInvokeInfo = mtd.PInvokeInfo;
                bool has = false;
                foreach (ModuleReference modRef in mod.ModuleReferences)
                    if (modRef.Name == ret.PInvokeInfo.Module.Name)
                    {
                        has = true;
                        ret.PInvokeInfo.Module = modRef;
                        break;
                    }
                if (!has)
                    mod.ModuleReferences.Add(ret.PInvokeInfo.Module);
            }
            if (mtd.HasCustomAttributes)
            {
                foreach (CustomAttribute attr in mtd.CustomAttributes)
                {
                    CustomAttribute nAttr = new CustomAttribute(ImportMethod(attr.Constructor, mod, ret, null), attr.GetBlob());
                    ret.CustomAttributes.Add(nAttr);
                }
            }

            foreach (GenericParameter param in mtd.GenericParameters)
            {
                var p = new GenericParameter(param.Name, ret);
                if (param.HasCustomAttributes)
                {
                    foreach (CustomAttribute attr in param.CustomAttributes)
                    {
                        CustomAttribute nAttr = new CustomAttribute(ImportMethod(attr.Constructor, mod, ret, null), attr.GetBlob());
                        p.CustomAttributes.Add(nAttr);
                    }
                }
                ret.GenericParameters.Add(p);
            }

            ret.ReturnType = ImportType(mtd.ReturnType, mod, ret, null);

            foreach (ParameterDefinition param in mtd.Parameters)
            {
                var p = new ParameterDefinition(param.Name, param.Attributes, ImportType(param.ParameterType, mod, ret, null));
                if (param.HasCustomAttributes)
                {
                    foreach (CustomAttribute attr in param.CustomAttributes)
                    {
                        CustomAttribute nAttr = new CustomAttribute(ImportMethod(attr.Constructor, mod, ret, null), attr.GetBlob());
                        p.CustomAttributes.Add(nAttr);
                    }
                }
                ret.Parameters.Add(p);
            }

            if (mtd.HasBody)
            {
                MethodBody old = mtd.Body;
                MethodBody bdy = new MethodBody(ret);
                bdy.MaxStackSize = old.MaxStackSize;
                bdy.InitLocals = old.InitLocals;

                ILProcessor psr = bdy.GetILProcessor();

                foreach (VariableDefinition var in old.Variables)
                    bdy.Variables.Add(new VariableDefinition(var.Name, ImportType(var.VariableType, mod, ret, null)));

                foreach (Instruction inst in old.Instructions)
                {
                    switch (inst.OpCode.OperandType)
                    {
                        case OperandType.InlineArg:
                        case OperandType.ShortInlineArg:
                            if (inst.Operand == old.ThisParameter)
                                psr.Emit(inst.OpCode, bdy.ThisParameter);
                            else
                            {
                                int param = mtd.Parameters.IndexOf(inst.Operand as ParameterDefinition);
                                psr.Emit(inst.OpCode, ret.Parameters[param]);
                            }
                            break;
                        case OperandType.InlineVar:
                        case OperandType.ShortInlineVar:
                            int var = old.Variables.IndexOf(inst.Operand as VariableDefinition);
                            psr.Emit(inst.OpCode, bdy.Variables[var]);
                            break;
                        case OperandType.InlineField:
                            psr.Emit(inst.OpCode, ImportField(inst.Operand as FieldReference, mod, null));
                            break;
                        case OperandType.InlineMethod:
                            if (inst.Operand == mtd)
                                psr.Emit(inst.OpCode, ret);
                            else
                                psr.Emit(inst.OpCode, ImportMethod(inst.Operand as MethodReference, mod, ret, null));
                            break;
                        case OperandType.InlineType:
                            psr.Emit(inst.OpCode, ImportType(inst.Operand as TypeReference, mod, ret, null));
                            break;
                        case OperandType.InlineTok:
                            if (inst.Operand is TypeReference)
                                psr.Emit(inst.OpCode, ImportType(inst.Operand as TypeReference, mod, ret, null));
                            else if (inst.Operand is FieldReference)
                                psr.Emit(inst.OpCode, ImportField(inst.Operand as FieldReference, mod, null));
                            else if (inst.Operand is MethodReference)
                                psr.Emit(inst.OpCode, ImportMethod(inst.Operand as MethodReference, mod, ret, null));
                            break;
                        default:
                            psr.Append(inst.Clone());
                            break;
                    }
                }

                for (int i = 0; i < bdy.Instructions.Count; i++)
                {
                    Instruction inst = bdy.Instructions[i];
                    Instruction o = old.Instructions[i];

                    if (inst.OpCode.OperandType == OperandType.InlineSwitch)
                    {
                        Instruction[] olds = (Instruction[])o.Operand;
                        Instruction[] news = new Instruction[olds.Length];

                        for (int ii = 0; ii < news.Length; ii++)
                            news[ii] = bdy.Instructions[old.Instructions.IndexOf(olds[ii])];

                        inst.Operand = news;
                    }
                    else if (inst.OpCode.OperandType == OperandType.ShortInlineBrTarget || inst.OpCode.OperandType == OperandType.InlineBrTarget)
                        inst.Operand = bdy.Instructions[old.Instructions.IndexOf(inst.Operand as Instruction)];
                }

                foreach (ExceptionHandler eh in old.ExceptionHandlers)
                {
                    ExceptionHandler neh = new ExceptionHandler(eh.HandlerType);
                    if (old.Instructions.IndexOf(eh.TryStart) != -1)
                        neh.TryStart = bdy.Instructions[old.Instructions.IndexOf(eh.TryStart)];
                    if (old.Instructions.IndexOf(eh.TryEnd) != -1)
                        neh.TryEnd = bdy.Instructions[old.Instructions.IndexOf(eh.TryEnd)];
                    if (old.Instructions.IndexOf(eh.HandlerStart) != -1)
                        neh.HandlerStart = bdy.Instructions[old.Instructions.IndexOf(eh.HandlerStart)];
                    if (old.Instructions.IndexOf(eh.HandlerEnd) != -1)
                        neh.HandlerEnd = bdy.Instructions[old.Instructions.IndexOf(eh.HandlerEnd)];

                    switch (eh.HandlerType)
                    {
                        case ExceptionHandlerType.Catch:
                            neh.CatchType = ImportType(eh.CatchType, mod, ret, null);
                            break;
                        case ExceptionHandlerType.Filter:
                            neh.FilterStart = bdy.Instructions[old.Instructions.IndexOf(eh.FilterStart)];
                            //neh.FilterEnd = bdy.Instructions[old.Instructions.IndexOf(eh.FilterEnd)];
                            break;
                    }

                    bdy.ExceptionHandlers.Add(neh);
                }

                ret.Body = bdy;
            }

            return ret;
        }
		void ReadExceptionHandlerEnd (ExceptionHandler eh, BinaryReader br, MethodBody body)
		{
			switch (eh.Type) {
			case ExceptionHandlerType.Catch :
				MetadataToken token = new MetadataToken (br.ReadInt32 ());
				eh.CatchType = m_reflectReader.GetTypeDefOrRef (token, new GenericContext (body.Method));
				break;
			case ExceptionHandlerType.Filter :
				eh.FilterStart = GetInstruction (body, br.ReadInt32 ());
				eh.FilterEnd = GetInstruction (body, eh.HandlerStart.Previous.Offset);
				break;
			default :
				br.ReadInt32 ();
				break;
			}
		}
		public virtual DialogResult ShowDialog(MethodDefinition mdef, ExceptionHandler selected)
		{
            m_mdef = mdef;
            m_selectedexceptionhandler = selected;
			return base.ShowDialog();
		}