Hi, I think you're just missing one thing: you're not creating the variable.
You need to add a VariableDefinition to newMethod.Body.Variables. Otherwise stloc.0 has no variable at index 0. Jb On Sun, Nov 23, 2014 at 7:17 PM, Artem Stekhnovskii <[email protected]> wrote: > I've injected an empty method into a class. I'm now trying to fill it with > this simple following code: > > Affliction test = new Affliction (); > if (test != null) > Console.AddMessage ("not null"); > > I've converted this snippet into ILCode with Reflexil and it works fine when > I inject it with Reflexil itself. > > However, when I inject the same ILCodeinstructions with Cecil, I get an > error when running the program and I also can't open it in .Net Reflector. > This is the ILcode that I'm injecting: > > IL_0000: newobj System.Void Affliction::.ctor() > IL_0001: stloc.0 > IL_0002: ldloc.0 > IL_0003: ldnull > IL_0004: call System.Boolean > Affliction::op_Inequality(Affliction,Affliction) > IL_0005: brfalse.s IL_0008 > IL_0006: ldstr "not null" > IL_0007: call System.Void Console:AddMessage(System.String) > IL_0008: ret > > This is how I do it: > > System.Reflection.ConstructorInfo constrInfo = > typeof(Affliction).GetConstructors()[0]; > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Newobj, > mainMod.Import (constrInfo))); > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc_0)); > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldloc_0)); > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull)); > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Call, > mainMod.Import(typeof(Affliction).GetMethod ("op_Inequality")))); > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse_S, > newMethod.Body.Instructions[1])); // instruction reference will be changed > later > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldstr, "not > null")); > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Call, > mainMod.Import(typeof(Console).GetMethod("AddMessage", new > Type[]{typeof(String)})))); > newMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); > newMethod.Body.Instructions [5].Operand = newMethod.Body.Instructions [8]; > > The inspection of the resulting instructions shows exactly what I'm aiming > for. And yet they don't work. > > Here's the error I get in the program: InvalidProgramException: Invalid IL > code in CommandLine:TestCecil (): IL_0005: stloc.0 > > And .Net Reflector throws an error saying Index was outside the bounds of > the array. > > This makes me think that the first instruction Newobj for some reason can't > create an object and doesn't push the reference onto the evaluation stack. > Then, the next instruction stloc.0 can't pop it and put it into the list of > local variables, and this throws errors. When I reference normal methods in > the same way, they are called just fine, but the constructors produce > errors. What did I miss? > > -- > -- > -- > mono-cecil > --- > You received this message because you are subscribed to the Google Groups > "mono-cecil" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. -- -- -- mono-cecil --- You received this message because you are subscribed to the Google Groups "mono-cecil" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
