csharp 使用Mono.Cecil和GLEE绘制函数依赖关系的一些代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 使用Mono.Cecil和GLEE绘制函数依赖关系的一些代码相关的知识,希望对你有一定的参考价值。

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Collections.Specialized;
using Microsoft.Glee.GraphViewerGdi;
using Microsoft.Glee.Drawing;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace CecilTest
{
	class Program
	{
		static StringCollection visitedMethodList = new StringCollection();
		static Graph graph;

		static void VisitMethodDefinition(MethodDefinition methodDefinition)
		{
			if (visitedMethodList.Contains(methodDefinition.Name))
				return;
			visitedMethodList.Add(methodDefinition.Name);
			StringCollection visitedDestinationList = new StringCollection();
			if (methodDefinition.Body == null)
				return;
			foreach (Instruction instruction in methodDefinition.Body.Instructions)
			{
				MethodDefinition calledMethodDefinition = instruction.Operand as MethodDefinition;
				if (instruction.OpCode.Name != "call" && instruction.OpCode.Name != "callvirt" || calledMethodDefinition == null)
					continue;
				//Console.WriteLine("{0} {1}", instruction.OpCode, instruction.Operand);
				bool skip = false;
				foreach (CustomAttribute customAttribute in calledMethodDefinition.CustomAttributes)
				{
					if (customAttribute.Constructor.DeclaringType.FullName == "InternalAttribute")
					{
						skip = true;
						break;
					}
				}

				if (skip)
					continue;
				string destination = calledMethodDefinition.Name;
				if (!visitedDestinationList.Contains(destination))
				{
					visitedDestinationList.Add(destination);
					graph.AddEdge(methodDefinition.Name, destination);
					VisitMethodDefinition(calledMethodDefinition);
				}
			}
		}

		static void Main(string[] args)
		{
			graph = new Graph("Call tree");
			AssemblyDefinition assemblyDefinition = AssemblyFactory.GetAssembly(@"..\..\..\Rascal\bin\Release\rascal.exe");
			ModuleDefinition moduleDefinition = assemblyDefinition.MainModule;
			VisitMethodDefinition(moduleDefinition.Types["Rascal.Program"].Methods.GetMethod("Main")[0]);
			graph.FindNode("Main").Attr.Fillcolor = new Microsoft.Glee.Drawing.Color(61, 151, 255);
/*
			foreach (TypeDefinition td in moduleDefinition.Types)
				foreach (MethodDefinition md in td.Methods)
					if (visitedMethodList.Contains(md.Name) == false)
					{
						VisitMethodDefinition(md);
						Node node = graph.FindNode(md.Name);
						if (node != null)
							node.Attr.Fillcolor = new Microsoft.Glee.Drawing.Color(61, 151, 255);
					}
*/
			GraphRenderer graphRenderer = new GraphRenderer(graph);
			graphRenderer.CalculateLayout();
			Bitmap b = new Bitmap((int) graph.Width, (int) graph.Height, PixelFormat.Format24bppRgb);
			graphRenderer.Render(b);
			b.Save(@"..\..\ct.png");
		}
	}
}

以上是关于csharp 使用Mono.Cecil和GLEE绘制函数依赖关系的一些代码的主要内容,如果未能解决你的问题,请参考以下文章

使用Mono Cecil对MSIL进行注入

使用MOno Cecil 的相关开源项目

使用 Mono.Cecil 在 C# 程序集中注入方法

Mono.Cecil - 0.6

If / else and while分支在Mono.Cecil中

Mono.Cecil AddInterfaceImplementation 等效?