Introduction to CPU architecture and ASM

Started by dcx2, March 05, 2010, 04:36:12 AM

Previous topic - Next topic

dcx2

So you want to learn ASM but you don't know where to start.  Perhaps a picture will help you understand what's going on.

Today's example will work with Super Mario Galaxy again.  We're going to look at the code which subtracts 1 from your health when an enemy hits you, so that we can understand what the assembly code is doing.  Here's the disassembly of the interesting section.

802B1C20:  80830380   lwz   r4,896(r3)
802B1C24:  2C040000   cmpwi   r4,0
802B1C28:  4182000C   beq-   0x802b1c34
802B1C2C:  3804FFFF      subi   r0,r4,1
802B1C30:  90030380   stw   r0,896(r3)


The non-bold part isn't relevant to this discussion, but I left in there for completeness.

Hidden in the spoilers below is an extremely simplified block diagram of the Wii's processor.  It shows four parts

1) Memory (MEM).  Pointers point to places in memory.  Mario's health, currently 3, is at address 810B5CB4.
2) Registers (REG).  This is where data being worked on is placed
3) Arithmetic Logic Unit (ALU).  This performs operations on data.
4) Instruction Register (IR).  This tells the CPU what to do.

Note that OP stands for Operation (add, subtract, load, store, and, or, etc).  rD stands for destination register.  rA stands is for the first source register.  rB is for the second (we won't be using that today).  I stands for "Immediate", which is how we refer to values that come from the IR as opposed to a normal register.  Word means any 32-bit value (as opposed to half-word, which is 16-bits, or byte, which is 8-bits)

[spoiler][/spoiler]

As you can see, right now the IR has lwz r4,896(r3) in it.  It stands for Load Word.  It is telling the CPU to

1) Take the value in r3, which is 0x810B5934 (Hex!)
2) Add the immediate value 896 (0x380 hex!) to it
3) Use the result as an address in memory
4) Put the data from that address into r4

Skip the irrelevant instructions...

[spoiler][/spoiler]

IR now has subi r0,r4,1.  It stands for SUBtract Immediate.  This instruction tells the CPU to

1) Take the value in r4, which is 3
2) Subtract 1 from it
3) Put the result into r0

[spoiler][/spoiler]

Finally, the last instruction is stw r0,896(r3), which stands for STore Word.  It tells the CPU to

1) Take the value in r3, which is 0x810B5934 (Hex!)
2) Add 896 (0x380 hex!) to it
3) Use the result as an address in memory
4) Put the data from r0 into that address

Now, what if you wanted to give infinite life?  There are several ways to do this.  The classic way is to replace the stw with a nop.

[spoiler][/spoiler]

nop tells the CPU to do...nothing.  It stands for "no operation".

There are other ways.  You could replace subi r0,r4,1 with mr r0,r4 (Move Register, more like "copy register"); this would move 3 from r4 to r0, and then the stw would always write the original health value back into memory.  You could also replace subi with li r0,3 (Load Immediate), which puts 3 into r0.  Then stw will always write 3 back into memory.  You could replace lwz with li r4,4, so that the subi will put 3 into r0 and the stw will always write 3 back into memory.

Remember, this was extremely simplified.  There's a lot more going on.  Sometimes, instead of rD, there's an rS.  Sometimes rA is the destination register.  Sometimes there's an rB or an immediate or three immediates (like rlwinm, Rotate Left Word Immediate then aNd with Mask).  The above is just meant to give you a mental set of building blocks to work with.  Hopefully you can piece together the rest.

May you go forth and write more ASM hacks!   ;D

sulfur


Romaap

Great tutorial, I added it to the Game Hacking Guides.
I think this would be very clear for hackers who don't have any programming experience and no ASM skills yet.

doomkaiber001

Hi, brilliant tutorial. One question; how and where do you use ASM codes?

cydp3

ASM codes can be made in either the Dissasembler tab or Breakpoint tab in WiiRd or Gecko.NET.
I'm not too expirenced with ASM codes...I'm still learning how to make them so I can't really tell you how to make them.

doomkaiber001

Oh... I was under the impression that you write them together, somehow, with the normal codes.

cydp3

No I don't think so.
Maybe read this tutorial. I think it explains breakpoints a bit better:
http://wiird.l0nk.org/forum/index.php/topic,3473.0.html

dcx2

There are two "types" of codes.

The first type I call "data" codes.  You find Mario's hit points in memory (0x810B5CB4 in this example), and you make an 04 code that constantly writes 3 to his health (050B5CB4 00000003), and this gives infinite health.  It requires zero knowledge of ASM.

The second type would be ASM codes.  See, the problem with data codes is that the addresses of the data sometimes move around.  So a data code may work everywhere, or it may only work for a single level, or even a single room in a level...or worse, it might move every time you restart the game.

If you use breakpoints, you can find the ASM that does interesting things to your data.  That's how I found the instructions in the example; write breakpoint on the health value, and then get hit, and the game will pause whenever it's writing the new health value.

Then, look around the disassembler and you can make changes.  For instance, near the conclusion I describe ways to give infinite health, like nop'ing the stw.  This would look like 042B1C30 60000000.

Note how the two codes use simple 04 writes.  The only way to know one from the other is to recognize that 00000003 is writing the data value 3 to my health, whereas 60000000 is the nop that's replacing the stw in the example.

ASM codes can also be broken into two sub-types.  There are simple ASM patches like the above, that replace a single instruction with another instruction.  Then there are more complex "hooks" that use the C2 code type, and can replace one instruction with many.

doomkaiber001

Thanks! It makes sense now. I think when I get USBGecko I'll try this.

Bully@Wiiplaza

#9
without any ASM, you won´t get that far... :-\
I already hacked a lot games and I often needed assembly, even if it´s harder than RAM fill codes. It still doesn´t mean that I am pretty good at all since I don´t have any programming experience. xD
ASM codes are totally worth it to make and they don´t bother with "not working always" :P
If you look at the codes from "good hackers", then you will notice that they are almost always using assembly... :smileyface:

------------
We need more tutorials like this, it rocks! ;D
Better would be a bit more complicated hacks like...
walk through walls or size modifier in assembly any game as an example.
My Wii hacking site...
http://bullywiihacks.com/

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

~Bully

matt123337