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.

Reply via email to