根据方法名获取方法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 ...
随机推荐
- 把leveldb嵌入到redis.实现真正的数据持久存储
目前最新版RedisStorage 是基于 redis 2.6.2基础上,加上 leveldb存储引擎. 这个项目是源于 公司项目的passport 用户认证改造.公司一个项目运行了N年.积累了几千万 ...
- linux命令学习之:cp
cp命令用来复制文件或者目录,是Linux系统中最常用的命令之一. 如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中.若同时指定多个文 ...
- git add 文件夹
1. 本地新建好文件夹,在文件夹里新建*.md 2. 切换到文件夹父目录 3. git add 文件夹名 4. git commit 5. git push
- Android TV开发 焦点控制
转载:http://www.eoeandroid.com/thread-264177-1-1.html 最近在做一款基于Android的互联网电视客户端,开发与phone/pad差不多,但是有一个值得 ...
- jq以固定开头的class属性的名称
$("div[class^='pick']").css({'border-color':'#000000'}); div [class^="aaa"]
- vue2.0细节剖析
1.样式切换 单个切换样式 /*html部分*/ <div class="bg" v-bind:class="{active:isActive}"> ...
- 内置函数 hashlib configparser logging 模块 C/S B/S架构
1.内置函数 # 内置的方法有很多 # 不一定全都在object中 # class Classes: # def __init__(self,name): # self.name = name # s ...
- Oracle_PL/SQL(8) 动态sql
动态sql0.pl/sql块的限制 不能执行ddl操作(create.drop.alter): 不能执行部分dcl操作(grant.revoke). 1.语法动态sql:在执行时才能确定要执行的sql ...
- 4K - 找新朋友
新年快到了,“猪头帮协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道 ...
- (转)EasyUI 分页总结
最近用到了easyui的分页和搜索栏功能,使用过程中由于运用不熟练导致其间也出现过一些问题,下面做个小结,供大家共同学习.1.首先使用EasyUI 的DataGrid分页,得加载其js类库:< ...