根据方法名获取方法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 ...
随机推荐
- ztree-持续更新中
版本v3快速入门: 1,官网下载https://gitee.com/zTree/zTree_v3 2,zTree-zTree_v3-master\zTree_v3下复制css和js文件夹到项目下 3, ...
- ATM取款机系统代码及此次作业感受
本次乃我们软件工程专业开学第一个小测试,本来以为是和之前2016级相同的或者类似得软件,所以之前学了好久的那个程序完全失去了它的作用,当然了老师也从来没有按套路出过牌,所以这个下马威我觉得作用起到了. ...
- Java面试基础知识(2)
1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.说说& ...
- MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring
Mybatis在与Spring集成的时候可以配置 MapperFactoryBean来生成Mapper接口的代理. 例如 <bean id="userMapper" clas ...
- IEDriver executable needs to be available in the path
解决办法: 去http://selenium-release.storage.googleapis.com/index.html 下载指定IE版本 解压后 拷贝到Python的目录下 重新运行,提示错 ...
- pthreads v3下的同步处理synchronized
之所以会用到同步,是因为如果多个线程中对同一个资源进行操作时,会发生混乱. 比如2个线程对变量进行加1操作,第1个线程还没来的及改写数据时,第2个线程就对变量进行操作了,那变量最终的结果就是未知的,这 ...
- 在pom.xml中引入jar包坐标的依赖范围
A依赖B,需要在A的pom.xml文件中添加B的坐标,添加坐标时需要指定依赖范围,依赖范围包括: compile:编译范围,指A在编译时依赖B,此范围为默认依赖范围.编译范围的依赖会用在编译.测试.运 ...
- Quartus11中新建工程
最近在使用CycloneII的开发板,但是高版本的Quartus不支持II系列的开发,于是只能用Q11了.好久没玩FPGA了,新建工程的过程中遇到了一些问题,这里把这些问题记下了以便以后查看. Qua ...
- istream_iterator和ostream_iterator
总结: istream_iterator<T>in(strm);T指明此istream_iterator的输入类型,strm为istream_iterator指向的流 提供了输入操作符(& ...
- 继承 (js原型链)
原型链是实现继承的主要方法.基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法. 1.构造函数.原型.实例的关系: 每个构造函数都有原型属性(Prototype),指向一个原型对象(函数创 ...