-HACKING GUIDE- ASM example, making moon jump codes

Started by Black_Wolf, October 10, 2008, 09:55:13 AM

Previous topic - Next topic

Black_Wolf

#15
oh with the bne, you just use the SKIP LINES kind of thing, so in your'e code it would be

bne +0x12


Also, make sure you put 0x where ever I had the dollar sign (i'll fix it up now, its just a different way of writing hex)


EDIT: Ok guide fix, and added screenshot of exactly what you're prog should look like!

lindtec

Thanks, now its a lot clearer.

Unfortunatly, I still get 2 errors:

My Code:
Address for Button-Check: 805D4FDA
Address to add a value: 804980F6

lis r0, 0x805D
lwz r1, 0x4FDA(r0)
li r2, 0x00001000
lis r3, 0x8049
lwz r4, 0x80F6(r3)
li r5, 0x00001000
cmpw r1, r2
bne +0x12
add r6, r4, r5
stw r6, 0x80F6(r3)


The errors:
\asmhelp-tmpout.txt:5: Error: operand out of range (0x000080f6 is not between 0xffff8000 and 0x00007fff)
\asmhelp-tmpout.txt:10: Error: operand out of range (0x000080f6 is not between 0xffff8000 and 0x00007fff)

Hope, you know a solution for this problem too, Black_Wolf.

Black_Wolf

#17
ok lol I REALLY hoped this wouldn't happen, but I guess I do need to explain this.

When you are LOADING based off another register (lwz) if the offset is over 0x00008000 it actually will MINUS 1 from the base (the lis), the asm thing doens't really like this, which is fair enough, so what you need to do to compensate for this, is put an FFFF in front of the offset if it is BIGGER than 0x00008000. Its very complex to explain this in detail, but just remember that as a basic rule. Its confusing I know, but this will actually be you're subroutine. It should compile under the asm converter

lis r0, 0x805D
lwz r1, 0x4FDA(r0)
li r2, 0x00001000
lis r3, 0x8049
lwz r4, 0xFFFF80F6(r3)
li r5, 0x00001000
cmpw r1, r2
bne +0x12
add r6, r4, r5
stw r6, 0xFFFF80F6(r3)

In MIPS (the language I'm fluent in) we actually just ADD one to our base lis, so it would be 804A, but the converter doesn't seem to like this at all, so this method SHOULD work as its really just the same thing backwards. If it doesn't though, let me know and you can actually change the 8049 to 804A without the converter to make it work properly.

lindtec

#18
Thanks a lot, now it works...

Btw. Maybe this is a stupid question, but what is the "Address"
at the top of the converter for (by default it shows 80000000,
in your screenshot, you put 804568C8 there)?

Black_Wolf

ok this is where the subroutine is "injected"

So you know that the game runs lines an lines of this code right? Well basically what we need to do is INTERUPT the basic game code, and link to our little routine, then when its done, it jumps back so the game keeps running as per usual.

Now usually the whole idea of a function is to edit a ROUTINE, so like you set a breakpoint on you're ammo, find the area of code that handles the gun losing ammo and taking damage off enemy, and you can RE WRITE IT to do heaps of damage, and not take ammo (see dr.pepper red steel thread in PAL codes section) So in this case we would inject our routine there, BUT with codes like moon jump, we are kind of making our own function, so we need to inject our routine in a place that the RAM constantly uses (like every frame)

To do this, Try setting a breakpoint ON you're controller address, it should take you to the area where the WPAD is read over and over, try injecting you're routine there. Remember, the LAST line of you're subroutine should be the ORIGINAL data of where you injected, so that it makes everything the way it should be before continueing

lindtec

Ok, now I understand it.

Btw. What happens, when there is allready a routine, that you could edit, but for whatever
reason, you write a new one that basically does the same, as the existing one, just with other
values.
Could there be conflicts or gets one of these routines (original vs. injected) priority?

Black_Wolf

ok, what you want to do there, just nop the whole original routine, and rewrite it. So still use the C2 code type, but also have a bunch of 32bit writes, and just nop it all (00000000) and that way you won't get any conflicts!

Igglyboo


brkirch

Quote from: Black_Wolf on October 10, 2008, 09:55:13 AMNow there are 2 popular methods for a moon jump code, one is generally easier than the other, but the address is hard to find.

The first method is a simple button activated gravity mod. You hold a button, gravity is lessened. Now finding gravity can be a chore, generally it can be found as a float 1 value (0x3f800000) HOWEVER try finding co-ordinates and experimenting with the area around it.

Now the SECOND method is to use the Z co-ordinates (height) to make a custom "jump" routine in asm. I generally use this is I can't find the gravity modifier, but it nevertheless works in a similar manner.

The best way I have found to make a moon jump code is to just locate the character's z-axis velocity address.  Then you only need to set the value to a constant when the jump button is held down.  Also that prevents the game physics from getting screwed up, which could happen with the methods you suggested (gravity could affect more than just the character you play as, and modifying the z coords could cause you to go through solid objects).

Black_Wolf

lol stupid PPC asm, 60000000 then.

So with the z-axis velocity, you could find by just jump, increase, at the peak of the jump (character slows) decrease etc?

I prefer actual z-axis modding, even though its more work, i just love working with co-ords, its incredibly easy to make teleport, mark and recall, walk through walls etc with the co-ordinates, I just really like the control. If you do have gravity though, setting it to 0 helps too, because you can make a full fledged FLIGHT code, with complete control over all the axises, to just hover anywhere you want!


lindtec

Hi again...

I've come up with the following code, which (at least) does something without freezing the game:

lis r0, 0x8049
lwz r1, 0xFFFF80F6(r0)
lis r2, 0x805D
lwz r3, 0x4FDA(r2)
li r4, 0x00001000
li r5, 0x00000100
cmpw r3, r4
bne +0x12
add r6, r5, r1
stw r6, 0xFFFF80F6(r0)


Problem: The code should add 100 to the value stored in register 1 as soon as I press the (-) button.
Unfortunatly, when I activate the code in WiiRD, the value jumps from  000002F4 to 4BB6A72C without pressing
any button.

I hope, someone can point out a mistake I made.

Dr.Pepper

Easiest way for you to debug, is just to add breakpoint in the beginning of that asm code and step through line by line and see when does the register value turn to wrong one.
Most of the time you have to be careful not to use too many registers, as game might use same registers for other purposes, ie, you have to be sure that register value is always unused ie 00000000, or store and restore the register value inside your asm code. As if your asm uses registers that game is using simultaneously on different part of the game, you might end in in freezing or other unforseen situations. Same thing is about memory locations, game can use some location to store value 2F4, but it can use the same location to store value 4BB6A72C etc during animations etc.

lindtec

#27
Sorry to bother you again.

I made sure, that the registers, I write to, are not in use, so this shouldn't be the problem.
Animations and such weren't played, while I tested the code.

How do I add a breakpoint to the asm code?

The whole "breakpoint"-tab in WiiRD is pretty confusing for me...

I understand, that you set the address you want to watch as breakpoint and the game
should stop running, when something read or writes to this address.

But what then, where can I see what reads or writes to my address?
I can't figure out, what to do with this assembler-window at the bottom.


Edit: I figured out, how it works in WiiRD, but I still don't know, how to breakpoint in an asm-code.

Dr.Pepper

you put your asm code address, and instead of read or write, you mark the execute option, and wiird will stop when your codeline is runned.

Black_Wolf

#29
I htink it could be the FFFF thing screwing it up, seems to be sensitive. There's a slightly longer way to do it though, load the FULL address into a register, and then do the lwz, you can use ORI for this!


lis r0, 0x8049
ori r0,r0,0x80F6
lwz r1, 0x0(r0)
lis r2, 0x805D
lwz r3, 0x4FDA(r2)
li r4, 0x00001000
li r5, 0x00000100
cmpw r3, r4
bne +0x12
add r6, r5, r1
stw r6, 0(r0)

This way, every time you refer to 0(r0) its the address 0x804980F6

See if that routine works better