简体   繁体   中英

Modify IL Operand with Mono.Cecil

I'm working with an external library that has a bug. I've tracked down the bug an it's an improper cast similar to:

var projectionBufferBase = startBuffer as IProjectionBuffer;

Where it should be:

var projectionBufferBase = startBuffer as IProjectionBufferBase;

Looking at the IL, this is represented as:

isinst Microsoft.VisualStudio.Text.Projection.IProjectionBuffer

I've used Mono.Cecil to load the DLL and find the lines I'd like to modify, but I'm unsure how to modify the operand before saving the DLL back to disk.

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 accepts an object, but if I set it as a string, it fails when writing the DLL to disk. Can I replace the operand? Or do I create an entirely new IL instruction and replace the old one?

From the Cecil documentation page here :

In order to insert an instruction before another:

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

processor.InsertBefore(firstInstruction, newInstruction);

You are right. You can't really assign a string to an operand here. You need to use the Cecil API to create a casting to a type. You need to first look at how this is done in the IL and then replicate it using the APIs.

I'm currently trying to dig through the API documentation to find out which method you should use but I can't find any. Do you have a link?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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