I see your problem. That never came up for me, as I mentioned, it's a
slightly different situation. What I actually did was creating a map of
Instruction -> offset (int), and I went through the method body and adjusted
all Instruction pointers.

I think this is possible for all instructions whose OpCode.OperandType is
InlineBr or InlineBr_S (i.e. all instructions whose operands are of type
Instruction).
I'm not sure if the switch instruction can also cause the same problem.

Good luck! :)

2011/7/7 Indiefreaks.com <[email protected]>

> Thanks Gabor.
>
> I actually implemented adding my code injection before each
> OpCodes.Return instance in the MethodDefinition.Body.Instructions
> list.
>
> I did need to inject the code differently depending if the method was
> returning a value or void so that it kept returning it correctly.
>
> However, I'm now facing an issue with if statements that are on the
> end of a method. For instance, imagine the following method:
>
> public void Foo()
> {
>   this.DoSomething();
>
>   if(myProperty.IsTrue)
>   {
>       this.DoSomethingElse();
>   }
> }
>
> If I use the last OpCodes.Ret, it actually injects my code in the if
> statement like so:
>
> public void Foo()
> {
>   this.DoSomething();
>
>   if(myProperty.IsTrue)
>   {
>       this.DoSomethingElse();
>       this.MyInjectedCodeMethod();
>   }
> }
>
> instead of putting it at the real end of the method. Do I have no
> other choice than parsing the method and see if I have a brfalse or
> brtrue that points to one of my ret addresses in the IL instructions?
>
> And if that is the case, is there any other similar case that I should
> take care of?
>
> Thanks
>
> On 7 juil, 22:34, Gábor Kozár <[email protected]> wrote:
> > It means that the exact same values will be on the stack after your
> custom
> > injected code, than before. Essentially means that your injected code
> does
> > not push any value to the stack it does not pop later, and also it does
> not
> > pop any values from the stack that it did not push (unless you save the
> > value to, for example, a local variable first and then load it back
> later).
> >
> > My project had a similar problem, when I was writing a method using
> > Mono.Cecil to inline (specific) method calls. I solved it by basically
> > injecting my custom code before all 'ret' instructions. (It's a bit more
> > complicated than that, because most of the 'ret' instructions are removed
> > during inlining, but you get the point.)
> >
> > 2011/7/7 Indiefreaks.com <[email protected]>
> >
> >
> >
> > > What do you mean stabilizing the stack?
> >
> > > On 7 juil, 14:37, Alex <[email protected]> wrote:
> > > > Hi,
> >
> > > > >Well, I tried that method but I get way too many return operations
> in
> >
> > > > some situations like when a switch operation occurs in the method.
> > > > Moreover, if I fear that simply injecting my code before the
> > > > OpCodes.Ret instruction wouldn't work neither in some cases like when
> > > > a value is returned by the method.
> >
> > > > I don't think that's a problem as long as you correctly stabilize the
> > > stack.
> >
> > > > Regards,
> > > > Alex
> >
> > > > On Thu, Jul 7, 2011 at 2:30 PM, Indiefreaks.com
> >
> > > > <[email protected]> wrote:
> > > > > Well, I tried that method but I get way too many return operations
> in
> > > > > some situations like when a switch operation occurs in the method.
> > > > > Moreover, if I fear that simply injecting my code before the
> > > > > OpCodes.Ret instruction wouldn't work neither in some cases like
> when
> > > > > a value is returned by the method.
> >
> > > > > I may also go down the route of cloning the current method and
> adding
> > > > > it (with a different name) to the current class and then clear the
> > > > > current method instructions and surround a call to the cached
> method
> > > > > by my profiling code making sure that I catch the returned value if
> > > > > different from "System.Void" to return it back once the original
> > > > > method ends...
> >
> > > > > On 7 juil, 13:44, Alex <[email protected]> wrote:
> > > > >> Hi,
> >
> > > > >> I think what you propose is the best way to achieve this. I'm not
> sure
> > > > >> if 'ret' is the only opcode that can leave a method normally,
> though.
> >
> > > > >> Regards,
> > > > >> Alex
> >
> > > > >> On Thu, Jul 7, 2011 at 11:47 AM, Indiefreaks.com
> >
> > > > >> <[email protected]> wrote:
> > > > >> > Hi,
> >
> > > > >> > In my current Xna game profiler tool (learn more athttp://
> > > indiefreaks.com),
> > > > >> > I'm wrapping each method that should be profiled with my
> profiling
> > > > >> > code.
> >
> > > > >> > Right now, in order to do so, I'm getting the first instruction
> from
> > > > >> > the MethodDefinition Body as well as the last one and inject my
> code
> > > > >> > before them.
> >
> > > > >> > It works perfectly fine on most cases except when a control flow
> > > > >> > operation code is set in the body.
> >
> > > > >> > My profiling code that is injected before the actual method is
> > > invoked
> > > > >> > works fine but because of the previous statement, the code I
> inject
> > > at
> > > > >> > what I would consider the end of the method never gets called or
> > > gets
> > > > >> > called inside an if or switch statement which crashes the
> resulting
> > > > >> > assembly.
> >
> > > > >> > From what I understand, if I have such control flow operations,
> the
> > > > >> > last instruction in a method body may not be the end of the
> current
> > > > >> > Method.
> >
> > > > >> > I'm now considering parsing the whole method instructions and
> look
> > > for
> > > > >> > each OpCodes.Ret instance to add my custom code there but I
> wondered
> > > > >> > if there was a better solution to find the end of a method or
> hook
> > > to
> > > > >> > it.
> >
> > > > >> > Thanks
> >
> > > > >> > --
> > > > >> > --
> > > > >> > mono-cecil- Masquer le texte des messages précédents -
> >
> > > > >> - Afficher le texte des messages précédents -
> >
> > > > > --
> > > > > --
> > > > > mono-cecil- Masquer le texte des messages précédents -
> >
> > > > - Afficher le texte des messages précédents -
> >
> > > --
> > > --
> > > mono-cecil- Masquer le texte des messages précédents -
> >
> > - Afficher le texte des messages précédents -
>
> --
> --
> mono-cecil
>

-- 
--
mono-cecil

Reply via email to