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

C#Mono.Cecil注入的IL代码无法执行,c#,.net,mono,cil,mono.cecil,C#,.net,Mono,Cil,Mono.cecil,我想用Mono.Cecil制作一个小示例代码 目标是操纵IL。 方法X确实会在控制台上打印一些东西。为了测试IL代码的操作,我删除了方法中的所有指令。但是当我运行External2.dll时,控制台输出仍然被打印出来(但是执行控制台输出的指令将从External2.dll中删除)。我如何解决这个问题 var module = ModuleDefinition.ReadModule("External.dll"); var types = module.Types; forea

我想用Mono.Cecil制作一个小示例代码 目标是操纵IL。 方法X确实会在控制台上打印一些东西。为了测试IL代码的操作,我删除了方法中的所有指令。但是当我运行External2.dll时,控制台输出仍然被打印出来(但是执行控制台输出的指令将从External2.dll中删除)。我如何解决这个问题

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");

我认为您需要使用
AssemblyDefinition
而不是
ModuleDefinition

此外,您不能简单地从方法体中删除所有指令。您需要至少有一个
ret
。例如,下面的代码不起作用:

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");
        }
    }
}

顺便说一句,您可以随时使用ret来帮助您。

是的,ret必须仍然存在。我怎么能监督这个:)再次感谢你的帮助。但我还是有同样的问题。IL代码会被你的代码操纵。但是由于某种原因,当我运行External2.dll时,我仍然会得到控制台输出“来自X”,就像有一些缓存机制一样。你知道这怎么可能吗?我使用dotnet\External2.dll运行它,当我将External2.dll(包含所有引用)复制到另一个文件夹时,它可以工作:),因此必须删除一个文件。我需要有关如何构建/运行的更多详细信息以提供更多帮助。例如,我已经用dotnetcore测试过这个,为了能够运行“External2.dll”,我需要将它复制到原来的版本上。