使用Mono.Cecil修改IL操作数

时间:2014-08-07 18:31:27

标签: c# mono il mono.cecil

我正在使用有错误的外部库。我已经跟踪了这个错误的错误演员,类似于:

var projectionBufferBase = startBuffer as IProjectionBuffer;

它应该在哪里:

var projectionBufferBase = startBuffer as IProjectionBufferBase;

查看IL,这表示为:

isinst Microsoft.VisualStudio.Text.Projection.IProjectionBuffer

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

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指令并替换旧指令?

1 个答案:

答案 0 :(得分:2)

来自Cecil文档页面here

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

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文档以找出您应该使用哪种方法,但我找不到任何方法。你有链接吗?