Hi,

>If I use the last OpCodes.Ret, it actually injects my code in the if statement 
>like so:

Right. You don't have much choice but to do control flow analysis
here; build a control flow graph from the IL and figure out where to
inject code.

>I'm not sure if the switch instruction can also cause the same problem.

Its operand is just an array of instruction pointers, so someone
certainly could write some pretty whacky code with that...

Regards,
Alex

On Fri, Jul 8, 2011 at 10:30 AM, Gábor Kozár <[email protected]> wrote:
> 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

-- 
--
mono-cecil

Reply via email to