问题描述
我想用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");
解决方法
我认为您需要使用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");
}
}
}
。例如,以下代码可以正常工作:
--find-links
顺便说一句,您随时可以使用https://cecilifier.me来帮助您。