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 шт):
Вам нужно заменять код не в методе, а в статическом конструкторе (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, тогда статический конструктор не будет создаваться компиляторам, и вам нужно будет его создать руками.