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的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...
随机推荐
- [转]ListView学习笔记(二)——ViewHolder
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候, ...
- 执行sql出现No Dialect mapping for JDBC type: -9错误
name的数据类型是nvarchar吗?如果是改为varchar类型应该能运行,但是这个治标不治本,这是hibernate没映射nvarchar 刚才整理了一下varchar和nvarchar的区别, ...
- R工具包
直到12月初在微软技术大会,看到我软的工程师演示R的使用,我就震惊了,然后最近在网上到处了解和爬一些R的资料,看着看着就入迷了,这就是个大宝库了,以前怎么没发现,看来还是太狭隘了.直到前几天我看到这个 ...
- 【转】如何搭建IPv6测试你的APP
IPv6的简介 IPv4 和 IPv6的区别就是 IP 地址前者是 .(dot)分割,后者是以 :(冒号)分割的(更多详细信息自行搜索). PS:在使用 IPv6 的热点时候,记得手机开 飞行模式 哦 ...
- mysql的优化:官网地址
http://dev.mysql.com/doc/refman/5.1/zh/optimization.html#index-merge-optimization
- u3d性能优化
原文地址:http://blog.csdn.net/molti/article/details/8520418 性能优化需要从多方面入手,大家在项目中遇到的问题还是很普遍的,欢迎大家补充. 图形方面: ...
- Oracle Net Manager 服务命名配置以及用PL/SQL 登陆数据库
我们知道,要连接一个数据库需要知道四个参数: 1. 登陆用户名:user: 2. 登录密码:password: 3. 存放数据库的服务器地址(server_ip)和端口(server_port): 4 ...
- ubuntu server install 安装中文(搜狗)输入法
1.对于ubuntu server默认无中文输入法框架,我比较倾向于我一直使用的ibus-sunpinyin.这里我需要先安装ibus的框架 不过我遇到了问题: dpkg: dependency pr ...
- window用Xmanager4.0的Xstart连接linux远程桌面
安装包: xorg-x11-xauth xterm.x86_64 0:253-1.el6 Execute command path:/usr/bin/xterm Xstart连接Linux远程桌面有一 ...
- 利用GetType反射方法再调用方法进行传递参数实现调用
直接上代码: TestMenuService.MenuServiceCSClient tesClient = new TestMenuService.MenuServiceCSClient(); va ...