简体   繁体   English

C# Mono.Cecil 注入的 IL 代码未执行

[英]C# Mono.Cecil injected IL Code does not get executed

I want to make a little sample code with Mono.Cecil The goal is to manipulate the IL.我想用 Mono.Cecil 制作一些示例代码,目的是操纵 IL。 The method X does print something on the console.方法 X 确实在控制台上打印了一些东西。 To test the manipulation of the IL code i remove all instructions from the method.为了测试 IL 代码的操作,我从该方法中删除了所有指令。 But when I run External2.dll the Console Output is still printed (but the instructions to do the Console output are removed from the External2.dll).但是,当我运行 External2.dll 时,控制台 Output 仍会打印出来(但执行控制台 output 的说明已从 External2.dll 中删除)。 How can I fix this problem?我该如何解决这个问题?

var module = ModuleDefinition.ReadModule("External.dll");
var types = module.Types;
foreach (var type in types) {
    foreach (var method in type.Methods) {
        if (method.Name == "X") {
            Console.WriteLine(method.Body.Instructions.Count);
            method.Body.Instructions.Clear();
            Console.WriteLine(method.Body.Instructions.Count);
        }
    }
}
module.Write("External2.dll");

I think you need to use AssemblyDefinition instead of ModuleDefinition我认为您需要使用AssemblyDefinition而不是ModuleDefinition

Also, you cannot simply remove all instructions from your method body.此外,您不能简单地从方法体中删除所有指令。 You need to have at least one ret .你需要至少有一个ret For instance the code below does work:例如下面的代码确实有效:

using System;
using System.Linq;
using Mono.Cecil;
using System.IO;

namespace cecil
{
    class Program
    {
        static void Main(string[] args)
        {
            X();

            var assembly = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location);
            var method = assembly.MainModule.Types.SelectMany(t => t.Methods).SingleOrDefault(m => m.Name == "X");

            if (method == null)
            {
                System.Console.WriteLine("Method X not found.");
            }
            else
            {
                Console.WriteLine(method.Body.Instructions.Count);
                method.Body.Instructions.Clear();
                var ilProcessor = method.Body.GetILProcessor();
                ilProcessor.Append(ilProcessor.Create(Mono.Cecil.Cil.OpCodes.Ret));

                Console.WriteLine(method.Body.Instructions.Count);

                var newAssemblyFileName= "External2.dll";
                assembly.Write(newAssemblyFileName);
                System.Console.WriteLine($"Assembly saved to {Path.GetFullPath(newAssemblyFileName)}");
            }
        }

        private static void X()
        {
            System.Console.WriteLine("From X");
        }
    }
}

btw, you can always use https://cecilifier.me to help you out.顺便说一句,您可以随时使用https://cecilifier.me来帮助您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM