教你怎么用Mono Cecil - 动态注入 (注意代码的注释)
原文 教你怎么用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 - 动态注入 (注意代码的注释)的更多相关文章
- 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)
原文 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...
- 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7. 怎么调用别的程序集的方法示例 8. [is declared in another module ...
- 不修改源代码,动态注入Java代码的方法(转)
转自:https://blog.csdn.net/hiphoon_sun/article/details/38707927 有时,我们需要在不修改源代码的前提下往一个第三方的JAVA程序里注入自己的代 ...
- Mono.Cecil
Mono Cecil十分强大,强大到可以静态注入程序集(注入后生成新的程序集)和动态注入程序集(注入后不改变目标程序集,只在运行时改变程序集行为),它甚至可以用来调试PDB MDB调试符号格式文件. ...
- iOS中动态注入JavaScript方法。动态给html标签添加事件
项目中有这样一种需求,给html5网页中图片添加点击事件,并且弹出弹出点击的对应的图片,并且可以保持图片到本地 应对这样的需求你可能会想到很多方法来实现. 1. 最简单的方法就是在html5中添加图片 ...
- Spring Boot动态注入删除bean
Spring Boot动态注入删除bean 概述 因为如果采用配置文件或者注解,我们要加入对象的话,还要重启服务,如果我们想要避免这一情况就得采用动态处理bean,包括:动态注入,动态删除. 动态注入 ...
- spring boot 动态注入bean
方法一 SpringContextUtil public class SpringContextUtil { private static ApplicationContext application ...
- 如何向AcmeAir注入问题代码
为什么要注入问题代码? AcmeAir的常规代码是为了压测测试准备的,所以绝大部分的操作都是可以在几十毫秒中就可以正常返回的.为了向用户展示我们APM工具可以在源代码级别发现系统潜在问题,我们需要在A ...
- 基于Mono.Cecil的静态注入
Aop注入有2种方式:动态注入和静态注入,其中动态注入有很多实现了 动态注入有几种方式: 利用Remoting的ContextBoundObject或MarshalByRefObject. 动态代理( ...
随机推荐
- 第七届河南省赛H.Rectangles(lis)
10396: H.Rectangles Time Limit: 2 Sec Memory Limit: 128 MB Submit: 229 Solved: 33 [Submit][Status] ...
- How draw a stem -and -leaf & box-plot display by R.or Python
参考: 使用R进行数据可视化套路之-茎叶图.盒形图 step by step R 读取数据 在网上下载的2013全国各省区GDP排名(exl文件) 先 另存为 data.txt(为了方便存到D盘文件夹 ...
- C语言字符转换ASCII码
//函 数 名:CharToHex()//功能描述:把ASCII字符转换为16进制//函数说明://调用函数://全局变量://输 入:ASCII字符//返 回:16进制///////// ...
- 开启新的activity获取它的返回值
1.开始界面 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...
- Session累计用户数据列表
OrderForm.html <body> <center> <h1 ><font size="20">Order Items& ...
- Oracle Enterprise Manager 11g 输入用户名和口令 点击“登录”按键后没反应,也不报错,是什么原因?
在tnsnames.ora文件中检查设置好像没什么问题,用sqlplus也可以正常操作orcl 问题找到了,其实可简单,https://localhost:1158/em/console/logon/ ...
- 关于两次指针(struct型)传参数的问题
这两天被struct传参给郁闷死了.今天终于解决了. 比如有一个struct如下: struct _ns1__Add_USCORESensorDataArray{ struct xsd__base64 ...
- LOJ 1341 Aladdin and the Flying Carpet(质因子分解)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1341 题意:给两个数a,b,求满足c * d = a且c>=b且d>=b的 ...
- C++的常量折叠(三)
背景知识 在开始之前先说一下符号表,这个编译器中的东西.下面看一下百度百科中的描述: 符号表是一种用于语言翻译器中的数据结构.在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如 ...
- 命令自动补全模块rlcomplete
rlcomplete定义了针对readline模块的命令自动补全函数. 当在unix平台下导入这个模块之后(前提是readline模块可用),一个Complete的实例会自动生成,并且 ...