教你怎么用Mono Cecil - 动态注入 (注意代码的注释)
2013-11-14 18:46
537 查看
原文 教你怎么用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 等。
相关文章推荐
- 在Unity中利用Mono.Cecil将代码注入到Dll中
- 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
- TextView(怎么用代码动态设置字体颜色)
- 不修改源代码,动态注入Java代码的方法
- android 在代码中动态设置字体颜色需要注意的问题
- jquery动态生成html代码 怎么 获取id 或 class
- 关于写代码的注意事项之,全部英文注释,tab缩进换成四个空格的缩进,代码末尾不能有空格
- 使用javassist动态注入代码
- android 在代码中动态的变更wight和height注意事项 Caused by: java.lang.ClassCastException:android.widget.LinearLayou
- 代码注释怎么写
- 使用javassist动态注入代码
- eclipse多行注释格式化代码时自动添加的星号怎么去掉?
- C代码注释注意//和/*xxx*/的区别
- 代码注释的注意事项
- Android中,xml代码注释注意事项
- cublas中执行矩阵乘法运算的函数 首先要注意的是cublas使用的是以列为主的存储方式,和c/c++中的以行为主的方式是不一样的。处理方法可参考下面的注释代码
- 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) 转
- Java 动态的创建注入代码,注入方法给类或者接口并通过反射调用
- 编译时MSIL注入--实践Mono Cecil(1)
- 如下这段代码怎么传递动态参数比较合适?(问题有点长~谢谢)