Load a register value into an adress with branch condition?

Started by Bully@Wiiplaza, December 22, 2010, 03:43:36 PM

Previous topic - Next topic

Bully@Wiiplaza

Hey guys,
I was wondering if it´s possible to spy out enemys data using a breakpoint in the game!

I´ll take PBR as an example:

Let´s set a breakpoint on the health adress, if an enemy gets hit, r0 shows the enemys remaining HP (hit points).
Normally, you only see the HP bar for enemys, but you can only see the exact amount of HP on your own Pokemon.
Luckily, I found an adress, which can rewrite the display HP of your Pokemon, so I can load the enemys HP there and can see it on my screen ;D

My ASM code should take the value from r0 (ONLY if an enemy got hit! I already found the player counter register, it´s r5)
and write it to adress 80xxxxxx as it´s value. If I need to get the breakpoint which can write to this specific adress instead of a RAM write, let me know!

Breakpoint Write on Health (This breakpoint was taken from the player, if it´s an enemy, r5 shows 0000001)
[spoiler]CR:44000000  XER:00000000  CTR:803CB5B4 DSIS:00000000
DAR:00000000 SRR0:803CB64C SRR1:0000B032   LR:803CB5F4
 r0:00000148  r1:80F650E8   r2:80648600   r3:0000014C
 r4:92481660   r5:00000000   r6:FFFFFFFC   r7:FFFFFFFC
 r8:00000000   r9:00000004  r10:00000004  r11:80F650E8
r12:803CB5B4  r13:806452C0  r14:00000008  r15:00000002
r16:00000000  r17:00000004  r18:00000000  r19:00000004
r20:0000F100  r21:00000010  r22:00000003  r23:00010000
r24:918E83A0  r25:00000000  r26:8048CDB4  r27:9247F240
r28:00000004  r29:918E83B4  r30:9247F240  r31:92481660

 f0:00000000   f1:3F000000   f2:00000000   f3:00000000
 f4:00000000   f5:00000000   f6:00000000   f7:00000000
 f8:00000000   f9:00000000  f10:00000000  f11:3F800000
f12:00000000  f13:00000000  f14:00000000  f15:00000000
f16:00000000  f17:00000000  f18:00000000  f19:00000000
f20:00000000  f21:00000000  f22:00000000  f23:00000000
f24:00000000  f25:00000000  f26:00000000  f27:00000000
f28:00000000  f29:00000000  f30:00000000  f31:00000000

803CB5B4:  9421FFF0    stwu    r1,-16(r1)
803CB5B8:  7C0802A6    mflr    r0
803CB5BC:  90010014    stw    r0,20(r1)
803CB5C0:  93E1000C    stw    r31,12(r1)
803CB5C4:  7C9F2378    mr    r31,r4
803CB5C8:  93C10008    stw    r30,8(r1)
803CB5CC:  7C7E1B78    mr    r30,r3
803CB5D0:  7FE3FB78    mr    r3,r31
803CB5D4:  80A400B4    lwz    r5,180(r4)
803CB5D8:  38050001    addi    r0,r5,1
803CB5DC:  900400B4    stw    r0,180(r4)
803CB5E0:  4800B88D    bl    0x803d6e6c
803CB5E4:  7C651B78    mr    r5,r3
803CB5E8:  7FC3F378    mr    r3,r30
803CB5EC:  7FE4FB78    mr    r4,r31
803CB5F0:  4800CA4D    bl    0x803d803c
803CB5F4:  1D0300C0    mulli    r8,r3,192
803CB5F8:  80FF215C    lwz    r7,8540(r31)
803CB5FC:  7C651B78    mr    r5,r3
803CB600:  7C9F4214    add    r4,r31,r8
803CB604:  80C42D8C    lwz    r6,11660(r4)
803CB608:  7C073215    add.    r0,r7,r6
803CB60C:  41810010    bgt-    0x803cb61c
803CB610:  7C0600D0    neg    r0,r6
803CB614:  901F2148    stw    r0,8520(r31)
803CB618:  48000008    b    0x803cb620
803CB61C:  90FF2148    stw    r7,8520(r31)
803CB620:  80DF2148    lwz    r6,8520(r31)
803CB624:  2C060000    cmpwi    r6,0
803CB628:  40800018    bge-    0x803cb640
803CB62C:  5460103A    rlwinm    r0,r3,2,0,29
803CB630:  7C7F0214    add    r3,r31,r0
803CB634:  80030164    lwz    r0,356(r3)
803CB638:  7C060050    sub    r0,r0,r6
803CB63C:  90030164    stw    r0,356(r3)
803CB640:  80642D8C    lwz    r3,11660(r4)
803CB644:  801F215C    lwz    r0,8540(r31)
803CB648:  7C030215    add.    r0,r3,r0
803CB64C:  90042D8C    stw    r0,11660(r4) --> was going to be executed
803CB650:  40800010    bge-    0x803cb660
803CB654:  38000000    li    r0,0
803CB658:  90042D8C    stw    r0,11660(r4)
803CB65C:  48000018    b    0x803cb674
803CB660:  7C7F4214    add    r3,r31,r8
803CB664:  80632D90    lwz    r3,11664(r3)
803CB668:  7C001840    cmplw    r0,r3
803CB66C:  40810008    ble-    0x803cb674
803CB670:  90642D8C    stw    r3,11660(r4)
803CB674:  7FC3F378    mr    r3,r30
803CB678:  7FE4FB78    mr    r4,r31
803CB67C:  4BFF1CF9    bl    0x803bd374
803CB680:  83E1000C    lwz    r31,12(r1)
803CB684:  38600000    li    r3,0
803CB688:  83C10008    lwz    r30,8(r1)
803CB68C:  80010014    lwz    r0,20(r1)
803CB690:  7C0803A6    mtlr    r0
803CB694:  38210010    addi    r1,r1,16
803CB698:  4E800020    blr    
[/spoiler]

Adress, which let´s you edit your own display HP amount (doesn´t affect them at all):
02478554 0000XXXX

8)
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

Nutmeg

First, what kind of breakpoint is this?  I assume that it is "write."  If that's the case, it should only break when the enemy is hit, so I think it should just be as easy as this:

Hook: 803CB64C

lis r16,0x8000
stw r0,0x1500(r16)
stw    r0,11660(r4)
lis r16,0x0000
nop
---------------------

-That stores enemy HP to 80001500.  Is that what you wanted?  I'm kind of confused about where you want the HP value stored...
I'm inbetween your legs... that's not awkward.

dcx2

Nutmeg; you shouldn't assume 0 = safe.  It does not.  The value in r16 could change; it's part of the non-volatile registers, so you shouldn't mess with it.  The short answer is to use r12 for anything that you ever want to do.  The long answer is here

Also, because Data Access Register DAR = 0, this must be from an execute breakpoint.

---

Bully; do you see the . after add.?  That means it sets the Condition Register CR.  Specifically, you get a free "cmpwi rD, 0".  CR is used to determine whether or not conditional branches (like the bge after your hook line) will be taken or not.  If you do some cmpwi to make sure you only target enemies, you will screw up the CR and the bge will do funny things.

To fix this problem, put the cmpwi r0,0 at the end of your ASM.  This makes sure the CR holds the right value before the branch back to game code.

---

EDIT:

Here's an example of the window where the CR is not safe (in red).  You either need to push/pop CR, or reproduce the comparison that is supposed to be there.

803CB640:  80642D8C    lwz    r3,11660(r4)
803CB644:  801F215C    lwz    r0,8540(r31)
803CB648:  7C030215    add.    r0,r3,r0
803CB64C:  90042D8C    stw    r0,11660(r4) --> was going to be executed
803CB650:  40800010    bge-    0x803cb660
803CB654:  38000000    li    r0,0
803CB658:  90042D8C    stw    r0,11660(r4)

Nutmeg

Shouldn't it should be safe to use r16 because of the way I load 0000 back to the register?

Wait... When the breakpoint hits, the value might not always be 0?  Uhg, I'm confused...
I'm inbetween your legs... that's not awkward.

dcx2

It's difficult to explain exactly.  The link I provided in my previous post ("the long answer is here") goes into great detail.

The short version is that just because r16 is 0 now doesn't mean it will be 0 later.  In particular, registers above r13 are bad to touch unless you push/pop them on/off the stack.  r12 is always safe, even though it will never be 0.

Bully@Wiiplaza

but I still don´t know, how it´s possible to store the value of r0 (if an enemy got hit)
to a specific adress as value :-[
You said that if I use a cmpwi, the bge will do funny things...
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

You need a cmpwi r5 to make sure you are only affecting enemies, right?  The problem is that this cmpwi r5 will adversely affect the CR.  However, you can reproduce the correct CR by doing a cmpwi that sets the CR exactly like the add. operation.  The . at the end of any instruction means that it sets the CR by cmpwi rD, 0.