Dnlib - как найти и изменить boolean операнд?

Подскажите как можно найти bool операнд через библиотеку dnlib
Через поиск смог найти

System.Boolean Filename.folder.classname::methodbl
// Filename - имя программы
// folder - директория в которой лежат классы
// classname - имя класса где записаны переменные
// methodbl - переменная типа bool со значением false

В коде записано так:

public static bool methodbl = false;

Заменять пробую так:

public static void GetAllMethodsFromModule(ModuleDefMD module)
{
  foreach (TypeDef type in module.GetTypes().Where(t => t.HasMethods))
  {
     foreach (var method in type.Methods.Where(m => m.HasBody))
     {
       IList<Instruction> instr = method.Body.Instructions;
       for (int i = 0; i < instr.Count; i++)
       {
         if (instr[i].OpCode == OpCodes.Ldstr)
         {
           if (instr[i].Operand.ToString().Contains("DefaultText"))
           {
             instr[i].Operand = "NewText";
           }            
         }
        if (instr[i].OpCode == OpCodes.Ldc_I4_0)
        {
           try
           {
             if (instr[i].Operand.ToString().Contains("System.Boolean Filename.folder.classname::methodbl"))
             {
               instr[i].Operand = OpCodes.Ldc_I4_1;
             }
           }
           catch { }
         }
       }
     }
   }
}

Ответы (1 шт):

Автор решения: Exploding Kitten

Вам нужно заменять код не в методе, а в статическом конструкторе (cctor), т.к. у вас создается статическое поле:

public static bool methodbl = false;

Например, заменить все false на true:

var module = ModuleDefMD.Load(/* ... */);
var type = module.Types.First(/* ... */);
var cctor = type.FindStaticConstructor();
var instructions = cctor.Body.Instructions;

for (var i = 0; i < instructions.Count; i++)
{
    var instruction = instructions[i];

    if (instruction.OpCode == OpCodes.Ldc_I4_0) // check for false
    {
        instruction.OpCode = OpCodes.Ldc_I4_1;
    }
}

В вашем случает это не работает, т.к. в методе находится загрузка значение поля на стек, а это ldsfld инструкция.

UPD: для того чтобы обновить конкретное поле, проверять немного больше условий, инициализация поля компилируется в:

ldc.i4.0
stsfld       bool xxx.Program::methodbl

то, можно попытаться проверять stsfld и имя поля, а заменять прошлую команду (+ возможно нужно будет учесть какие-то доп. случаи), например:

if (instruction.OpCode == OpCodes.Stsfld &&
    instruction.Operand is FieldDef fieldDef &&
    fieldDef.Name == "methodbl") 
{
    instructions[i - 1].OpCode = OpCodes.Ldc_I4_1;
}

Также стоит учитывать и тот кейс, когда у вас bool будет инициализированная значением по умолчанию, т.е. false, тогда статический конструктор не будет создаваться компиляторам, и вам нужно будет его создать руками.

→ Ссылка