public void HeuristicAdd(Mono.Cecil.ModuleDefinition module) { // Search module for PFEs and add enclosing method. // Find all pfe's in graph. foreach (Mono.Cecil.MethodDefinition method in Campy.Types.Utils.ReflectionCecilInterop.GetMethods(module)) { if (method.Body == null) { return; } foreach (Mono.Cecil.Cil.Instruction i in method.Body.Instructions) { Mono.Cecil.Cil.OpCode op = i.OpCode; Mono.Cecil.Cil.FlowControl fc = op.FlowControl; object operand = i.Operand; Mono.Cecil.MethodReference call_to = operand as Mono.Cecil.MethodReference; if (fc == Mono.Cecil.Cil.FlowControl.Call) { if (call_to != null && call_to.Name.Equals("For") && call_to.DeclaringType != null && call_to.DeclaringType.FullName.Equals("Campy.Parallel")) { Add(method); } } } } }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode) { if (opcode.OperandType != OperandType.InlineNone) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, null)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, byte value) { if (opcode.OperandType != OperandType.ShortInlineI || opcode == OpCodes.Ldc_I4_S) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, (object)value)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, double value) { if (opcode.OperandType != OperandType.InlineR) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, (object)value)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, float value) { if (opcode.OperandType != OperandType.ShortInlineR) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, value)); }
static OpCode FindOpcode(Cecil.Cil.OpCode cop) { var opType = typeof(OpCodes).GetFields().First((op) => { return(op.Name.ToLower().Replace('_', '.') == cop.Name); }); return((OpCode)opType.GetValue(null)); }
public override void Visit(Model.Bytecode.InitObjInstruction instruction) { Cecil.Cil.OpCode op = Cecil.Cil.OpCodes.Initobj; Cecil.TypeReference type = referenceGenerator.TypeReference(instruction.Type); Result = new List <Mono.Cecil.Cil.Instruction>() { processor.Create(op, type) }; }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, MethodReference method) { if (method == null) { throw new ArgumentNullException("method"); } if (opcode.OperandType != OperandType.InlineMethod && opcode.OperandType != OperandType.InlineTok) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, method)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, Instruction target) { if (target == null) { throw new ArgumentNullException("target"); } if (opcode.OperandType != OperandType.InlineBrTarget && opcode.OperandType != OperandType.ShortInlineBrTarget) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, target)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, Instruction[] targets) { if (targets == null) { throw new ArgumentNullException("targets"); } if (opcode.OperandType != OperandType.InlineSwitch) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, targets)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, ParameterDefinition parameter) { if (parameter == null) { throw new ArgumentNullException("parameter"); } if (opcode.OperandType != OperandType.ShortInlineArg && opcode.OperandType != OperandType.InlineArg) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, parameter)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, string value) { if (value == null) { throw new ArgumentNullException("value"); } if (opcode.OperandType != OperandType.InlineString) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, value)); }
private object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is Mono.Cecil.Cil.OpCode) { Mono.Cecil.Cil.OpCode code = (Mono.Cecil.Cil.OpCode)segment.Reference; string encodedName = code.Code.ToString(); string opCodeHex = code.Size > 1 ? string.Format("0x{0:x2}{1:x2}", code.Op1, code.Op2) : string.Format("0x{0:x2}", code.Op2); XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation; if (docProvider != null) { string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + encodedName); if (documentation != null) { XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(string.Format("{0} ({1}) - ", code.Name, opCodeHex)); renderer.AddXmlDocumentation(documentation); return(renderer.CreateTextBlock()); } } return(string.Format("{0} ({1})", code.Name, opCodeHex)); } else if (segment.Reference is MemberReference) { MemberReference mr = (MemberReference)segment.Reference; // if possible, resolve the reference if (mr is TypeReference) { mr = ((TypeReference)mr).Resolve() ?? mr; } else if (mr is MethodReference) { mr = ((MethodReference)mr).Resolve() ?? mr; } XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr)); try { XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module); if (docProvider != null) { string documentation = docProvider.GetDocumentation(XmlDocKeyProvider.GetKey(mr)); if (documentation != null) { renderer.AppendText(Environment.NewLine); renderer.AddXmlDocumentation(documentation); } } } catch (XmlException) { // ignore } return(renderer.CreateTextBlock()); } return(null); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, CallSite site) { if (site == null) { throw new ArgumentNullException("site"); } if (opcode.Code != Code.Calli) { throw new ArgumentException("code"); } return(new Instruction(opcode, site)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, TypeReference type) { if (type == null) { throw new ArgumentNullException("type"); } if (opcode.OperandType != OperandType.InlineType && opcode.OperandType != OperandType.InlineTok) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, type)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, VariableDefinition variable) { if (variable == null) { throw new ArgumentNullException("variable"); } if (opcode.OperandType != OperandType.ShortInlineVar && opcode.OperandType != OperandType.InlineVar) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, variable)); }
public static Instruction Create(Mono.Cecil.Cil.OpCode opcode, FieldReference field) { if (field == null) { throw new ArgumentNullException("field"); } if (opcode.OperandType != OperandType.InlineField && opcode.OperandType != OperandType.InlineTok) { throw new ArgumentException("opcode"); } return(new Instruction(opcode, field)); }
public void FindNewBlocks(Assembly assembly) { // Do not analyze Campy modules generally... if (Options.Singleton.Get(Options.OptionType.DoNotAnalyzeCampyAssemblies)) { return; } // Starting from all blocks in this assembly, // find all PFE's, then compute control-flow/ // data-flow analysis in order to compute call // structure and new blocks to analyze. List <Inst> pfe_list = new List <Inst>(); List <CFG.CFGVertex> pfe_entries = new List <CFGVertex>(); // Find all pfe's all nodes in assembly. foreach (CFG.CFGVertex node in this.VertexNodes) { foreach (Inst inst in node._instructions) { Mono.Cecil.Cil.OpCode op = inst.OpCode; Mono.Cecil.Cil.FlowControl fc = op.FlowControl; object operand = inst.Operand; Mono.Cecil.MethodReference call_to = operand as Mono.Cecil.MethodReference; if (fc == Mono.Cecil.Cil.FlowControl.Call) { if (call_to != null && call_to.Name.Equals("For") && call_to.DeclaringType != null && call_to.DeclaringType.FullName.Equals("Campy.Parallel")) { System.Console.WriteLine("Found PFE in block " + node.Name); pfe_list.Add(inst); } } } } // Convert PFE instructions into a list of entries. foreach (Inst inst in pfe_list) { CFG.CFGVertex entry = FindEntry(inst); if (!pfe_entries.Contains(entry)) { pfe_entries.Add(entry); } } // Perform sparse data flow propagation in order to // get all indirect calls. Add those blocks to the graph. this._cfa.SparseDataFlowPropagation(pfe_entries); }
public override void Visit(Model.Bytecode.LoadMethodAddressInstruction instruction) { Cecil.Cil.OpCode op = Cecil.Cil.OpCodes.Ldftn; if (instruction.Operation == AnalysisNet.Bytecode.LoadMethodAddressOperation.Virtual) { op = Cecil.Cil.OpCodes.Ldvirtftn; } Cecil.Cil.Instruction cilIns = processor.Create(op, referenceGenerator.MethodReference(instruction.Method)); Result = new List <Mono.Cecil.Cil.Instruction>() { cilIns }; }
static OpCode FindOpcode(Cecil.Cil.OpCode cop) { if (cop.Name == "constrained.") { return(OpCodes.Constrained); } var opType = typeof(OpCodes).GetFields().FirstOrDefault((op) => { return(op.Name.ToLower().Replace('_', '.') == cop.Name); }); if (opType == null) { throw new Exception($"Unsupported opcode: {cop.Name}"); } return((OpCode)opType.GetValue(null)); }
private void ExtractBasicBlocksOfMethod(MethodDefinition definition) { _done.Add(definition); // Make sure definition assembly is loaded. String full_name = definition.Module.FullyQualifiedName; LoadAssembly(full_name); if (definition.Body == null) { System.Console.WriteLine("WARNING: METHOD BODY NULL! " + definition); return; } int instruction_count = definition.Body.Instructions.Count; StackQueue <Mono.Cecil.Cil.Instruction> leader_list = new StackQueue <Mono.Cecil.Cil.Instruction>(); // Each method is a leader of a block. CFGVertex v = (CFGVertex)this.AddVertex(_node_number++); v.Method = definition; v.HasReturnValue = definition.IsReuseSlot; v._entry = v; this._entries.Add(v); v._ordered_list_of_blocks = new List <CFGVertex>(); v._ordered_list_of_blocks.Add(v); for (int j = 0; j < instruction_count; ++j) { // accumulate jump to locations since these split blocks. Mono.Cecil.Cil.Instruction mi = definition.Body.Instructions[j]; //System.Console.WriteLine(mi); Inst i = Inst.Wrap(mi, this); Mono.Cecil.Cil.OpCode op = i.OpCode; Mono.Cecil.Cil.FlowControl fc = op.FlowControl; v._instructions.Add(i); // Verify that mi not owned already. CFG.CFGVertex asdfasdf; Debug.Assert(!partition_of_instructions.TryGetValue(mi, out asdfasdf)); // Update ownership. partition_of_instructions.Add(mi, v); if (fc == Mono.Cecil.Cil.FlowControl.Next) { continue; } if (fc == Mono.Cecil.Cil.FlowControl.Branch || fc == Mono.Cecil.Cil.FlowControl.Cond_Branch) { // Save leader target of branch. object o = i.Operand; // Two cases that I know of: operand is just and instruction, // or operand is an array of instructions (via a switch instruction). Mono.Cecil.Cil.Instruction oo = o as Mono.Cecil.Cil.Instruction; Mono.Cecil.Cil.Instruction[] ooa = o as Mono.Cecil.Cil.Instruction[]; if (oo != null) { leader_list.Push(oo); } else if (ooa != null) { foreach (Mono.Cecil.Cil.Instruction ins in ooa) { Debug.Assert(ins != null); leader_list.Push(ins); } } else { throw new Exception("Unknown operand type for basic block partitioning."); } } } StackQueue <int> ordered_leader_list = new StackQueue <int>(); for (int j = 0; j < instruction_count; ++j) { // Order jump targets. These denote locations // where to split blocks. However, it's ordered, // so that splitting is done from last instruction in block // to first instruction in block. Mono.Cecil.Cil.Instruction i = definition.Body.Instructions[j]; //System.Console.WriteLine("Looking for " + i); if (leader_list.Contains(i)) { ordered_leader_list.Push(j); } } // Split block at jump targets in reverse. while (ordered_leader_list.Count > 0) { int i = ordered_leader_list.Pop(); CFG.CFGVertex new_node = v.Split(i); } //this.Dump(); StackQueue <CFG.CFGVertex> stack = new StackQueue <CFG.CFGVertex>(); foreach (CFG.CFGVertex node in this.VertexNodes) { stack.Push(node); } while (stack.Count > 0) { // Split blocks at branches, not including calls, with following // instruction a leader of new block. CFG.CFGVertex node = stack.Pop(); int node_instruction_count = node._instructions.Count; for (int j = 0; j < node_instruction_count; ++j) { Inst i = node._instructions[j]; Mono.Cecil.Cil.OpCode op = i.OpCode; Mono.Cecil.Cil.FlowControl fc = op.FlowControl; if (fc == Mono.Cecil.Cil.FlowControl.Next) { continue; } if (fc == Mono.Cecil.Cil.FlowControl.Call) { continue; } if (fc == Mono.Cecil.Cil.FlowControl.Meta) { continue; } if (fc == Mono.Cecil.Cil.FlowControl.Phi) { continue; } if (j + 1 >= node_instruction_count) { continue; } CFG.CFGVertex new_node = node.Split(j + 1); stack.Push(new_node); break; } } //this.Dump(); stack = new StackQueue <CFG.CFGVertex>(); foreach (CFG.CFGVertex node in this.VertexNodes) { stack.Push(node); } while (stack.Count > 0) { // Add in all final non-fallthrough branch edges. CFG.CFGVertex node = stack.Pop(); int node_instruction_count = node._instructions.Count; Inst i = node._instructions[node_instruction_count - 1]; Mono.Cecil.Cil.OpCode op = i.OpCode; Mono.Cecil.Cil.FlowControl fc = op.FlowControl; switch (fc) { case Mono.Cecil.Cil.FlowControl.Branch: case Mono.Cecil.Cil.FlowControl.Cond_Branch: { // Two cases: i.Operand is a single instruction, or an array of instructions. if (i.Operand as Mono.Cecil.Cil.Instruction != null) { Mono.Cecil.Cil.Instruction target_instruction = i.Operand as Mono.Cecil.Cil.Instruction; CFGVertex target_node = this.VertexNodes.First( (CFGVertex x) => { if (!x._instructions.First().Instruction.Equals(target_instruction)) { return(false); } return(true); }); if (Options.Singleton.Get(Options.OptionType.DisplaySSAComputation)) { System.Console.WriteLine("Create edge a " + node.Name + " to " + target_node.Name); } this.AddEdge(node, target_node); } else if (i.Operand as Mono.Cecil.Cil.Instruction[] != null) { foreach (Mono.Cecil.Cil.Instruction target_instruction in (i.Operand as Mono.Cecil.Cil.Instruction[])) { CFGVertex target_node = this.VertexNodes.First( (CFGVertex x) => { if (!x._instructions.First().Instruction.Equals(target_instruction)) { return(false); } return(true); }); System.Console.WriteLine("Create edge a " + node.Name + " to " + target_node.Name); this.AddEdge(node, target_node); } } else { throw new Exception("Unknown operand type for conditional branch."); } break; } case Mono.Cecil.Cil.FlowControl.Break: break; case Mono.Cecil.Cil.FlowControl.Call: { // We no longer split at calls. Splitting causes // problems because interprocedural edges are // produced. That's not good because it makes // code too "messy". break; object o = i.Operand; if (o as Mono.Cecil.MethodReference != null) { Mono.Cecil.MethodReference r = o as Mono.Cecil.MethodReference; Mono.Cecil.MethodDefinition d = r.Resolve(); IEnumerable <CFGVertex> target_node_list = this.VertexNodes.Where( (CFGVertex x) => { return(x.Method.FullName == r.FullName && x._entry == x); }); int c = target_node_list.Count(); if (c >= 1) { // target_node is the entry for a method. Also get the exit. CFGVertex target_node = target_node_list.First(); CFGVertex exit_node = target_node.Exit; // check if this is a recursive call. DO NOT BOTHER!! if (node.Method == target_node.Method) { } else { // Create edges from exit to successor blocks of the call. foreach (CFGEdge e in node._Successors) { System.Console.WriteLine("Create edge c " + exit_node.Name + " to " + e.to.Name); this._interprocedure_graph.AddEdge(exit_node, e.to); } // Create edge from node to method entry. System.Console.WriteLine("Create edge b " + node.Name + " to " + target_node.Name); this._interprocedure_graph.AddEdge(node, target_node); } } } break; } case Mono.Cecil.Cil.FlowControl.Meta: break; case Mono.Cecil.Cil.FlowControl.Next: break; case Mono.Cecil.Cil.FlowControl.Phi: break; case Mono.Cecil.Cil.FlowControl.Return: break; case Mono.Cecil.Cil.FlowControl.Throw: break; } } //this.Dump(); }
public Mono.Cecil.Cil.Instruction CreateInstruction(Mono.Cecil.Cil.ILProcessor worker, Mono.Cecil.Cil.OpCode opcode) { throw new NotImplementedException(); }
internal Instruction(int offset, Mono.Cecil.Cil.OpCode opCode) { this.offset = offset; this.opcode = opCode; }
internal Instruction(Mono.Cecil.Cil.OpCode opcode, object operand) { this.opcode = opcode; this.operand = operand; }
void TextViewMouseHover(object sender, MouseEventArgs e) { TextViewPosition?position = textEditor.TextArea.TextView.GetPosition(e.GetPosition(textEditor.TextArea.TextView) + textEditor.TextArea.TextView.ScrollOffset); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value); ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); if (tooltip != null) { tooltip.IsOpen = false; } if (content != null) { tooltip = new ToolTip() { Content = content, IsOpen = true } } ; } object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is Mono.Cecil.Cil.OpCode) { Mono.Cecil.Cil.OpCode code = (Mono.Cecil.Cil.OpCode)segment.Reference; string encodedName = code.Code.ToString(); string opCodeHex = code.Size > 1 ? string.Format("0x{0:x2}{1:x2}", code.Op1, code.Op2) : string.Format("0x{0:x2}", code.Op2); string documentationFile = FindDocumentation("mscorlib.xml"); string text = ""; if (documentationFile != null) { XmlDocumentationProvider provider = new XmlDocumentationProvider(documentationFile); string documentation = provider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + encodedName); if (documentation != null) { text = StripXml(documentation); } } return(string.Format("{0} ({1}): {2}", code.Name, opCodeHex, text)); } return(null); } string StripXml(string xmlText) { try { using (XmlTextReader xml = new XmlTextReader(new StringReader(xmlText))) { StringBuilder ret = new StringBuilder(); while (xml.Read()) { if (xml.NodeType == XmlNodeType.Element) { string elname = xml.Name.ToLowerInvariant(); switch (elname) { case "summary": break; case "br": case "para": ret.AppendLine(); break; default: xml.Skip(); break; } } else if (xml.NodeType == XmlNodeType.Text) { ret.Append(Regex.Replace(xml.Value, @"\s+", " ")); } } return(ret.ToString()); } } catch (XmlException) { return(null); // invalid XML docu } } string FindDocumentation(string fileName) { string path = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); List <string> names = new List <string>(); EnumerateCultures(CultureInfo.CurrentCulture, names); names.Add("en"); names.Add("en-US"); names.Add("en-GB"); foreach (string name in names) { string location = Path.Combine(path, name, fileName); if (File.Exists(location)) { return(location); } } path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"); string loc = Path.Combine(path, fileName); if (File.Exists(loc)) { return(loc); } return(null); } void EnumerateCultures(CultureInfo info, List <string> names) { while (info != null) { names.Add(info.Name); info = info.Parent; if (info == info.Parent) { return; } } }
void TextViewMouseHover(object sender, MouseEventArgs e) { TextViewPosition?position = textEditor.TextArea.TextView.GetPosition(e.GetPosition(textEditor.TextArea.TextView) + textEditor.TextArea.TextView.ScrollOffset); if (position == null) { return; } int offset = textEditor.Document.GetOffset(position.Value.Location); if (referenceElementGenerator.References == null) { return; } ReferenceSegment seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault(); if (seg == null) { return; } object content = GenerateTooltip(seg); if (tooltip != null) { tooltip.IsOpen = false; } if (content != null) { tooltip = new ToolTip() { Content = content, IsOpen = true } } ; } object GenerateTooltip(ReferenceSegment segment) { if (segment.Reference is Mono.Cecil.Cil.OpCode) { Mono.Cecil.Cil.OpCode code = (Mono.Cecil.Cil.OpCode)segment.Reference; string encodedName = code.Code.ToString(); string opCodeHex = code.Size > 1 ? string.Format("0x{0:x2}{1:x2}", code.Op1, code.Op2) : string.Format("0x{0:x2}", code.Op2); XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation; if (docProvider != null) { string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + encodedName); if (documentation != null) { XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(string.Format("{0} ({1}) - ", code.Name, opCodeHex)); renderer.AddXmlDocumentation(documentation); return(renderer.CreateTextBlock()); } } return(string.Format("{0} ({1})", code.Name, opCodeHex)); } else if (segment.Reference is MemberReference) { MemberReference mr = (MemberReference)segment.Reference; // if possible, resolve the reference if (mr is TypeReference) { mr = ((TypeReference)mr).Resolve() ?? mr; } else if (mr is MethodReference) { mr = ((MethodReference)mr).Resolve() ?? mr; } XmlDocRenderer renderer = new XmlDocRenderer(); renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr)); try { XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module); if (docProvider != null) { string documentation = docProvider.GetDocumentation(XmlDocKeyProvider.GetKey(mr)); if (documentation != null) { renderer.AppendText(Environment.NewLine); renderer.AddXmlDocumentation(documentation); } } } catch (XmlException) { // ignore } return(renderer.CreateTextBlock()); } return(null); }
/// <summary> /// Creates a CIL instruction that is emitted as-is. /// </summary> /// <param name="op">The opcode to emit.</param> public CilOpInstruction(OpCode op) : this(CilInstruction.Create(op), null) { }