Измените операнд IL с помощью Mono.Cecil

Я работаю с внешней библиотекой, в которой есть ошибка. Я отследил ошибку, и это неправильное приведение, похожее на:

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 и заменить старую?


person JoshVarty    schedule 07.08.2014    source источник


Ответы (1)


Со страницы документации 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, чтобы узнать, какой метод следует использовать, но не могу найти ни одного. У вас есть ссылка?

person Farhad Alizadeh Noori    schedule 07.08.2014