ASM Code Example (Part I)

Started by Nutmeg, January 23, 2011, 02:06:18 AM

Previous topic - Next topic

Nutmeg

ASM Code Example (Part I)
Home Team Has 999 Goals [Mario Strikers Charged]
Game ID: R4QE01
By Nutmeg on 1/17/11

Overview

We are going to make a basic assembly language (ASM) code.  This tutorial is not for a beginner coder.  If you have never made a code using Gecko dotNET [Credits: Link and dcx2] or WiiRd [Credits: kenobi and Link], then I suggest that you read dexter0’s basic RAM write tutorial that can be found here: http://members.cox.net/dexter0/WiiHacking/example1.shtml

What We Will Accomplish

I have found a code that will set the home team’s goals to 999:  

Home Team Always Has 999 Goals [Nutmeg] [NTSC-USA]
05060578 000003E7


[spoiler][/spoiler]

The home team will always have 999 goals, no more, no less.  It comes with a catch however, this code will only work on the first stadium.  (For those of you who actually own Mario Strikers Charged, it is “The Vice”.)  The easy way to solve this problem is to make a pointer… but I don’t like pointers.  (They take too long to search for, and they are not always found.)  So, we are going to write a code in ASM that writes 999 goals to the home team, for all stadiums (levels).

Before We Begin


•What you will need
•Your wii
•A USB Gecko [Credits: Nuke]
•The Homebrew Channel [Credits: Team Twiizers]
•Gecko OS (app for the Homebrew Channel) [Credits: brkirch]
•WiiRd GUI or Gecko dotNET (I will be using Gecko dotNET)
•Know how to make a RAM write code.  You cannot make an ASM code without knowing how to make a RAM write code.  If you cannot make a RAM write code, go to dexter0’s tutorial: http://members.cox.net/dexter0/WiiHacking/example1.shtml
•Make sure you can access the “disassembly” tab on either WiiRd or Gecko dotNET.  If you cannot access this tab, go to wiird.l0nk.org to ask for help.  I’m sure they will help you if you ask nicely.



Background about ASM

Assembly language coding is completely different than RAM write coding.  RAM write codes are almost always found in the later sections of memory.  Here is how the Wii’s memory is formatted.  (For this tutorials purpose, it will only involve the 80 memory range):

[spoiler][/spoiler]

Vocabulary Terms

ASM: This is an abbreviation for “Assembly Language.”
ASM Read: The ASM “reads” the values in the “value” section of the memory, and moves it to the ASM section of memory.
ASM Write: Once the ASM has “read” the value, it can “write” an entirely new value to the “value” section of memory.
ASM Instruction: These are held in the ASM section of memory.  They manipulate the “registers,” which we will deal with later in this tutorial.
Destination Register: Is the register where a value to be stored.  (In our example, it is r0.)
Source Register: Is the register whose value is stored somewhere in the “value” section of memory.  (In our example, it is also r0.)
Additional Note: The destination register is always insignificant because the value it holds will be overwritten by the next ASM “instruction.”  Because it is insignificant, we can always use it in ASM codes.

Here is the basic format on how Assembly Language works:

Step 1: The ASM reads a value out of the value section of memory.
Step 2: The ASM performs some “instructions” on the value.
Step 3: The ASM writes the new value back to the value section of memory.


ASM Reading

The chart above is very simplified and does not always hold to be true however; it should give you a good idea about how a Wii game works.  Here is how a Wii game works when you apply a direct RAM write code (e.x. a 04 code, like in dexter0’s tutorial):  You write a value to an address.  For this example we will use my code for Mario Strikers Charged (NTSC-USA version).  The value 0x3E7 (999) is written to 0x81060578.  The Assembly language part of the memory “reads” the value, 999, and the game thinks that you have 999 goals.  Additional Note: An address is usually “read” more than it is “written to.”

ASM Writing


The assembly language does not only take in the value from 0x81060578, it can also write a new value into that address.  Here’s an example:  First, assume that we have no codes applied.  The game is not hacked.  When we score a goal there is an “instruction” in the assembly language part of the memory that writes a new value to the address.  In our case, it’s 0x81060578.

Let’s Get Started!

First, we will take our address that holds the value of our home team goals, 0x81060578.  Now copy the address into the “break-points tab on WiiRd or on Gecko dotNET and select “read” as the break-point type.  This is what your “break-points tab should look like:

[spoiler][/spoiler]   


The Break Point Results Screen

Then click "set."

[spoiler][/spoiler]

Zoom in on your screen if you cannot see the above image clearly enough.  Please note that I maximized the Gecko dotNET window to show all of the information.  Your window might not be this big after you click “set.”

The screen is divided into two boxes.  The lower box holds assembly language instructions.  The instructions have two uses.  They are used to manipulate, or change the values in the upper box, and they are used to take a value out of the upper box and send it to an address in the “values” section of memory.  The upper box holds something called the “registers.”  The ASM “instructions” are what controls these “registers.”   Together, the “instructions” and the “registers” are what runs the game.  But, how do we hack them so that they do what we want?


Back to Our Example


The “instruction” that is at the top of the lower box is the instruction we want to manipulate.  The instruction is:

801AEB5C:   801E0008   lwz   r0,8(r30)

-801AEB5C is our “ASM Address.”
-lwz is our ASM “instruction.”
-r0 is the “destination register.”
-(r30) is our “base” of the ASM “instruction.”
-8 is our “displacement” of our ASM “instruction.”

Here is what that means.  The 801AEB5C is the address that our code will use.  In the code that only works for the first level, the address is 81060578.  The code written in assembly language will use a completely different address!  The second part is 801E0008.  Don’t worry about that part, you have no use for it.  Now, we come to the important part about the ASM.


Lwz r0,8(r30)
The value in r30 is 81060570.  You can find the value in r30, by locating r30 in the upper box.
The value in r0 is insignificant.  We don’t care what is in it.


Lwz is an assembly language “instruction.”  Lwz is short of “Load Word and Zero.”  What it does, is it loads a value from an address in the “value” section of memory and puts it into a given register.  The “instruction” that we are dealing with is lwz r0,8(r30).  We know what lwz does, but what does the r0,8(r30) do?  First, go to the value in r30, 81060570, and add 8.  Our address is 81060578.  Look at the address from our original code.  It is also 81060578.  This means that we are dealing with the correct ASM “instruction.”  lwz r0,8(r30) takes the value from our address, 81060578, and puts it into r0.  That is why the original value in r0 is insignificant.  It is over-written by the number of goals we have.  Right now, we have not changed anything in the “Assembly Language” section of memory.  We need to figure out how to turn our information into a code.  More specifically, we need to make the game think that we have 999 goals.



Creating the Code’s Structure


How should we make the game think that we have 999 goals?  In this case, it is just like any other code.  We have to “write” 999 to the original code that only works on the first stadium.  The address for that is 81060578.  But how do we do that?  We will use another ASM “instruction.”  It is called “stw.”  Stw is an abbreviation of “store word.”  It does exactly the opposite of lwz.  Stw takes a value from a register (the values in the upper box) and writes it to an address in the “value” section of memory.  Our instruction will look like this:

Stw   r0,8(r30)

Does that look familiar to the lwz “instruction?”  The r0,8(r30) is exactly the same as in the lwz “instruction.”  The “instructions” are exactly the same, except stw puts the value from r0 into r30 + 8, while lwz takes the value from r30 + 8 and puts it into r0.

Our next problem is, is that we have to change r0 to be 999 before we store it to our address, 81060578.  Right now, it is far from 999.  We will use another ASM “instruction” to put 999 goals into r0.  This “instruction” is called “li.”  â€œLi” is an abbreviation for “load immediate.”  What it does, is it puts a value into a “register.”  In our case, we want to put 999 into r0.  This is what our instruction will look like:

Li   r0,999

This ASM “instruction is much simpler than the lwz and stw “instructions.”  This instructions puts 999 into r0.  That was easy, wasn’t it?


Now we have the skeleton of our code.  We will put 999 into r0.  Then we will put r0 into r30 + 8 (That is 81060578, our original address).  The overall effect of this code, is that the game will think we have 999 goals, just like the original code, however it should work on every stadium.  (I will not tell you why.  It’s just built into the “Assembly Language” part of memory.)


Our code will look like this.  We start with the address we found in the “Assembly Language” portion of memory.  That is 801AEB5C.  So here, is the basic format of our code:
Address: 801AEB5C
Li   r0,999
Stw   r0,8(30)
Nop

“Nop” is an abbreviation of “no operation.”  Every code in ASM needs an odd number of lines.  Without the “nop” we only have 2 lines, which is even.  We use the ASM instruction, “nop,” to fill up the last line.  â€œNop” does absolutely nothing.  It’s just “there” to make the code have an odd number of “instructions.”



Turning that Nonsense into a Code

   
Open up ASMWiiRd.  In The “address” box at the top, put our address that is in the “Assembly Language” area of memory.  Then, in the box that is called “Assembler Code,” put our ASM “instructions.”  Click the arrow that is pointing to the “Code” box, and it should give us a code.  Here is what it should look like before we click the arrow:

[spoiler][/spoiler]

Now, we will click the top arrow, which is between the “Assembler code” box and the “Code” box.  After it is clicked, it should look like this:


[spoiler][/spoiler]

Now, We have our code!  The final code is exactly what you see in the “Code” box.

Home Team Always Has 999 Goals [Nutmeg] [NTSC-USA]
C21AEB5C 00000002
380003E7 901E0008
60000000 00000000


[spoiler][/spoiler]
The code works perfectly.  Instead of working specifically on the first stadium, it works on all stadiums!

Conclusion

   You should now be able to figure out how to make your own basic codes using assembly language!  Here are some simplified steps to conclude this tutorial:

•   Make the basic code.  (One that looks like this: 05060578 000003E7)
•   Copy the address into the “breakpoints” tab and select the type as “read.”  Set the breakpoint.
•   Use ASMWiiRd to change the given “instruction” to store your own value (999) to your basic address (81060578).
•   Remember to use the address in the “Assembly Language” section of memory (801AEB5C)!

This concludes Part I of the tutorial.  Thanks for reading, and I hope you’ve learned how to make codes using assembly language!



Addition Help

If there is anything about this tutorial you don’t understand, go to the WiiRd forums, and to “Wii Game Hacking Help.”  http://wiird.l0nk.org/forum/index.php/board,7.0.html  If you have a good question to ask, and you ask nicely, I’m sure that myself, or another member will be happy to help you.

What’s up Next

In part II, I will be covering the same code, except we will change it so that it is possible to add/subtract goals from the score, just by pressing a button!  Stay tuned!


Written by,

Nutmeg

Places you can find me:
WiiRd Forums: http://wiird.l0nk.org/forum/
Volderbeek’s Forums: http://volderbeek.freeforums.org/
Mdmwii’s Forums: http://mdmwii.altervista.org/






I'm inbetween your legs... that's not awkward.

toonlink444

THANK YOU!!! My prayers have been anwsered. Please make many more. And if possible vid tutorials.
In the begining there was nothing. Then it exploded
New blog!! Check it out for hacking Smash Bros Brawl!! http://letshackblank.blogspot.com/

Nutmeg

If you have any questions feel free to ask.  :D

-Glad you like it!  :D
I'm inbetween your legs... that's not awkward.

Bully@Wiiplaza

Quote from: Nutmeg on January 23, 2011, 06:56:48 PM
If you have any questions feel free to ask.  :D

-Glad you like it!  :D
did the posts get deleted? :confused:
My Wii hacking site...
http://bullywiihacks.com/

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

~Bully

Romaap


Nutmeg

#5
Quote from: Bully@Wiiplaza on January 23, 2011, 08:13:09 PM
Quote from: Nutmeg on January 23, 2011, 06:56:48 PM
If you have any questions feel free to ask.  :D

-Glad you like it!  :D
did the posts get deleted? :confused:

Nope, I had in the "secret section" only.  Most everybody in there already knows ASM, so now it's available to everybody.

Quote from: Romaap on January 23, 2011, 11:13:01 PM
Really nice, I added it to the Game Hacking Guides post.

Thanks! :D
I'm inbetween your legs... that's not awkward.

floppytripod

I really understand this now, because of this tutorial. I am amazed how detailed it is. You cleared up so many questions that I had. Thank you so much for taking the time to make this tut.
:D

toonlink444

Ok I have a little noob trouble. I think a final smash value is 806289BC 0000000E
So I did a write break point  and checked if the value was right, it was.
The lower box said 800028C8: 90030008    stw r0,8(r3)
What I'm trying to do is make everyone always have a final smash. So this looked like the correct ASM instruction So inASM<>WiiRd converter I put
Address: 800028C8
stw r0,8(r3)
and got
C20028C8 00000001
90030008 00000000
I put it in and the game froze.
Can you help me. If you need more info I can provide it.
In the begining there was nothing. Then it exploded
New blog!! Check it out for hacking Smash Bros Brawl!! http://letshackblank.blogspot.com/

Jackal

What you did should not make the game freeze
It's just branching and do the same instruction
Did you try disabling everything else?

toonlink444

In the begining there was nothing. Then it exploded
New blog!! Check it out for hacking Smash Bros Brawl!! http://letshackblank.blogspot.com/

Deathwolf

#10
Quote from: toonlink444 on January 24, 2011, 03:38:31 PM
Ok I have a little noob trouble. I think a final smash value is 806289BC 0000000E
So I did a write break point  and checked if the value was right, it was.
The lower box said 800028C8: 90030008    stw r0,8(r3)
What I'm trying to do is make everyone always have a final smash. So this looked like the correct ASM instruction So inASM<>WiiRd converter I put
Address: 800028C8
stw r0,8(r3)
and got
C20028C8 00000001
90030008 00000000
I put it in and the game froze.
Can you help me. If you need more info I can provide it.

C20028C8 00000001
90030008 00000000

and

040028C8 90030008
is the same
if you always want a final smash, use another register for the final smash value.

lis r12,0x0000
ori r12,r12,0x000E
stw r12,8(r3)

now it stores the 0E value from r12 into your RAM address [806289BC]
lolz

toonlink444

#11
Ummm, Can you explain the lis, and ori. And why use a different register
Edit:
Didn't work. I'll keep searching for the final smash value because I found more addresses that act the same
In the begining there was nothing. Then it exploded
New blog!! Check it out for hacking Smash Bros Brawl!! http://letshackblank.blogspot.com/

Romaap

lis - load immediate shifted (loads a value in the register at the first 16 bits instead of the last 16 bits)
lis r12, 0x1234 - this puts 0x12340000 in r12

ori - OR immediate (in Deathwolf's example it is used to set the last 16 bits of a register)
ori r12, 0x5678 - assuming that r12 is 0x1234000, this will make r12: 0x12345678

toonlink444

hopefully one day I will understand this better. But why change registers
In the begining there was nothing. Then it exploded
New blog!! Check it out for hacking Smash Bros Brawl!! http://letshackblank.blogspot.com/

Deathwolf

example on your last address:

800028C8: 90030008    stw r0,8(r3)

stw r0,8(r3) <-- r0 = 0000000E <-- value
stw r0,8(r3) <-- r3 = 806289BC <-- address

if you lose your final smash, the 0E value changes back to 00.
so you another register. 0E on r12. so you have always the 0E value.

lolz