利用 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的更多相关文章

  1. VS导出方法名和方法备注的方法

    VS导出方法名和方法备注的方法 方法一: 只能导出图片格式的UML 类图 1.点击查看类图 2.在空白处点击讲关系导出为图像 方法二: 是把整个类库的方法名都罗列出来 这个方便整理一些 具体方法如下 ...

  2. Asp.net .net(C#) 获取当前命名空间,类名,方法名的方法

    public static string GetMethodInfo() {     string str = "";      //取得当前方法命名空间     str += & ...

  3. .NET C#-- 利用BeginInvoke与EndInvoke完成异步委托方法并获取方法执行返回值示例

    //定义委托 delegate string MyDelegate(string name); //定义委托调用函数 public string Hello(string name) { Thread ...

  4. localstorage和cookie的设置方法和获取方法

    1.设置localStorage window.localStorage.setItem(vm.mobileSelf,JSON.stringify(contactInfo)); vm.mobileSe ...

  5. Java学习-024-获取当前类名或方法名二三文

    今天,看朋友编写程序,打印日志时,需要记录当前类的类名以及当前方法的方法名,我发现 TA 将类名或者方法名直接写死在了代码中...虽说这样可以实现记录类名和方法名,但是当有特殊情况需要修改类名或者方法 ...

  6. java 反射机制之 getDeclaredMethod()获取方法,然后invoke执行实例对应的方法

    关于反射中getDeclaredMethod().invoke()的学习,来源于项目中的一行代码: SubjectService.class.getDeclaredMethod(autoMatchCo ...

  7. java基础:方法的定义和调用详细介绍,方法同时获取数组最大值和最小值,比较两个数组,数组交换最大最小值,附练习案列

    1. 方法概述 1.1 方法的概念 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建才可以使用,该过程成为方法定义 方法创建后并不是直接可 ...

  8. AOP方法拦截获取参数上的注解

    https://www.jianshu.com/p/f5c7417a75f9 获取参数注解 在spring aop中,无论是前置通知的参数JoinPoint,还是环绕通知的参数ProceedingJo ...

  9. java方法句柄-----2.方法句柄的获取、变换、特殊方法句柄

    目录 1.获取方法句柄 1.1查找构造方法.一般方法和静态方法的方法句柄 1.2 查找类中的特殊方法(类中的私有方法) 1.3 查找类中静态域和一般域 1.4 通过反射API得到的Constructo ...

随机推荐

  1. 8.14 git??sourceTree??

    目前这个项目是四个前端在做,我用的版本控制工具是sourceTree,有两个人用的是命令行,厉害.(刚哥说,肯定要会命令行的,(⊙o⊙)好,我学!!) 上周五提交代码时,文件冲突了,而且我给1.3版本 ...

  2. 通过java.net.URLConnection发送HTTP请求(原生、爬虫)

    目录 1. 运用原生Java Api发送简单的Get请求.Post请求 2. 简单封装 3. 简单测试 如何通过Java发送HTTP请求,通俗点讲,如何通过Java(模拟浏览器)发送HTTP请求.Ja ...

  3. StackExchange.Redis使用以及封装

    来源:http://www.cnblogs.com/qtqq/p/5951201.html Redis安装:http://www.runoob.com/redis/redis-install.html ...

  4. idea spring-boot gradle mybatis 搭建开发环境

    使用工具idea 2017.2开发,gradle构建项目,使用的技术有spring-boot.mybatis 1.新建项目 说明:1.src为源码路径,开发主要在src下 2.src/main/jav ...

  5. Window10系统的安装

    关于系统的安装网上有许多的教程,本文的教程并没有什么特别的.只是将自己在安装过程中遇到的问题记录下来,方便以后观看. 1.下载系统镜像 首先从MSDN上下载windows10镜像.在操作系统Windo ...

  6. eclipse集成svn进行项目开发

    在用eclipse进行项目开发的时候,报了一个错误:switch不支持String的参数.这个问题的原因是因为jre版本低于1.7,而当前的eclipse版本最高只能选1.6,无奈,我只能考虑换ecl ...

  7. 1.3 Java中的标识符和关键字

    1.标识符 含义:标识符用于给程序中的类.变量.方法命名的符号. 组成:数字(0-9).字母(a-z)(A-Z).下划线(_).美元符号$. 命名规则:1.数字不能够作为命名符号的开头 2.不能够使用 ...

  8. 还没有写完准备弡上cpickle 还有字典

    #!/usr/bin/python #Filename: cpickle.py import cPickle as p import os shoplistfile="shoplist.da ...

  9. Java的反射技术

    什么是反射机制 Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能调用它的任意属性和方法.这种动态获取信息以及动态调用对象属性和方法的即使称为J ...

  10. robotframework 运行集合

    Robot Framework 运行测试通过 pybot 命令,检查 _C:\Python36\Scripts_ 目录下是否有 pybot.bat 文件,正确安装 Robot Framework 一定 ...