WiiRd forum

Wii & Gamecube Hacking => Wii Game hacking help => Topic started by: Patedj on February 26, 2011, 07:52:18 AM

Title: Calling Stacks
Post by: Patedj on February 26, 2011, 07:52:18 AM
I think from what dcx2 told me, I would have to find the original caller.

1a)
If I compare the 1st address' called stacks and the second address' called stacks via the dissasembler tab and right click load, could I figure out the the original caller?

2a)
If yes, is it the one that looks the same.
2b)
If yes, there are many. Would it be the highest address that I should look into?

1b)
then, I could simply branch it to the next function right? it would then skip everything. Or I could add value and branch etc. right?

Title: Re: Calling Stacks
Post by: dcx2 on February 26, 2011, 03:11:16 PM
I don't understand your question, but then again, I'm not sure you understand your question either...

Let's say we're playing a game where you and your enemy have health.  When you get hit, the game will call a function, let's call it GiveDamage().

Now let's say you want to hack infinite life.  So you search for your HP, get hit, search again, get hit, etc.  You eventually find the ASM that's subtracting from your HP.  This ASM is a part of the GiveDamage() function.  So you nop the stw to make enemies do zero damage.

However, when you go to hit your enemy, he doesn't take damage either!  Why?

---

When you hit the enemy, let's say there's another function called PlayerAttack().  PlayerAttack() is called when you press the button that makes you attack.  PlayerAttack() will do a check to make sure that you're close enough to actually hit your enemy.  If you are, PlayerAttack() will then call GiveDamage() to hurt the enemy.

When the enemy hits you, let's say that EnemyAttack() is called.  EnemyAttack() checks to make sure the enemy is close enough to hit you.  If you are, EnemyAttack() will call GiveDamage() to hurt you.

GiveDamage() is called when you attack the enemy and when the enemy attacks you.  So when you hacked GiveDamage(), you prevented yourself from hurting the enemy.  At this point, you would set a write BP on your HP and get hit again.  Then, while the game is at the breakpoint, you could either press Step Out on the BP tab or you could use the Call Stack listbox on the Disassembly tab to go to the caller; that is, your breakpoint is currently in the GiveDamage() function when it is hurting you, so we know GiveDamage() was called by EnemyAttack(), so now we can walk the stack back to EnemyAttack().

---

I'm sure you noticed all the ()'s.  Functions take arguments, or parameters (pretty much the same thing).  For instance, GiveDamage() actually looks more like GiveDamage(Actor* target, int damage).  "Actor* target" is a pointer the actor that is supposed to be given damage.  "int damage" is the amount of damage that should be done to this actor.

Function arguments are usually passed into a function using r3,r4, all the way up to r10 if there are 8 arguments.  So when you walk back to EnemyAttack, if you look just before the bl that takes you to GiveDamage(), you will see that a pointer to you is being loaded into r3 and the damage you're supposed to take is being loaded into r4.  This is where you would zero out r4.  Then, when EnemyAttack() is called, 0 will be passed in for your damage, instead of the actual damage you were supposed to take.

---

With that in mind, re-read the tutorial on walking the stack that I wrote.

http://wiird.l0nk.org/forum/index.php/topic,5080

Notice how the argument was -1 when I shot a starbit and 1 when I picked a starbit up.  See how I walked back to the caller (twice) and changed the li r3,-1 to li r3,0.
Title: Re: Calling Stacks
Post by: Patedj on February 26, 2011, 04:21:23 PM
 O0 I was looking for that! Thanks.
Now I see what you mean when I should look for the common caller.

Taking Guitar Hero Metallica into example. Ive got the ASM for storing the data into the Rock Meter. Colored buttons would be the caller and the guitars strum lever too.
So, if I find the lever address and load the call stack option, or step out, I would eventually arrive to the Rock Meter's Stack.

It's nice getting the language straight.  O0

At this point I would see which register is loaded into the branch and zero it for sub and max it for add.
Title: Re: Calling Stacks
Post by: dcx2 on February 26, 2011, 04:30:53 PM
That's all hypothetical talk there...you should never assume you know for sure what the different callers are.  There could be more.  There may be less.

You can only work your way backward one step at a time from the breakpoint and see if each step looks like the right place.  You must map it out manually.  Again; do not assume you know the callers before mapping them out.  That's dangerous.

One thing that helps.  After setting a read or write breakpoint and finding an address, try setting an execute breakpoint to see if anyone else is using this code too.
Title: Re: Calling Stacks
Post by: Patedj on February 27, 2011, 12:11:07 AM
Taking into consideration all of that. If I copy past both call stack load option in the dissasembler for both addresses, it would then be possible to arrive to a common caller, right?

Let's say controllerlever() call stacks are
[spoiler]8019F418
8019EC50
80115DE4
80116564
8019FC40
8000F09C
80006208[/spoiler]

and RockMeterHP() call stacks are
[spoiler]801D57F0
801D5D44
801D5D44
801D65FC
800296A4
80029588
80115DE4
80116564
8019FC40
8000F09C
80006208[/spoiler]

Then could I say that 80115DE4 is the common caller?
Title: Re: Calling Stacks
Post by: dcx2 on February 27, 2011, 12:42:04 AM
Yes, that is correct.

Pretty much all the breakpoints will have the bottom of the call stack in common.  Those callers are the functions that start the game.

The top of the call stack is the instruction that your breakpoint hit.

You can double click any of the calls in the call stack to go straight to it.  You can double click the top to go back to your breakpoint.

Note that the call stack is different from the stack.  The call stack is a list of functions showing who called who.  The stack is an area of memory where those functions store some of their data.  They are related, though; each entry in the call stack owns a corresponding chunk of the stack.