Beispiel #1
0
        public CallInfo[] Collect(Mono.Cecil.MethodDefinition method, Func <Instruction, bool> filter = null)
        {
            //if (method.Name != "SimpleLogFromTryCatch"
            //	&& method.Name != "EnqueueNoOpIfNeeded") return new CallInfo[0];

            if (!method.HasBody)
            {
                return(new CallInfo[0]);
            }

            var body = method.Body;

            if (method.Body.Instructions.Any(i => i.Is(OpCodes.Call, OpCodes.Callvirt) && filter(i)))
            {
                var function    = ilReader.ReadIL(body);
                var opsByOffset = body.Instructions.ToDictionary(instr => instr.Offset);

                var transformContext = decompiler.CreateILTransformContext(function);
                //foreach (var t in ILTransforms)
                //{
                //				t.Run(function, transformContext);
                //}

                var collector = new BlockVisitor(function, i =>
                {
                    var range = i.ILRange;
                    var op    = opsByOffset[range.Start];
                    while (!op.Is(OpCodes.Call, OpCodes.Callvirt))
                    {
                        op = op.Next;
                        if (op.Offset > range.End)
                        {
                            return(false);
                        }
                    }

                    return(filter(op));
                });

                function.AcceptVisitor(collector);

                if (collector.CallStarts.Count > 0)
                {
                    var retval = new CallInfo[collector.CallStarts.Count];

                    var i = 0;
                    foreach (var(blockStart, callOffset) in collector.CallStarts)
                    {
                        retval[i++] = new CallInfo(opsByOffset[blockStart], opsByOffset[callOffset]);
                    }

                    return(retval);
                }
            }

            return(new CallInfo[0]);
        }
Beispiel #2
0
            public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
            {
                base.DecompileMethod(method, output, options);
                var module    = method.ParentModule.PEFile;
                var metadata  = module.Metadata;
                var methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)method.MetadataToken);

                if (!methodDef.HasBody())
                {
                    return;
                }
                IAssemblyResolver assemblyResolver = module.GetAssemblyResolver();
                var typeSystem = new DecompilerTypeSystem(module, assemblyResolver);
                var reader     = new ILReader(typeSystem.MainModule);

                reader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols;
                var        methodBody = module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
                ILFunction il         = reader.ReadIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, kind: ILFunctionKind.TopLevelFunction, cancellationToken: options.CancellationToken);
                var        decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings)
                {
                    CancellationToken = options.CancellationToken
                };
                ILTransformContext context = decompiler.CreateILTransformContext(il);

                context.Stepper.StepLimit = options.StepLimit;
                context.Stepper.IsDebug   = options.IsDebug;
                try
                {
                    il.RunTransforms(transforms, context);
                }
                catch (StepLimitReachedException)
                {
                }
                catch (Exception ex)
                {
                    output.WriteLine(ex.ToString());
                    output.WriteLine();
                    output.WriteLine("ILAst after the crash:");
                }
                finally
                {
                    // update stepper even if a transform crashed unexpectedly
                    if (options.StepLimit == int.MaxValue)
                    {
                        Stepper = context.Stepper;
                        OnStepperUpdated(new EventArgs());
                    }
                }
                (output as ISmartTextOutput)?.AddButton(Images.ViewCode, "Show Steps", delegate {
                    Docking.DockWorkspace.Instance.ShowToolPane(DebugStepsPaneModel.PaneContentId);
                });
                output.WriteLine();
                il.WriteTo(output, DebugSteps.Options);
            }
Beispiel #3
0
            public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
            {
                base.DecompileMethod(method, output, options);
                if (!method.HasBody)
                {
                    return;
                }
                var typeSystem             = new DecompilerTypeSystem(method.Module);
                var specializingTypeSystem = typeSystem.GetSpecializingTypeSystem(new SimpleTypeResolveContext(typeSystem.Resolve(method)));
                var reader = new ILReader(specializingTypeSystem);

                reader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols;
                ILFunction il         = reader.ReadIL(method.Body, options.CancellationToken);
                var        namespaces = new HashSet <string>();
                var        decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings)
                {
                    CancellationToken = options.CancellationToken
                };
                ILTransformContext context = decompiler.CreateILTransformContext(il);

                context.Stepper.StepLimit = options.StepLimit;
                context.Stepper.IsDebug   = options.IsDebug;
                try {
                    il.RunTransforms(transforms, context);
                } catch (StepLimitReachedException) {
                } catch (Exception ex) {
                    output.WriteLine(ex.ToString());
                    output.WriteLine();
                    output.WriteLine("ILAst after the crash:");
                } finally {
                    // update stepper even if a transform crashed unexpectedly
                    if (options.StepLimit == int.MaxValue)
                    {
                        Stepper = context.Stepper;
                        OnStepperUpdated(new EventArgs());
                    }
                }
                (output as ISmartTextOutput)?.AddButton(Images.ViewCode, "Show Steps", delegate {
                    DebugSteps.Show();
                });
                output.WriteLine();
                il.WriteTo(output, DebugSteps.Options);
            }