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