编译时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 平台为例 ...
随机推荐
- 从 BM 到 RBM
1. 拓扑结构上 如下图示,在拓扑结构上,RBM(受限的玻尔兹曼机)与 BM(玻尔兹曼机)的最大区别在于: RBM 取消了可见层的层内连接以及隐含层的层内连接,主要在于 BM 的层内连接使得其学习过程 ...
- activiti自己定义流程之整合(五):启动流程时获取自己定义表单
流程定义部署之后,自然就是流程定义列表了,但和前一节一样的是,这里也是和之前单独的activiti没什么差别.因此也不多说.我们先看看列表页面以及相应的代码,然后在一步步说明点击启动button时怎样 ...
- WPF 文字换行TextWrapping 显示不全用省略号TextTrimming 显示不全弹提示内容ToolTip
原文:WPF 文字换行TextWrapping 显示不全用省略号TextTrimming 显示不全弹提示内容ToolTip [TextBlock] 换行 TextWrapping="W ...
- 【codeforces 534B】Covered Path
[题目链接]:http://codeforces.com/contest/534/problem/B [题意] 你在t秒内可以将车的速度任意增加减少绝对值不超过d; 然后要求在一开始车速为v1,t秒之 ...
- MySQL日期 专题
一.MySQL 获得当前日期时间 函数 1.1 获得当前日期+时间(date + time)函数:now() mysql> select now();+--------------------- ...
- EasyUI入门:怎样引入及简单使用
或许,仅仅有当做比較大的项目的时候,才会发现封装好的东西会为程序员们带来多少方便.合作开发的时候更应该强调复用,才干更加发挥团队的优势. 今天使用了一些EasyUI,发现非常wonderful! 比方 ...
- Android 它们的定义View
安卓开发过程,安卓官方控制有时来自往往不能满足我们的需求.这一次,我必须定义自己.下面我们就来看看他们的定义View: package com.example.myview; import andro ...
- Javascript中的类实现
Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用来支持虚函数的virtual,不过,Javascript是一门 ...
- Delphi 禁用x64位系统文件重定向功能
在X64系统里面,一些特殊的目录和特殊的注册表键被分为2个独立的部分.对于文件系统来说, %systemroot%\system32 目录被保留给64位文件使用,而32位文件会被重定向到%s ...
- MFC 窗口分割与通信
一.关于CSplitterWnd类我们在使用CuteFtp或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割. 那么我们自己如何创 ...