//A method with try … catch (MSIL) whose Assembly is loaded by
Mono.Cecil and instructions injected in catch{ … } block
.method private hidebysig instance void TestMethod (object A,
class [mscorlib]
System.EventArgs a) cil managed
{
// Code size 544 (0x220)
.maxstack 5
.locals init (int32 V_0,
int32 V_1,
class [mscorlib]System.Exception V_2,
int32[] V_3,
string V_4)
.try
{
IL_0000: ldc.i4.2
IL_0001: stloc.0
IL_0002: ldc.i4.3
IL_0003: stloc.1
IL_0004: leave.s IL_001f /*** should be IL_021f ***/
} // end .try
catch [mscorlib]System.Exception
{
IL_0006: stloc.2
IL_0007: ldarg.0
// The original instruction is a “ldstr” has been replaced with a
list of instructions that I dreamed up ��
//…………………..
IL_0207: ldloc.2
IL_0208: callvirt instance string [mscorlib]
System.Object::ToString()
IL_020d: call string [mscorlib]System.String::Concat
(string,
string)
IL_0212: ldc.i4.0
IL_0213: newarr [mscorlib]System.Object
IL_0218: call instance void FormBase::ShowInfo(string,
object[])
IL_021d: leave.s IL_021f
} // end handler
IL_021f: ret
} // end of method TestClass::TestMethod
Instructions are injected using Mono.Cecil’s method.Body.CilWorker.
As you can see from the above /* ... */ line, after the instruction
injection, the short form (_s) OpCode with
OperandType.ShortInlineBrTarget will be insufficient since it is only
8 unsigned bit long and it will get overflow. I managed to replace the
short form OpCode with non-short form one. But that is more like a
"hack" as it replaces every single one of them. Nonetheless, that did
the trick and rendered a valid program and my small test application
succeeded. But it failed in much more complex projects.
I wonder if I am still missing something? Thanks for any insights.
--~--~---------~--~----~------------~-------~--~----~
--
mono-cecil
-~----------~----~----~----~------~----~------~--~---