-HACKING GUIDE2- Asm Example Mark and Recall (TELEPORT!)

Started by Black_Wolf, October 14, 2008, 10:53:59 AM

Previous topic - Next topic

Black_Wolf

Hey again guys, just writing some quick templates for you all.
This is a little more complex, so only attempt this if you have a bit of a decent understanding.
!!!Remember, I am still new to the Wii Scene (and PowerPC for that matter) so bear with me if I make some mistakes!


As you know I love working with co-ordinates, so here is another quick guide for you if you have found them yet. This code essentially "saves" you're co-ordinates when you press a button, and then when you press ANOTHER button, it stores them all back to their address. Meaning you can essentially save a spot (easy to make multiple button saves). So for example, store the co-ords of you're flag, then the oppositions flag in a ctf match. Then just press the 2 STORE buttons repeatedly to capture the flag over and over lol. Here's how its done

WHAT YOU NEED
-The address of the co-ords (x,y and z)
-An address for a blank bit of code (zero's) where you can copy you're co-ords to. Just do a string search in a hex editor for 00000000000000000000000000000000 etc to get a big area lol.
-Link's asm helper.

WHAT IT DOES
BUTTON1
-Loads the x, y, and z co-ords into a register
-Stores all of these at a blank area of code (different addresses)
BUTTON2
-Loads the x, y, z co-ords SAVED IN THE BLANK PART
-Stores these back at the real co-ord address.

For this example, we will say:

BUTTON1 (mark) is Z
BUTTON2 (recall) is C
The 3 blanks are at 80114560,80114564 and 80114568 respectively
The co-ords are at 80981C70, 80981C74 and 80981C78 respectively
The button activator is at 80C650A4


The ASM

li r0, 0x2000
li r1, 0x4000
lis r2, 0x80C6
lwz r2, 0x50A4(r2)
cmpw r2, r0
beq +0x10
cmpw r2, r1
beq +0x2C
b +0x48
lis r3, 0x8098
lwz r4, 0x1c70(r3)
lwz r5, 0x1c74(r3)
lwz r6, 0x1c78(r3)
lis r7, 0x8011
stw r4, 0x4560(r7)
stw r5, 0x4564(r7)
stw r6, 0x4568(r7)
b +0x24
lis r3, 0x8011
lwz r4, 0x4560(r3)
lwz r5, 0x4564(r3)
lwz r6, 0x4568(r3)
lis r7, 0x8098
stw r4, 0x1c70(r7)
stw r5, 0x1c74(r7)
stw r6, 0x1c78(r7)
nop


Ok now with some comments:

   BUTTON CHECK:
li r0, 0x2000   //Loads the Z value into r0
li r1, 0x4000   //Loads the C value into r1
lis r2, 0x80C6   
lwz r2, 0x50A4(r2)   //Loads the button control value into r2
cmpw r2, r0   //Checks if Z is pressed
beq +0x10   //If it is, branches to MARK FUNCTION
cmpw r2, r1   //Checks if C is pressed
beq +0x2C   //If is is, branches to RECALL FUNCTION
b +0x48      //If neither, branch to the end

   MARK FUNCTION:
lis r3, 0x8098
lwz r4, 0x1c70(r3)   //Loads X co-ords into r4
lwz r5, 0x1c74(r3)   //Loads Y co-ords into r5
lwz r6, 0x1c78(r3)   //Loads Z co-ords into r6
lis r7, 0x8011
stw r4, 0x4560(r7)   //Stores X Co-ords at SAVE1
stw r5, 0x4564(r7)   //Stores Y Co-ords at SAVE2
stw r6, 0x4568(r7)   //Stores Z Co-ords at SAVE3
b +0x24      //Branch to the end

   RECALL FUNCTION
lis r3, 0x8011
lwz r4, 0x4560(r3)   //Loads SAVE1 into r4
lwz r5, 0x4564(r3)   //Loads SAVE2 into r5
lwz r6, 0x4568(r3)   //Loads SAVE3 into r6
lis r7, 0x8098
stw r4, 0x1c70(r7)   //Stores SAVE1 at X co-ords
stw r5, 0x1c74(r7)   //Stores SAVE2 at Y co-ords
stw r6, 0x1c78(r7)   //Stores SAVE3 at Z co-ords
nop

REDSOXROX

Yay, thanks for making the ASM guides BlackWolf...
how do we decide which register to use though?
like in this:
lwz r4, 0x1c70(r3)
lwz r5, 0x1c74(r3)
lwz r6, 0x1c78(r3)

How do I decide to use r3 in everyone?
Red Sox vs. Yankees 4/4/2k10 Season Opener
Red Sox: 9 Yankees: 7 Final!

Black_Wolf

WELL the r4, r5, r6 are just register I hadn't used in the routine yet. HOWEVER the r3 is important, you'll notice that in the lines above I load the START of the address, in the mark function its like this

r3 has 0x8098 (first bytes of co-ords) therefore

lwz r4, 0x1c70(r3) loads value at 0x80981c70
lwz r5, 0x1c74(r3) loads value at 0x80981c74
lwz r6, 0x1c78(r3) loads value at 0x80981c78

Thats pretty much why we do it, you can really only load 4 digits (2 bytes) at one time, so thats why we load the FIRST 4 digits, and then the last 4 BASED on the register with the first 4 to make the whole address

REDSOXROX

Quote from: Black_Wolf on October 15, 2008, 06:54:50 AM
WELL the r4, r5, r6 are just register I hadn't used in the routine yet. HOWEVER the r3 is important, you'll notice that in the lines above I load the START of the address, in the mark function its like this

r3 has 0x8098 (first bytes of co-ords) therefore

lwz r4, 0x1c70(r3) loads value at 0x80981c70
lwz r5, 0x1c74(r3) loads value at 0x80981c74
lwz r6, 0x1c78(r3) loads value at 0x80981c78

Thats pretty much why we do it, you can really only load 4 digits (2 bytes) at one time, so thats why we load the FIRST 4 digits, and then the last 4 BASED on the register with the first 4 to make the whole address
Ah, i see. Thank you my friend.
Red Sox vs. Yankees 4/4/2k10 Season Opener
Red Sox: 9 Yankees: 7 Final!

Black_Wolf

no problem, after you get used to this whole loading in 2 steps idea, the whole concept becomes a lot simpler. You read pointers in this way too, so you would:

lis r0, "start of pointer"
lwz r0, "end of pointer"(r0) //This loads whatever is stored at the pointers address i.e the DMA address into r0
lwz r1, "OFFSET"(r0) //Loads the contents of [POINTER]+OFFSET into r1

You can easily store values in this way as well ;)

brkirch

There are a couple of problems here:
  • You can't replace nop instructions with data unless you can ensure that the data won't ever be executed as an instruction.  Even though nop doesn't do anything, it will be executed anyway, so if you replace it with data, the CPU will try to execute the data and that won't work very well...
  • Under no circumstances should data be stored in r1, as r1 is the stack pointer.  The only time the stack pointer should be changed is when creating and removing stack frames.
  • You said to use Link's ASM helper, which implies that this is supposed to be using an ASM insert.  When inserting ASM, you have to be sure that the registers are safe to use (which you obviously didn't because you used r1...).  To get a safe to use register, either the first operation after the ASM insert with that register must be overwriting the register without reading it, or you need to create a stack frame, save the registers to it, restore them after the ASM insert is finished, and remove the stack frame by advancing the stack pointer.
The idea of teleport by saving and restoring coordinates is a good one, but you'll have to be careful if you plan to implement it using ASM.  It may just be easier to use the code types, as they should be able to accomplish the same thing.

Black_Wolf

#6
I wrote the first r registers an example, obviously I'm not going to know which registers to use if the code is a false one!

Its a good point however, do check what registers are safe, and if necessary, store the original values back into them at the end of the routine if it is needed.

Ok so code caves are handled in zero's in wii then. Ok fixed think you for the suggestion.

Also both of the tutorials I wrote can easily be done with code types, but I am simply trying to help by providing examples to those looking for them, I apologize if me using the wrong registers offends you some way, and if you don't think the tutorials are helping I can have them removed. Honestly, I just feel that a few examples, of the language in general (correct registers or not) can benefit those looking for help...

Also, could you possibly direct me to a list of the registers the wii uses, and what they are for, so I don't make the same mistake again, you'll have to excuse me, but the safe registers seem to be different in every console I have hacked, I am new to the wii scene as well.

Igglyboo

Do i need to use ASM for this?
Could i just find the adresses with the coordinates and write a button activator to go along with them?

Black_Wolf

a button activator for what? You still need to actually SAVE the co-ords, otherwise you'll just teleport to the same spot every time.

You could use the gecko registers to do it, but this is also just another asm example for those wanting to learn. Thats the whole point of thie thread, an example of asm code

Igglyboo

A button activator would poke the lines at the values (the co-ords) and take me there.

REDSOXROX

Quote from: Igglyboo on October 17, 2008, 02:16:28 PM
A button activator would poke the lines at the values (the co-ords) and take me there.
...I think that's explained in the tut. :confused:
Anyway, I think I'll use this in my next code...
Red Sox vs. Yankees 4/4/2k10 Season Opener
Red Sox: 9 Yankees: 7 Final!

Black_Wolf

I still don't really get what you mean. A button activator would be like

IF you press Z
Write 0x0012568C to Co-Ords as an example

BUT this means every time you press Z it just pokes 0x0012568c to the co-ords, meaning YOU TELEPORT TO THE SAME PLACE EVERY TIME

With my code its like this

IF you press C
The current co-ords are SAVED
IF you press Z
Replace the existing co-ords with the saved ones


This means you can actually SET the teleport location IN GAME. So like you find some cover in a fps, save you're co-ords there. And then you can like run around or whatever, lose some health, just press Z and you'll teleport to the cover.

Romaap

That can also be done without ASM

IF you press C
The current co-ords are SAVED(in Gecko Register)
IF you press Z
Replace the existing co-ords with the saved ones

Black_Wolf

as I said above, yes you could use gecko register, but I'm not fond of the idea, because if someone uses the same register in their code, it screws yours up.

With asm, you have more complete control over whats being stored into the register. You COULD do it like this to prevent the risk though

On Press C
Load co-ords into gecko registers
Store gecko to blank area.
On press Z
Load blank area into gecko registers
Store gecko registers to co-ords


That way you're still saving to addresses which is far safer.

BUT THIS IS NOT THE POINT

***THIS IS AN ASM EXAMPLE***
In other words PEOPLE READ THIS IF THEY WANT AN EXAMPLE OF ASM yes it can be done in other ways, but that wouldn't help people understand asm now would it?

The gecko code types are so detailed that you can probebly do nearly every single NON injected code without a scrap of asm, but sometimes its a lot longer, and a lot harder than using a simple routine, sometimes its visa versa.

Romaap

line 4 gives me this error: "Error: operand out of range (0x0000a782 is not between 0xffff8000 and 0x00007fff)"
line 4 is: "lwz r18, 0xA782(r18)"
my whole ASM is
[spoiler]li r16, 0x2000
li r17, 0x4000
lis r18, 0x806B
lwz r18, 0xA782(r18)
cmpw r18, r16
beq +0x10
cmpw r18, r17
beq +0x2C
b +0x48
lis r19, 0x90B6
lwz r20, 0x14A0(r19)
lwz r21, 0x14A4(r19)
lwz r22, 0x14A8(r19)
lis r23, 0xCD00
stw r20, 0x7FF0(r23)
stw r21, 0x7FF4(r23)
stw r22, 0x7FF4(r23)
b +0x24
lis r19, 0xCD00
stw r20, 0x7FF0(r19)
stw r21, 0x7FF4(r19)
stw r22, 0x7FF4(r19)
lis r23, 0x90B6
lwz r20, 0x14A0(r23)
lwz r21, 0x14A4(r23)
lwz r22, 0x14A8(r23)
nop[/spoiler]

why does line 4 has to be between 0xffff8000 and 0x00007fff?