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

使用 Mono Cecil 进行反编译:using Mono.Cecil;
using Mono.Cecil.Cil; //...... AssemblyDefinition asm = AssemblyFactory.GetAssembly("MyLibrary.dll");
foreach (TypeDefinition type in asm.MainModule.Types)
{
if (type.Name == "Class1") //获取类名
{
foreach (MethodDefinition method in type.Methods) 遍历方法名称
{
Console.WriteLine(".maxstack {0}", method.Body.MaxStack);
foreach (Instruction ins in method.Body.Instructions)
{
Console.WriteLine("L_{0}: {1} {2}", ins.Offset.ToString("x4"),
ins.OpCode.Name,
ins.Operand is String ? String.Format("\"{0}\"", ins.Operand) : ins.Operand);
}
}
}
}
输出: .maxstack 8
L_0000: nop
L_0001: ldstr "Hello, World!"
L_0006: call System.Void System.Console::WriteLine(System.String)
L_000b: nop
L_000c: ret nop ----> ldstr ----> call ----> nop ----> ret ----> =================》下面我们开始进行注入了 AssemblyDefinition asm = AssemblyFactory.GetAssembly("MyLibrary.dll");
foreach (TypeDefinition type in asm.MainModule.Types)
{
if (type.Name == "Class1")
{
foreach (MethodDefinition method in type.Methods)
{
if (method.Name == "Test")
{
foreach (Instruction ins in method.Body.Instructions)
{
if (ins.OpCode.Name == "ldstr" && (string)ins.Operand == "Hello, World!") //如果发现操作数为"Hello, World! ===>改为"Hello, C#!";
{
ins.Operand = "Hello, C#!";
}
}
}
}
}
} AssemblyFactory.SaveAssembly(asm, "Test.dll"); 用 Lutz Roeder's Reflector 打开 Test.dll 看看结果。
.method public hidebysig instance void Test() cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldstr "Hello, C#!"
L_0006: call void [mscorlib]System.Console::WriteLine(string)
L_000b: nop
L_000c: ret
} 达成所愿~~~~~ 完成代码修改以后,我们玩一个更难点的,注入额外的代码。(好像有点做病毒的意思,呵呵~) 任务目标是在 Console.WriteLine("Hello, World!"); 前注入 Console.WriteLine("Virus? No!");,还好这不是真的破坏性代码 AssemblyDefinition asm = AssemblyFactory.GetAssembly("MyLibrary.dll");
foreach (TypeDefinition type in asm.MainModule.Types)
{
if (type.Name == "Class1")
{
foreach (MethodDefinition method in type.Methods)
{
if (method.Name == "Test")
{
foreach (Instruction ins in method.Body.Instructions)
{
if (ins.OpCode.Name == "ldstr" && (string)ins.Operand == "Hello, World!") //关键的地方,找到目的地
{
CilWorker worker = method.Body.CilWorker; Instruction insStr = worker.Create(OpCodes.Ldstr, "Virus? NO!");
worker.InsertBefore(ins, insStr); MethodReference refernce = asm.MainModule.Import(typeof(Console).GetMethod("WriteLine",
new Type[]{typeof(string)})); Instruction insCall = worker.Create(OpCodes.Call, refernce);
worker.InsertAfter(insStr, insCall); Instruction insNop = worker.Create(OpCodes.Nop);
worker.InsertAfter(insCall, insNop); break;
}
}
}
}
}
}
用反射测试一下修改后的程序集。
AssemblyFactory.SaveAssembly(asm, "Test.dll"); Assembly testAssembly = Assembly.LoadFrom("Test.dll");
Type class1Type = testAssembly.GetType("MyLibrary.Class1");
Object o = Activator.CreateInstance(class1Type);
class1Type.InvokeMember("Test", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null, o, null);4. 获取程序集信息
AssemblyDefinition asm = AssemblyFactory.GetAssembly("Learn.Library.dll"); Console.WriteLine("Kind:{0}", asm.Kind);
Console.WriteLine("Runtime:{0}", asm.Runtime);
输出:
Kind:Dll
Runtime:NET_2_0 利用 ModuleDefinition.Image 属性,我们可以获取程序集几乎全部的细节信息。包括 CLIHeader、DebugHeader、DOSHeader、FileInformation、HintNameTable、ImportAddressTable、ImportLookupTable、ImportTable、MetadataRoot、PEFileHeader、PEOptionalHeader、ResourceDirectoryRoot、Sections、TextSection 等。

教你怎么用Mono Cecil - 动态注入 (注意代码的注释)的更多相关文章

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

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

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

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

  3. 不修改源代码,动态注入Java代码的方法(转)

    转自:https://blog.csdn.net/hiphoon_sun/article/details/38707927 有时,我们需要在不修改源代码的前提下往一个第三方的JAVA程序里注入自己的代 ...

  4. Mono.Cecil

    Mono Cecil十分强大,强大到可以静态注入程序集(注入后生成新的程序集)和动态注入程序集(注入后不改变目标程序集,只在运行时改变程序集行为),它甚至可以用来调试PDB MDB调试符号格式文件. ...

  5. iOS中动态注入JavaScript方法。动态给html标签添加事件

    项目中有这样一种需求,给html5网页中图片添加点击事件,并且弹出弹出点击的对应的图片,并且可以保持图片到本地 应对这样的需求你可能会想到很多方法来实现. 1. 最简单的方法就是在html5中添加图片 ...

  6. Spring Boot动态注入删除bean

    Spring Boot动态注入删除bean 概述 因为如果采用配置文件或者注解,我们要加入对象的话,还要重启服务,如果我们想要避免这一情况就得采用动态处理bean,包括:动态注入,动态删除. 动态注入 ...

  7. spring boot 动态注入bean

    方法一 SpringContextUtil public class SpringContextUtil { private static ApplicationContext application ...

  8. 如何向AcmeAir注入问题代码

    为什么要注入问题代码? AcmeAir的常规代码是为了压测测试准备的,所以绝大部分的操作都是可以在几十毫秒中就可以正常返回的.为了向用户展示我们APM工具可以在源代码级别发现系统潜在问题,我们需要在A ...

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

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

随机推荐

  1. ZOJ 2562 More Divisors(高合成数)

    ZOJ 2562 More Divisors(高合成数) ACM 题目地址:ZOJ 2562 More Divisors 题意:  求小于n的最大的高合成数,高合成数指一类整数,不论什么比它小的自然数 ...

  2. POJ1363:Rails

    Description There is a famous railway station in PopPush City. Country there is incredibly hilly. Th ...

  3. Studious Student Problem Analysis

    (http://leetcode.com/2011/01/studious-student-problem-analysis.html) You've been given a list of wor ...

  4. C++对象模型--总结

    http://c.biancheng.net/cpp/biancheng/view/239.html 博客园有关C++内存布局,对象模型的文章. Effective C++ 绝不重写non-virtu ...

  5. Bandwidthd+Postgresql数据库配置笔记

    Bandwidthd+Postgresql数据库配置笔记 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/zjianbo/article/detai ...

  6. php生成数据字典,代码

    <?php /** * 生成mysql数据字典 */ header("Content-type:text/html;charset=utf-8"); // 配置数据库 $da ...

  7. PowerShell Remove all user defined variable in PowerShell

    When PS scripts executes, it is possibly create much user defined variables. So, sometimes these var ...

  8. FreeBSD 10安装KDE桌面环境简介(亲测bsdconfig命令有效)

    FreeBSD 10出来一段时间了,自己摸索装上KDE环境,网上介绍的都是10以前版本的,要么对现在的不合适,走了一大圈弯路还是装不好:要么太繁琐且装了一堆无用的软件.本着让更多人能快速方面的入门Fr ...

  9. Java并发编程总结3——AQS、ReentrantLock、ReentrantReadWriteLock(转)

    本文内容主要总结自<Java并发编程的艺术>第5章——Java中的锁. 一.AQS AbstractQueuedSynchronizer(简称AQS),队列同步器,是用来构建锁或者其他同步 ...

  10. Linux安装make无法使用

    1.apt-get update 2.apt-get install g++ 3.apt-get install pentium-builder 4.apt-get install build-ess ...