Add a try-catch with Mono Cecil
Adding exception handlers with Mono.Cecil is not difficult, it just requires you to know how exception handlers are laid out in the metadata.
Let say you have the C# method:
static void Throw ()
{
throw new Exception ("oups");
}
If you decompile it, it should look somewhat similar to this:
.method private static hidebysig default void Throw () cil managed
{
IL_0000: ldstr "oups"
IL_0005: newobj instance void class [mscorlib]System.Exception::.ctor(string)
IL_000a: throw
}
Now let say that you want to inject code in this method such as it's similar to the C# code:
static void Throw ()
{
try {
throw new Exception ("oups");
} catch (Exception e) {
Console.WriteLine (e);
}
}
That is, you simply want to wrap the existing code in a try catch handler. You can do it easily with Cecil this way:
var method = ...;
var il = method.Body.GetILProcessor ();
var write = il.Create (
OpCodes.Call,
module.Import (typeof (Console).GetMethod ("WriteLine", new [] { typeof (object)})));
var ret = il.Create (OpCodes.Ret);
var leave = il.Create (OpCodes.Leave, ret);
il.InsertAfter (
method.Body.Instructions.Last (),
write);
il.InsertAfter (write, leave);
il.InsertAfter (leave, ret);
var handler = new ExceptionHandler (ExceptionHandlerType.Catch) {
TryStart = method.Body.Instructions.First (),
TryEnd = write,
HandlerStart = write,
HandlerEnd = ret,
CatchType = module.Import (typeof (Exception)),
};
method.Body.ExceptionHandlers.Add (handler);
This code is manipulating the previous method to look like this:
.method private static hidebysig default void Throw () cil managed
{
.maxstack 1
.try { // 0
IL_0000: ldstr "oups"
IL_0005: newobj instance void class [mscorlib]System.Exception::'.ctor'(string)
IL_000a: throw
} // end .try 0
catch class [mscorlib]System.Exception { // 0
IL_000b: call void class [mscorlib]System.Console::WriteLine(object)
IL_0010: leave IL_0015
} // end handler 0
IL_0015: ret
}
We're adding three new instructions: a call to Console.WriteLine, a leave to gracefully exit the catch handler, and finally (pun intended), a ret. Then we're simply creating a ExceptionHandler instance to represent a try catch handler whose try encompasses the existing body, and whose catch is the WriteLine statement.
One important thing to note is that the end instruction of a range is not contained inside the range. It's basically a [TryStart:TryEnd[ range.
Add a try-catch with Mono Cecil的更多相关文章
- 运用Mono.Cecil 反射读取.NET程序集元数据
CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...
- 基于Mono.Cecil的静态注入
Aop注入有2种方式:动态注入和静态注入,其中动态注入有很多实现了 动态注入有几种方式: 利用Remoting的ContextBoundObject或MarshalByRefObject. 动态代理( ...
- 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7. 怎么调用别的程序集的方法示例 8. [is declared in another module ...
- 巧用Mono.Cecil反射加载类型和方法信息
最近在做服务的细粒度治理,统一管理所有服务的方法.参数.返回值信息.方便后续的各个模块之间的对接和协作. 目前系统中所有的服务,管理到接口契约粒度,即服务接口声明和服务接口实现.要做服务的细粒度治理: ...
- Mono.Cecil - 0.6
原文:Mono.Cecil - 0.6 项目地址:Mono.Cecil 项目描述:In simple English, with Cecil, you can load existing manage ...
- c# Mono.Cecil IL方式 读MethodBody
using Kufen.Common.Definitions; using Mono.Cecil; using System; using System.Collections.Generic; us ...
- Mono.Cecil 初探(一):实现AOP
序言 本篇文章介绍基于Mono.Cecil实现静态AOP的两种方式:无交互AOP和交互式AOP. 概念介绍 Mono.Cecil:一个可加载并浏览现有程序集并进行动态修改并保存的.NET框架. AOP ...
- C# Asp.net中的AOP框架 Microsoft.CCI, Mono.Cecil, Typemock Open-AOP API, PostSharp -摘自网络 (可以利用反射 Attribute 进行面向切面编程 可以用在记录整个方法的Log方面)
Both Microsoft.CCI and Mono.Cecil are low-level, and don't validate produced assemblies. It takes lo ...
- 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)
原文 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...
随机推荐
- mysql 存储过程 invoker invoker
方法一:修改存储过程的definer update mysql.proc set definer='root@localhost' where db='db_name'; 方法二:修改sql secu ...
- Mysql: Connect/C++ 使用过程中发现返回 std::string 造成的内存泄露
在使用 Connect/C++ ,测试时发现在调用 getString 出现了内存增长的情况. ConstructOutput(); //打印出当前内存 ;i<;++i) { prepareSt ...
- esayUI实践的一些体会
1.如何在页面中使用 easy ui ? 引入 四个文件 <!-- 引入easy ui --> <link rel="stylesheet" type=" ...
- C#基础教程/适合初学者
C#基础教程 第一章 C#语言基础 本章介绍C#语言的基础知识,希望具有C语言的读者能够基本掌握C#语言,并以此为基础,能够进一步学习用C#语言编写window应用程序和Web应用程序.当 ...
- r 数据分组处理
一.R语言实现数据的分组求和 实验数据集 姓名,年龄,班级 ,成绩, 科目 student <- data.frame ( name = c("s1", "s2&q ...
- MySQL多表数据记录查询详解
在实际应用中,经常需要实现在一个查询语句中显示多张表的数据,这就是所谓的多表数据记录连接查询,简称来年将诶查询. 在具体实现连接查询操作时,首先将两个或两个以上的表按照某个条件连接起来,然后再查询到所 ...
- C++(1)C++类四个默认函数---构造函数、析构函数、拷贝函数、赋值函数
C++构造函数和析构函数 默认构造函数指不带参数或者所有参数都有缺省值的构造函数!!! (1)构造函数.析构函数与赋值函数 构造函数.析构函数与赋值函数是每个类最基本的函数.它们太普通以致让人容易麻痹 ...
- HBase系统入门--整体介绍
转自:http://www.aboutyun.com/thread-8957-1-2.html 问题导读:1.HBase查询与写入哪个更好一些?2.HBase面对复杂操作能否实现?3.Region服务 ...
- 《FPGA全程进阶---实战演练》第二章之焊接板子及调试注意事项
1.若是读者第一次做板子,强烈建议画完PCB板后将PCB图打印出来,然后对照你买的芯片将芯片放置对 应的位置,然后查看所有的封装格式适不适合,否则等你做出板子来后再试,为时晚矣.笔者虽然知道要这么 做 ...
- 【转】Microsoft .Net Remoting之Remoting事件处理全接触
Remoting事件处理全接触 前言:在Remoting中处理事件其实并不复杂,但其中有些技巧需要你去挖掘出来.正是这些技巧,仿佛森严的壁垒,让许多人望而生畏,或者是不知所谓,最后放弃了事件在Remo ...