Breakpoint Trigger

Started by live2play, June 07, 2010, 03:58:21 AM

Previous topic - Next topic

live2play

I have the following situation.

1) Set Read BP at memory address.
2) Perform action in game.
3) BP triggers on lbz r0,0(r4) and r4=address_x.
4) The LR at this point is determined and the instruction that led to the command being executed was a bl 0x<instruction_address>
5) I placed an execute BP on the bl instruction above with a condition of r4=address_x.
6) The BP never triggers.  Why?

The problem with the above scenario is that I am not able to keep backtracking to determine why r4 gets set to address_x.  The reason I need to set the r4=address_x condition on the bl BP is that the instruction is part of the "main loop" and has other purposes of which I am not interested.  Given that there is nothing between the bl and the lbz r0,0(r4) instruction it directly references, I would expect that r4 would eventually be address_x.

dcx2

Do you see frames go by?  It's possible that the bl is being called so many times that you would have to wait for a very long time before r4 was the value you are looking for.

It's also possible that the data at r4 was moved, although it seems like that's probably not the case since you can set read BPs and stuff.

Are you sure you traced back to the caller correctly?  Have you tried Gecko.NET's Step Out?

Sometimes a bl does not go exactly where we think it will go; it doesn't always go to a stwu.  Sometimes there is a small pre-prologue before the stwu, or sometimes there's a pre-prologue that branches to the stwu (my Walking the Stack tutorial has one of those branch-to-stwu).  It's possible the pre-prologue is loading r4.

In fact, I would double-check the prologue for the function containing the lbz.  Set an execute BP on the first instruction of the prologue, with your condition r4=address_x; this will make sure you miss most of the main loop calls to other functions.

For that matter, you could try setting an execute breakpoint on the lbz with r4=address_x.  Work your way back from the lbz, to the prologue, and finally the caller.

If you're getting hit too many times in your breakpoint, you could also make a fancy C2 breakpoint condition.  Hook the lbz, and replace it with something like this.

lis r0, upper 16-bits of address_x
ori r0, r0, lower 16 bits
cmpw r0,r4
bne- 0x08
nop
lbz r0,0(r4)

Set an Execute breakpoint on the nop (if needed, you can Step Into the hooked lbz to follow it to the code handler's code data; make a note of this address).  The only time that nop will ever execute is if r0==r4==address_x.  Now you don't have to worry about your condition hit testing too many times.  If address_x changes, you don't have to send codes to Gecko OS again.  Just go back to the noted address and Poke the immediate parts of the lis and ori as needed (it's a good habit to pause the game before Poking in-memory codes)

live2play

Great recommendations.  As always, thank you very much!