用monocecil修改IL操作数

本文关键字:操作数 IL 修改 monocecil | 更新日期: 2023-09-27 18:17:04

我正在使用一个有bug的外部库。我已经找到了这个bug,它是一个不正确的类型转换,类似于:

var projectionBufferBase = startBuffer as IProjectionBuffer;

实际位置:

var projectionBufferBase = startBuffer as IProjectionBufferBase;

查看IL,它表示为:

isinst Microsoft.VisualStudio.Text.Projection.IProjectionBuffer

我使用Mono。Cecil加载DLL并找到我想修改的行,但我不确定如何在将DLL保存回磁盘之前修改操作数。

MethodDefinition brokenMethod = ...
foreach (var item in brokenMethod.Body.Instructions)
{
    //Find the instruction with the incorrect operand
    if (item.Operand != null && item.Operand.ToString() == "Microsoft.VisualStudio.Text.Projection.IProjectionBuffer")
    {
        Console.WriteLine(item);
        //What do I assign here? It can't be a string.
        item.Operand = ...
    }
}
assemblyDefinition.Write(@"C:'Users'...'DirectoryWithDLLs'newDLL.dll");

item.Operand接受一个对象,但如果我将其设置为字符串,则在将DLL写入磁盘时失败。我可以替换操作数吗?或者我创建一个全新的IL指令并替换旧的?

用monocecil修改IL操作数

Cecil文档页:

为了在另一条指令之前插入一条指令:

var processor = method.Body.GetILProcessor();
var newInstruction = processor.Create(OpCodes.Call, someMethodReference);
var firstInstruction = method.Body.Instructions[0];
processor.InsertBefore(firstInstruction, newInstruction);

你是对的。你不能把字符串赋值给操作数。您需要使用Cecil API来创建对类型的强制转换。您需要首先查看这是如何在IL中完成的,然后使用api复制它。

我目前正试图通过API文档挖掘找出你应该使用哪种方法,但我找不到任何。你有链接吗?