根据方法名获取方法Body Content
利用 MethodBody类的GetILAsByteArray方法可以获取到返回字节数组的MSIL的body。然后再去解析此字节数组, 可以得到MSIL,然后你再去解析MSIL,你就可以得到你想到source code,这样就可以做小的反....,以下是代码的实现....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit; namespace Timwi.ILReaderExample
{
public class ILReader
{
public class Instruction
{
public int StartOffset
{
get; private set;
}
public OpCode OpCode
{
get; private set;
}
public long? Argument
{
get; private set;
}
public Instruction(int startOffset, OpCode opCode, long? argument)
{
StartOffset = startOffset;
OpCode = opCode;
Argument = argument;
}
public override string ToString()
{
return OpCode.ToString() + (Argument == null ? string.Empty : " " + Argument.Value);
}
} private Dictionary<short, OpCode> _opCodeList; public ILReader()
{
_opCodeList = typeof(OpCodes).GetFields().Where(f => f.FieldType == typeof(OpCode)).Select(f => (OpCode)f.GetValue(null)).ToDictionary(o => o.Value);
} public IEnumerable<Instruction> ReadIL(MethodBase method)
{
MethodBody body = method.GetMethodBody();
if (body == null)
yield break; int offset = ;
byte[] il = body.GetILAsByteArray();
while (offset < il.Length)
{
int startOffset = offset;
byte opCodeByte = il[offset];
short opCodeValue = opCodeByte;
offset++; // If it's an extended opcode then grab the second byte. The 0xFE prefix codes aren't marked as prefix operators though.
if (opCodeValue == 0xFE || _opCodeList[opCodeValue].OpCodeType == OpCodeType.Prefix)
{
opCodeValue = (short)((opCodeValue << ) + il[offset]);
offset++;
} OpCode code = _opCodeList[opCodeValue]; Int64? argument = null; int argumentSize = ;
if (code.OperandType == OperandType.InlineNone)
argumentSize = ;
else if (code.OperandType == OperandType.ShortInlineBrTarget || code.OperandType == OperandType.ShortInlineI || code.OperandType == OperandType.ShortInlineVar)
argumentSize = ;
else if (code.OperandType == OperandType.InlineVar)
argumentSize = ;
else if (code.OperandType == OperandType.InlineI8 || code.OperandType == OperandType.InlineR)
argumentSize = ;
else if (code.OperandType == OperandType.InlineSwitch)
{
long num = il[offset] + (il[offset + ] << ) + (il[offset + ] << ) + (il[offset + ] << );
argumentSize = (int)( * num + );
} // This does not currently handle the 'switch' instruction meaningfully.
if (argumentSize > )
{
Int64 arg = ;
for (int i = ; i < argumentSize; ++i)
{
Int64 v = il[offset + i];
arg += v << (i * );
}
argument = arg;
offset += argumentSize;
} yield return new Instruction(startOffset, code, argument);
}
}
} public static partial class Program
{
public static void Main(string[] args)
{
var reader = new ILReader();
var module = typeof(Program).Module;
foreach (var instruction in reader.ReadIL(typeof(Program).GetMethod("Main")))
{
string arg = instruction.Argument.ToString();
if (instruction.OpCode == OpCodes.Ldfld || instruction.OpCode == OpCodes.Ldflda || instruction.OpCode == OpCodes.Ldsfld || instruction.OpCode == OpCodes.Ldsflda || instruction.OpCode == OpCodes.Stfld)
arg = module.ResolveField((int)instruction.Argument).Name;
else if (instruction.OpCode == OpCodes.Call || instruction.OpCode == OpCodes.Calli || instruction.OpCode == OpCodes.Callvirt)
arg = module.ResolveMethod((int)instruction.Argument).Name;
else if (instruction.OpCode == OpCodes.Newobj)
// This displays the type whose constructor is being called, but you can also determine the specific constructor and find out about its parameter types
arg = module.ResolveMethod((int)instruction.Argument).DeclaringType.FullName;
else if (instruction.OpCode == OpCodes.Ldtoken)
arg = module.ResolveMember((int)instruction.Argument).Name;
else if (instruction.OpCode == OpCodes.Ldstr)
arg = module.ResolveString((int)instruction.Argument);
else if (instruction.OpCode == OpCodes.Constrained || instruction.OpCode == OpCodes.Box)
arg = module.ResolveType((int)instruction.Argument).FullName;
else if (instruction.OpCode == OpCodes.Switch)
// For the 'switch' instruction, the "instruction.Argument" is meaningless. You'll need extra code to handle this.
arg = "?";
Console.WriteLine(instruction.OpCode + " " + arg);
}
Console.ReadLine();
}
}
}
根据方法名获取方法Body Content的更多相关文章
- VS导出方法名和方法备注的方法
VS导出方法名和方法备注的方法 方法一: 只能导出图片格式的UML 类图 1.点击查看类图 2.在空白处点击讲关系导出为图像 方法二: 是把整个类库的方法名都罗列出来 这个方便整理一些 具体方法如下 ...
- Asp.net .net(C#) 获取当前命名空间,类名,方法名的方法
public static string GetMethodInfo() { string str = ""; //取得当前方法命名空间 str += & ...
- .NET C#-- 利用BeginInvoke与EndInvoke完成异步委托方法并获取方法执行返回值示例
//定义委托 delegate string MyDelegate(string name); //定义委托调用函数 public string Hello(string name) { Thread ...
- localstorage和cookie的设置方法和获取方法
1.设置localStorage window.localStorage.setItem(vm.mobileSelf,JSON.stringify(contactInfo)); vm.mobileSe ...
- Java学习-024-获取当前类名或方法名二三文
今天,看朋友编写程序,打印日志时,需要记录当前类的类名以及当前方法的方法名,我发现 TA 将类名或者方法名直接写死在了代码中...虽说这样可以实现记录类名和方法名,但是当有特殊情况需要修改类名或者方法 ...
- java 反射机制之 getDeclaredMethod()获取方法,然后invoke执行实例对应的方法
关于反射中getDeclaredMethod().invoke()的学习,来源于项目中的一行代码: SubjectService.class.getDeclaredMethod(autoMatchCo ...
- java基础:方法的定义和调用详细介绍,方法同时获取数组最大值和最小值,比较两个数组,数组交换最大最小值,附练习案列
1. 方法概述 1.1 方法的概念 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建才可以使用,该过程成为方法定义 方法创建后并不是直接可 ...
- AOP方法拦截获取参数上的注解
https://www.jianshu.com/p/f5c7417a75f9 获取参数注解 在spring aop中,无论是前置通知的参数JoinPoint,还是环绕通知的参数ProceedingJo ...
- java方法句柄-----2.方法句柄的获取、变换、特殊方法句柄
目录 1.获取方法句柄 1.1查找构造方法.一般方法和静态方法的方法句柄 1.2 查找类中的特殊方法(类中的私有方法) 1.3 查找类中静态域和一般域 1.4 通过反射API得到的Constructo ...
随机推荐
- swift - self的弱引用
1. weak var weakSelf = self 2. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {[weak se ...
- how2j学习日志——J2EE(2018年3月28日)
1. 开始跟着站长学习J2EE,首页是简单的Tomcat安装和部署,我从官网上下载的是7.0.85版本,修改server.xml中的默认端口号为80.80端口是web服务的默认端口,因此在浏览器上输入 ...
- golang语言中sync/atomic包的学习与使用
package main; import ( "sync/atomic" "fmt" "sync" ) //atomic包提供了底层的原子级 ...
- webstorm配置node.js
1.确保电脑已经安装好了node.js
- Linux移植之子目录下的built-in.o生成过程分析
在Linux移植之make uImage编译过程分析中罗列出了最后链接生成vmlinux的过程.可以看到在每个子目录下都有一个built-in.o文件.对于此产生了疑问built-in.o文件是根据什 ...
- laravel框架数据迁移
迁移就像数据库的版本控制,允许团队简单轻松的编辑并共享应用的数据库表结构,迁移通常和Laravel 的 schema 构建器结对从而可以很容易地构建应用的数据库表结构.如果你曾经告知小组成员需要手动添 ...
- iis日志分析软件及大文本切割软件下载
在网上找了好几个日志分析软件,觉得这个是最简单.实用的,至少对我来说. 但这个软件有个缺点,就是日志比较大时,分析详细的会溢出,需要用到文本切割工具. 软件下载: iis日志分析软件 大文本切割软件 ...
- java基础之—类加载器
要了解类加载器先要了解类的加载 一.类的加载(类的加载概述) 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 1.加载 就是指将clas ...
- 设计服务类网站原型模板分享——Fortyseven
Fortyseven是一个设计服务网站,设计理念是帮助企业设计出赚钱的品牌和网站.该网站图文排版配色都很不错,很有欧美复古风,多采用大图结合文案排版. 本原型由国产Mockplus(原型工具)和iDo ...
- python 读取xml
#!/usr/bin/python # -*- coding: UTF- -*- from xml.dom.minidom import parse import xml.dom.minidom # ...