Floating Value in ASM C2

Started by Deathwolf, July 18, 2010, 11:45:41 AM

Previous topic - Next topic

Deathwolf

I'm trying to write a floating value in ASM but it wont work.

address: 81279524

Breakpoint read:

CR  : 28000888  XER : 20000000  CTR : 00000004  DSIS: 00400000
DAR : 81279520  SRR0: 80389960  SRR1: 0000A032  LR  : 803898E0
r0  : 00000000  r1  : 807F8490  r2  : 807E43A0  r3  : 81278E80
r4  : 81162B50  r5  : 807F84D8  r6  : 81301E78  r7  : 00000095
r8  : 00000006  r9  : 00000002  r10 : 0000003C  r11 : 807F8520
r12 : 803C4C80  r13 : 807DCA20  r14 : 00000000  r15 : 00000000
r16 : 00000000  r17 : 00000000  r18 : 00000000  r19 : 00000000
r20 : 00000000  r21 : 00000000  r22 : 00000000  r23 : 00000000
r24 : 00000000  r25 : 00000000  r26 : 00000000  r27 : 00000000
r28 : 00000000  r29 : 8127C8D0  r30 : 807F8640  r31 : 8127C8D0

f0  : 3F800000  f1  : 00000000  f2  : 3F7FFFF8  f3  : 40400000
f4  : 3F000000  f5  : 3F7FFFFF  f6  : BF219454  f7  : BF2FF35E
f8  : BEB80F24  f9  : 3F800000  f10 : 80000000  f11 : 3F800000
f12 : 00000000  f13 : 3F800000  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


80389960:  880306A0 lbz r0,1696(r3)
80389964:  2C000000 cmpwi r0,0
80389968:  41820010 beq- 0x80389978
8038996C:  801F001C lwz r0,28(r31)
80389970:  54000398 rlwinm r0,r0,0,14,12
80389974:  901F001C stw r0,28(r31)
80389978:  7FE3FB78 mr r3,r31
8038997C:  48065A75 bl 0x803ef3f0
80389980:  3CA0806D lis r5,-32659
80389984:  7C641B78 mr r4,r3
80389988:  38658D18 subi r3,r5,29416
8038998C:  4BCD7D05 bl 0x80061690
80389990:  2C030000 cmpwi r3,0
80389994:  41820010 beq- 0x803899a4
80389998:  801F001C lwz r0,28(r31)
8038999C:  54000398 rlwinm r0,r0,0,14,12



lbz:
li rD,0xLLLL
stw rD,d(rA)

if I jump it say:

803B8590:  C02306A4   lfs   f1,1700(r3)

lfs:
stwu r1,-16(r1)
stw r11,8(r1)
lis r11,0xHHHH
ori r11,r11,0xLLLL
stw r11,d(rA)
lwz r11,8(r1)
addi r1,r1,16
lfs frD,d(rA)

what's wrong?
lolz

James0x57

Show the assembly around 803B8590.

What value are you trying to write?


Deathwolf

803B8574:  7C832378 mr r3,r4
803B8578:  80850584 lwz r4,1412(r5)
803B857C:  38840310 addi r4,r4,784
803B8580:  4BC561C0 b 0x8000e740
803B8584:  00000000 .word 0x00000000
803B8588:  00000000 .word 0x00000000
803B858C:  00000000 .word 0x00000000
803B8590:  C02306A4 lfs f1,1700(r3)
803B8594:  4E800020 blr
803B8598:  00000000 .word 0x00000000
803B859C:  00000000 .word 0x00000000
803B85A0:  9421FFF0 stwu r1,-16(r1)
803B85A4:  7C0802A6 mflr r0
803B85A8:  38800000 li r4,0
803B85AC:  90010014 stw r0,20(r1)
803B85B0:  88030705 lbz r0,1797(r3)


I want to write the floating value into 3D000000 with ASM to WiiRd in C2.
lolz

James0x57

803B8590:  C02306A4   lfs   f1,1700(r3)
803B8594:  4E800020   blr   
803B8598:  00000000   .word   0x00000000
803B859C:  00000000   .word   0x00000000   

This will make it always read in 3D000000 for the float:

803B8590:  lis rX,0x3D00
803B8594:  stw rX,1700(r3)   
803B8598:  lfs f1,1700(r3)
803B859C:  blr

change rX to a free register.




I don't understand why you posted the information from 80389960?


Deathwolf

#4
code:

C23B8590 00000003
3E003D00 920306A4
C02306A4 4E800020
60000000 00000000


it works, thanks again.

but why:
lis rX,0x3D00
stw rX,1700(r3)   
lfs f1,1700(r3)
blr

where is the information about this?
brkirch didn't post it!?
lolz

James0x57

lis rX,0x3D00 // load immediate shifted rX = 3D000000
stw rX,1700(r3)   // store word in rX to the address 1700 + r3's value
lfs f1,1700(r3)  // this is the original instruction that reads into f1, the value at address 1700 + r3's value
blr

You don't have to use C2 since there is enough room in the game's programming to fit the modification.

So this will work too:

063B8590 00000010
3E003D00 920306A4
C02306A4 4E800020


Deathwolf

#6
lis rX,0xXXXX
ori rX,rX, 0xXXXX
stw rX,XXXXXX
XXXXXXXXXXX
blr

can I use this on every assembly?
lolz


Deathwolf

lolz

James0x57



Deathwolf

#10
uff another code:

size:
803C0D14:  C03E002C   lfs   f1,44(r30)
803C0D18:  C05E0030   lfs   f2,48(r30)
803C0D1C:  C07E0034   lfs   f3,52(r30)

803C0D20:  48207561   bl   0x805c8280
803C0D24:  38610008   addi   r3,r1,8
803C0D28:  389E0264   addi   r4,r30,612
803C0D2C:  7C651B78   mr   r5,r3
803C0D30:  48207041   bl   0x805c7d70
803C0D34:  807E0F00   lwz   r3,3840(r30)
803C0D38:  48026E59   bl   0x803e7b90
803C0D3C:  38630024   addi   r3,r3,36
803C0D40:  38810008   addi   r4,r1,8
803C0D44:  38BD0024   addi   r5,r29,36
803C0D48:  48207029   bl   0x805c7d70
803C0D4C:  807E0F00   lwz   r3,3840(r30)
803C0D50:  48026E41   bl   0x803e7b90

it freez.

code:

lis r16,0x4000
stw r16,44(r30)
lfs f1,44(r30)
blr



lolz

dcx2

Wow, I'm late to the party...this is what I get for sleeping in.  =P

Quote from: James0x57 on July 18, 2010, 12:13:55 PM
I don't understand why you posted the information from 80389960?

Look at the original instruction he broke on [ lbz   r0,1696(r3) ], and the instruction he wanted to replace [ lfs   f1,1700(r3) ].  My guess is that Deathwolf forgot to check the "Exact" checkbox for the data breakpoint.


Quote from: Deathwolf on July 18, 2010, 12:26:21 PM
but why:
lis rX,0x3D00
stw rX,1700(r3)   
lfs f1,1700(r3)
blr

where is the information about this?
brkirch didn't post it!?

brkirch didn't post that method because it is unreliable.  rX must be a "safe" register; if it is not you will crash.  It's very, very difficult to explain to people how to find a safe register if they are new to ASM.  When in doubt, r12 is a safe register 99.9% of the time.

That is why brkirch posted the examples that use stwu r1 etc.  He is making room on the stack and saving the previous value of the register he wants to use.  This way, when he's done, he can put the old value back.  This is always a safe way to do it.

stwu r1,-16(r1)   # make space on the stack (16 bytes)
stw r11,8(r1)   # make a backup copy of r11 on the stack
lis r11,0xHHHH   # load r11 with the float that we want
ori r11,r11,0xLLLL
stw r11,d(rA)   # store the float where we want it to go
lwz r11,8(r1)   # restore our backed up copy of r11
addi r1,r1,16   # remove the space we made (16 bytes)
lfs frD,d(rA)

Quote from: Deathwolf on July 18, 2010, 03:58:59 PM
803C0D14:  C03E002C   lfs   f1,44(r30)
803C0D18:  C05E0030   lfs   f2,48(r30)
803C0D1C:  C07E0034   lfs   f3,52(r30)

803C0D20:  48207561   bl   0x805c8280
code:

lis r16,0x4000
stw r16,44(r30)
lfs f1,44(r30)
blr

You're on the right track, but I think James' non-C2 patch job has you confused.  You do NOT want the blr there!  blr = "Branch to Link Register".  It is how we "return" from a bl = Branch and Link.  bl/blr are like a telephone call.  bl is calling someone, blr is hanging up.  You put a blr where it shouldn't be, so you hung up the phone in the middle of the conversation.

I think you're also picking registers at random, which is bad.  I don't see anything that would suggest r16 is safe there.

What if a pointer was in r16?  You would overwrite the pointer with a float.  And then later the game would try to use the float you put in r16 as a pointer.  And the game would crash.  That's why brkirch's example would store r16 on the stack, so we can get the pointer back in r16 when we're done.

If you don't know what registers are safe, use r12.

---

Gecko.NET can log instructions as they are executed.  Maybe this log will help you understand how bl/blr work.

803A2E6C:  7FE3FB78   mr   r3,r31 
803A2E70:  3880001F   li   r4,31   
803A2E74:  48007D5D   bl   0x803aabd0        # puts address of next instruction 803A2E78 into LR
803AABD0:  80630980   lwz   r3,2432(r3)   
|  803AABD4:  2C030000   cmpwi   r3,0   
|  803AABD8:  40820028   bne-   0x803aac00
|  803AABDC:  38600000   li   r3,0       
|  803AABE0:  4E800020   blr                     # LR = 803A2E78
803A2E78:  2C030000   cmpwi   r3,0       
803A2E7C:  4182001C   beq-   0x803a2e98

Follow the addresses along.  You can see how the bl takes us somewhere else, 803AABD0.  We start executing instructions there, until we hit the blr, which takes us back to where the bl left off, 803A2E78.

James' non-C2 patch included the blr because that was part of the original function.  A C2 hook should NEVER, EVER have a blr.  Every bl must have a matching blr.

---

I just took another look at your code...you're trying to make a size modifier for Super Mario Galaxy 2?  I know this because I made a size roller for SMG2, and the addresses are exactly the same.  http://wiird.l0nk.org/forum/index.php/topic,5791.msg54813.html#msg54813

My size roller uses non-ASM code types to modify grA.  Then at the end, there's a C2 hook that uses the value in grA instead of a value hard-coded into the assembly.  Here's the C2 I used.


Hook = 803C0D14:  C03E002C   lfs   f1,44(r30)
grA = 80001830

lis r12,0x8000   # load grA into r12
lwz r12,0x1830(r12)
stw r12,44(r30)    # store to x/y/z size addresses
stw r12,48(r30)
stw r12,52(r30)
lfs f1,44(r30)      # replaced instruction

Deathwolf

#12
yea I see, the addresses are the same.
but how to assembly it?

lis should work on every assembly right?

btw r16 is a free register.
r17/18/19/20 and and and are also nothing (free).

maybe:
lis r18,0x4000
stw r18,44(r30)
lfs f1,44(r30)

btw awesome code dcx2^^
lolz

dcx2

Yes, you can use lis to hard-code a value in for the size modifier.  That's how brkirch's original Size Modifier for SMG worked.

(brkirch SMG1 universal size modifier, disassembled!)

lis r29,0xZZZZ     # load ZZZZ0000 into r29
stw r29,36(r30) # store to x/y/z size addresses
stw r29,40(r30)
stw r29,44(r30)
lfs f1,36(r30)     # replaced instruction

---

I don't know how you are coming to the conclusion that r16-r20 are safe.  They aren't.  Being 0 does NOT mean safe!  I repeat!  Being 0 does not mean safe!  r12 is almost never 0, but it is almost always safe!

A safe register is one that will be written to before it is read again by the game code (there are also special "volatile registers" that are safe once you cross a bl or blr).  r16-r20 are not written to in this area of the game, so they ARE NOT SAFE.

Notice how brkirch used r29 above.  If you were to look at the ASM for SMG, you would see that right after brkirch's hook, there's "mr r29,r3".  This is over-writing the float that we put in r29 with something else.  THAT is what makes a register safe; after the hook, r29 is written to by the game before it is read by the game.

Deathwolf

lol what!!??

lis r29,0xZZZZ   writes 4000
stw r29,36(r30) <]]]]
stw r29,40(r30) <]]]]] to 3F80
stw r29,44(r30) <]]]]
lfs f1,36(r30)     <--- why 36??


lolz