jbevain / mono.reflection

Some useful reflection helpers, including an IL disassembler.
151 stars 51 forks source link

Executing result of GetInstructions #19

Open sake402 opened 4 years ago

sake402 commented 4 years ago

Hi. I am using this library for generating opcodes from a CIL byte[] alongside with the Harmony project. My concept is to recompile a changed source code on the fly, get a method from the new assembly and then its instructions and replace the new instructions with the old one.

So I have been using the library for getting the new instructions. All works very well until the library encounter a branch instruction in the new code.

Inside the MethodBodyReader.ResolveBranches you have this

switch (instruction.OpCode.OperandType) {
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                    instruction.Operand = GetInstruction (instructions, (int) instruction.Operand);
                    break;

Which throws exception when harmony is using the opcodes to patch the method.

Given that the operand of branches needs to be an offset to the instruction to branch to, I changed the code to this

var targetInstruction = GetInstruction(instructions, (int)instruction.Operand);
int byteOffset = targetInstruction.Offset - instruction.Offset - 1;
int targetOffset = instructions.IndexOf(targetInstruction);
int instructionOffset = targetOffset - index - 1;
instruction.Operand = (sbyte)(instructionOffset);// //GetInstruction(instructions, (int)instruction.Operand);

But I still get exception anyway. Any pointers from you please...

jbevain commented 4 years ago

Hi,

Unfortunately there's not much I can do to help here.

GetInstruction is going to throw if it can not find the instruction at the offset. If the patched method points at an invalid offset it should throw. You'll need to make sure the input IL makes sense. If that's a bug in the method body reader, please provide a test case that I can look at.

Thanks!