原文:编译时MSIL注入--实践Mono Cecil(1)

紧接上两篇浅谈.NET编译时注入(C#-->IL)浅谈VS编译自定义编译任务—MSBuild Task(csproject),在第一篇中我们简单研究了c#语法糖和PostSharp的MSIl注入,紧接第二篇中我们介绍了自定义MSBuild编译任务(记得有位老兄发链接用 MSBuild自动发布Silverlight xap ,我想说的我做的是自定义编译任务,不是什么发布,MSBuild本就是一个发布工具)。之所以在此前介绍编译Task是因为我讲介绍的就是利用MSBuild和MSILInject制作静态注入式AOP,想成熟的产品PostSharp,当然我也不会去重造轮子,但需要明白起原理和自动化注入时机。废话不多说,今天将请出我们的MSIL注入的好东西:Mono.Cecil.官方网站http://www.mono-project.com/Cecil,他是一个强大的MSIL 注入工具,在我们的Reflector插件Reflexil(动态修改程序集插件,很好用,我已经尝试多次)就有他的身影出现。还有如大名鼎鼎的SharpDevelopLINQPadJa.NET等等(可以参见https://github.com/jbevain/cecil/wiki/Users)。

在本节我们需要看看这个Mono.Cecil,先来一个简单的认识。

我来在我们的方法执行前后加入我们的输出信息:

原来代码:

class Program 
   { 
       static void Main(string[] args) 
       { 
           Console.WriteLine("破浪Blog:http://www.cnblogs.com/whitewolf/"); 
       } 
   }

任务:

1我将在方法执行前后添加一个Console.WriteLine("Method start…");

2方法最后添加Console.WriteLine("Method finish…“);

具体Mono.Cecil Code:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Mono.Cecil; 
using Mono.Cecil.Cil;  namespace BlogSample 

    class Program 
    { 
        static void Main(string[] args) 
        { 
            AssemblyDefinition assembiy = AssemblyFactory.GetAssembly(args[]); //后期版本AssemblyFactory已被去掉,改用AssemblyDefinition.ReadAssembly(fileName);
            foreach (Mono.Cecil.TypeDefinition item in assembiy.MainModule.Types) 
            { 
                foreach (MethodDefinition method in item.Methods) 
                { 
                    if (method.Name.Equals("Main")) 
                    {                          var ins = method.Body.Instructions[]; 
                        var worker = method.Body.CilWorker; 
                        worker.InsertBefore(ins, worker.Create(OpCodes.Ldstr, "Method start…")); 
                        worker.InsertBefore(ins, worker.Create(OpCodes.Call, 
                            assembiy.MainModule.Import(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })))); 
                        ins = method.Body.Instructions[method.Body.Instructions.Count - ];                          worker.InsertBefore(ins, worker.Create(OpCodes.Ldstr, "Method finish…")); 
                        worker.InsertBefore(ins, worker.Create(OpCodes.Call, 
                            assembiy.MainModule.Import(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })))); 
                        break; 
                    } 
                }              }              AssemblyFactory.SaveAssembly(assembiy, "IL_" + args[]); //后期版本:assembiy.Write(fileName);
            Console.Read(); 
        } 
    } 
}

DOS运行结果:

我们在来看看反编译后的MSIL

C#:

在这最后我们可以想一下,如果我们利用Mono.Cecil可以干些什么事情,能做的当然很多,我首先想尝试的了与上一节浅谈VS编译自定义编译任务—MSBuild Task(csproject)结合PostSharp一样的静态注入AOP框架。还能做什么的就要靠大家发挥大家聪明的才智。

编译时MSIL注入--实践Mono Cecil(1)的更多相关文章

  1. Compile-time Dependency Injection With Go Cloud's Wire 编译时依赖注入 运行时依赖注入

    Compile-time Dependency Injection With Go Cloud's Wire - The Go Blog https://blog.golang.org/wire Co ...

  2. 浅谈.NET编译时注入(C#-->IL)

    原文:浅谈.NET编译时注入(C#-->IL) .NET是一门多语言平台,这是我们所众所周知的,其实现原理在于因为了MSIL(微软中间语言)的一种代码指令平台.所以.NET语言的编译就分为了两部 ...

  3. 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络

    目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7.  怎么调用别的程序集的方法示例 8. [is declared in another module ...

  4. 基于Mono.Cecil的静态注入

    Aop注入有2种方式:动态注入和静态注入,其中动态注入有很多实现了 动态注入有几种方式: 利用Remoting的ContextBoundObject或MarshalByRefObject. 动态代理( ...

  5. 教你怎么用Mono Cecil - 动态注入 (注意代码的注释)

    原文 教你怎么用Mono Cecil - 动态注入 (注意代码的注释) 使用 Mono Cecil 进行反编译:using Mono.Cecil; using Mono.Cecil.Cil; //.. ...

  6. Android APT(编译时代码生成)最佳实践

    越来越多第三方库使用apt技术,如DBflow.Dagger2.ButterKnife.ActivityRouter.AptPreferences.在编译时根据Annotation生成了相关的代码,非 ...

  7. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  8. 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)

    原文 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...

  9. 使用 Mono.Cecil 辅助 Unity3D 手游进行性能测试

    Unity3D 引擎在  UnityEngine 名字空间下,提供了  Profiler 类(Unity 5.6 开始似乎改变了这个名字空间),用于辅助对项目性能进行测试.以 Android 平台为例 ...

随机推荐

  1. 【u032】均衡发展

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 神牛小R在许多方面都有着很强的能力,具体的说,他总共有m种能力,并将这些能力编号为1到m.他的能力是一 ...

  2. Go语言学习(十)bytes包处理字节切片

    bytes包提供了对字节切片进行读写操作的一系列函数 字节切片处理的函数比較多,分为基本处理函数,比較函数,后缀检查函数,索引函数,切割函数, 大写和小写处理函数和子切片处理函数等. 1.字节切片基本 ...

  3. 【codeforces 534D】Handshakes

    [题目链接]:http://codeforces.com/contest/534/problem/D [题意] n个人依次进入一个房间; 进进来的人会和房间里面没有组队的人握一次手; (这里的握手只计 ...

  4. mysql创建用户、赋予指定权限命令

    1.远程登录mysql mysql -h ip -u root -p 密码 2.创建用户 格式:grant 权限 on 数据库.* to 用户名@登录主机 identified by "密码 ...

  5. 保护SSD,设置Chrome浏览器临时文件夹到ramdisk分区

    很多用低端/山寨SSD的朋友都用Ramdisk来保护硬盘,一般都把系统temp目录和IE浏览器临时文件夹目录设到Ramdisk分区了.      最近用谷歌的chrome浏览器,发现浏览网页时候硬盘灯 ...

  6. spring mybatis circular reference

    摘要: Error creating bean with name 'XXX': Requested bean is currently in creation: Is there an unreso ...

  7. events(事件): 基础1

    1    所有能触发事件的对象都是 EventEmitter 类的实例. 这些对象开放了一个 eventEmitter.on() 函数,允许将一个或多个函数绑定到会被对象触发的命名事件上. 事件名称通 ...

  8. 推荐5款实用的jQuery时间轴插件

    1.使用CSS3和jQuery制作的水平时间轴 这是一个可以在PC和移动端表现非常棒的水平时间轴,它由上部水平滑块和下部时间点对应的内容区块,点击时间轴上的时间点,下部内容会滑动到对应的内容区块.使用 ...

  9. 键盘各键对应的编码值(key code)

    原文:键盘各键对应的编码值(key code) 来源:http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes ...

  10. CORSFilter

    import java.io.IOException; import javax.servlet.Filter;import javax.servlet.FilterChain;import java ...