编译时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(动态修改程序集插件,很好用,我已经尝试多次)就有他的身影出现。还有如大名鼎鼎的SharpDevelop,LINQPad,Ja.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)的更多相关文章
- 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 ...
- 浅谈.NET编译时注入(C#-->IL)
原文:浅谈.NET编译时注入(C#-->IL) .NET是一门多语言平台,这是我们所众所周知的,其实现原理在于因为了MSIL(微软中间语言)的一种代码指令平台.所以.NET语言的编译就分为了两部 ...
- 使用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的静态注入
Aop注入有2种方式:动态注入和静态注入,其中动态注入有很多实现了 动态注入有几种方式: 利用Remoting的ContextBoundObject或MarshalByRefObject. 动态代理( ...
- 教你怎么用Mono Cecil - 动态注入 (注意代码的注释)
原文 教你怎么用Mono Cecil - 动态注入 (注意代码的注释) 使用 Mono Cecil 进行反编译:using Mono.Cecil; using Mono.Cecil.Cil; //.. ...
- Android APT(编译时代码生成)最佳实践
越来越多第三方库使用apt技术,如DBflow.Dagger2.ButterKnife.ActivityRouter.AptPreferences.在编译时根据Annotation生成了相关的代码,非 ...
- 运用Mono.Cecil 反射读取.NET程序集元数据
CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...
- 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)
原文 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...
- 使用 Mono.Cecil 辅助 Unity3D 手游进行性能测试
Unity3D 引擎在 UnityEngine 名字空间下,提供了 Profiler 类(Unity 5.6 开始似乎改变了这个名字空间),用于辅助对项目性能进行测试.以 Android 平台为例 ...
随机推荐
- [Thu, 9 Jul 2015 ~ Tue, 14 Jul 2015] Deep Learning in arxiv
这一期的神作论文有蛮多的,都很有意思. Feature Representation In ConvolutionalNeural Networks 该论文中论述了在某种CNN结构下,是否有准确率较高 ...
- Golang快速入门
Go语言简介: Golang 简称 Go,是一个开源的编程语言,Go是从2007年末由 Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian L ...
- 怎样在log4j.xml配置文件中引入变量:小公司经验较多的我和阿里UC等大公司经验较多的Boss,一些技术交流和探讨
从最初学习使用log4j的时候,网上和书本上主要都是使用"log4j.properties"这种属性格式,配置日志.多年以来,一直使用这种格式,总的来说,简单.够用. 而有十 ...
- linux下Java程序中插入DB中国的数据乱码问题
首先,插入到DB数据,在Linux在查询时,现场展示??. 再次,在windows连接到db上,查看的结果并非乱码. 改动Eclipse软件中的编码:如上图:windows菜单->prefere ...
- C#编写TensorFlow人工智能应用
C#编写TensorFlow人工智能应用 TensorFlowSharp入门使用C#编写TensorFlow人工智能应用学习. TensorFlow简单介绍 TensorFlow 是谷歌的第二代机器学 ...
- ajax的跨域请求问题:减少options请求
服务器端在Response Headers里添加字段Access-Control-Max-Age: 86400 , "Access-Control-Max-Age"表明在86400 ...
- NFS Server搭建实践
NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系统能够彼此分享个 ...
- java 多线程以及线程池
1.多线程可以使程序反应更快,交互性更强,执行效率最高. 2.创建一个线程: 要实现Runnable 接口,创建Thread类的对象,用start开始执行线程. 3.使用Thread中的yield( ...
- 创Python规划2
于Milang的IDE多年的编辑后,,然后按F5关于实施.这将是在下面Output输出形式"Hello, World!"弦,例如下面的附图: watermark/2/text/aH ...
- Asp.net固定功能位充满了零(解决,演示样本)!
Asp.net固定功能位充满了零(解决.演示样本)! 在发展,其中,数实现出现8数字.但是,需要使用0加厚.例如:123,代表:0000123. 真实的比例,如下: decimal aaa = 123 ...