NOTE: I have tried to explain the ps2 hacking experience in a very basic understanding level to new people to the scene, information may not be exact and terms could be off feel free to update and make this a bit better. Any information i have missed feel free to add in a post and ill be sure to add to it, credit will be shown at the top.




THIS TUTORIAL IS FAR FROM DONE, I HAVE ADDED A FEW BITS OF TUTORIALS FROM SP0NGE AND UNI TERROR TO IT, CREDIT IS SHOWN.

1. HOW TO USE A PS2DIS

// In this section i will be explaining how to use the ps2dis and the most needed features used in the creation of code making.

Psdis Most used options:

File
>New
>Open
>Save
>Save As
>Save As Text // Saves the selected area into a Text file.
>Save As Bin // Saves the selected area into a bin file.

Edit
>Copy
>Edit Line Attributes
>Jump To Labeled // Used to view labels in the memory dump
>Jump to Address // Go to the address specified
>Find Pattern // Pattern search

Analyzer
>Invoke Analyzer // Builds indexs and helps with code making

Ps2dis Keyboard Shortcuts

F3 >Next Refferal // To find the refferal of whats marked with spacebar.
Shift F3 >Previous Refferal // To find the refferal of whats marked with spacebar.
F5 >Next Pattern Search // For a hex String or String search
Shift F5 >Previous Pattern Search // For a hex String or String search
Shift Ctrl R >Emulator // Emulates how the mips will read
G >Go to Address // Go to a specified address


Ps2dis Graphical Layout:

White/Grey Box // Used to display the Actual Hex
Baby Blue Box // Used to display addresses of memory, Commands used and data.

Left side of Blue Box // Displays the address and data of memory
Right side of Blue Box // Displays the registers used and mips command

-------------------------------------------------------------------------------------------------------------------------------

2. Code Writes in Cheat Devices

// In this section i will explain the code types and how to use these features to your needs.

A = ADDRESS
D = DATA

2AAAAAAA DDDDDDDD // 32 bit write will write all 8 numbers in data
1AAAAAAA DDDDDDDD // 16 bit write will write the last 4 numbers of data
0AAAAAAA DDDDDDDD // 8 bit write will write the last 2 numbers of data

Now that we understand this lets put this to work, say we had a code such as session master (Socom Series) 0073f900 00000001.
Notice in this code the data has 000000001, Now the off data is 000000000 Meaning we only want to change the last number in the
data of this code. So we have chosen the 8 bit write so that it will not interfere with the rest of the data in the line. Now the reason i say
this is because if you loaded up a memory trainer and viewed the data in this address you will see there is much more then just a 1.
But because we only want to change the last number of the data we use the 8 bit write. Now if you were to try 2073f900 00000001, you
might just so happend to notice you freeze. The reason this happends is because its going to put the full 8 numbers into the address and get rid of
what was there before causing a collison in the game.


Jokers

DAAAAAAA 0000DDDD

As you can see this is the setup of a joker. A joker does not have to be a button configuration its basically telling the cheat device when to turn on this code.
So in our button joker its actually an address which displays what buttons are pressed. The last 4 numbers is the button id, there are diffrent ways to jokering
code then just this. You can have any address you want, when the data stated is seen the cheat device will activate it. Now depending on your cheat device
there are diffrent types of jokers this is just the main one we use.

// Now if a code is not jokerd the cheat device will constantly write the data given to that address meaning it will never change from what you have specified.

-------------------------------------------------------------------------------------------------------------------------------------------

3. Registers


zero
at
t0
t1
t2
t3
t4
t5
t6
t7
t8
t9
s0
s1
s2
s3
s4
s5
s6
s7
a0
a1
a2
a3
v0
v1
v2
Gp
Sp
Fp
k0
k1
Ra

// These are the registers that the mips assembly language uses. The registers are holders of information,
a very easy exampe of this is t0 + t1 = t4. Now say we gave t0 = 1 and t2 = 2 then what would t4 equal?
T4 would equal 3, so 3 will be stored in t4.

T registers are temporary and will not need to be preserved in a routine.
Other registers may not need to be preserved but it is in your best intrest to preserve them anyways.

---------------------------------------------------------------------------------------------------------------------------------------------------

4. Mips Commands

Loading and Storing

// Loading in a very simple explination is taking information(DATA) from an address, Or loading a value into a register.
This data can then be manipulated and or used for functions and sub routines.

EXAMPLE:

I want to load 8 numbers of data ( word.) and put it into a register, i then want to change it too diffrent data and put it back.

>00567777 40000001
>Load 40000001 into t1
>change it to 80000100
>Store it back to 00567777
>So now the address will have the new data 00567777 80000100.

// Pretty basic concept, soo to do this in mips we use certain commands, these commands i will list with an explination.

Loading commands:
lui Loads first 4 numbers of data or value.
lw Loads a word ( 8 numbers of data)
lh Loads a half of a word (4 numbers of data)
lb Loads a Byte (2 numbers of data)

Storing Commands:
sw Stores a word ( 8 numbers of data)
sh Stores a half of a word (4 numbers of data)
sb Stores a Byte (2 numbers of data)

There are more commands but these are the main ones to get you started in learning this concept.

EXAMPLE WITH COMMANDS USED:

lui t0 $0056 Loads first half of address
addiu t0 t0 $7777 Loads second half of Address
lui t1 $8000 Loads first 4 numbers of the value
addiu t1 t1 $0001 Loads Last 4 numbers of the value
Sw t1 $0000(t0) Stores a full 8 Numbers into the address.
Jr ra End

Branches and Jumps

// This was written by uni terror.

Branches are the way the PS2 is able to make decisions,
should I enable this or not? Is this value equal to this register?
Without them your game couldn't decide anything
(well there's other conditionals but branches are the most common).
For the most part if the condition is true, they branch or
skip to the specified address. Jumps are also important
as they allow subroutines to be run inside functions and
can be disabled accoridngly to only disable one aspect of a function.

Jump instructions
j jump (jumps to address specified)
jal jump and link (jumps to another function and returns when
it's done executing)
Jalr Jal return (Jumps to the specified address, reads tell the jr ra and returns.)

Branch instructions
b branch (branchs or skips to address without checking a condition)
beq branch on equal (branch or skip to address if the two
registers given are equal)
bne branch on not equal (branch or skip to address
if the two registers are NOT equal)
comparing registers seeing if register 2 is greater than register 1

bgt branch on greater than
bge branch on greater than or equal
bgeu branch on greater than or equal unsigned
bgtu branch on greater than unsigned comparing registers seeing if register 2 is less than register 1
blt branch on less than (not bacon lettuce and tomatoe)
ble branch on less than or equal
bleu branch on less than or equal unsigned
bltu branch on less than unsigned comparing register to zero
beqz branch on equal to zero
bgez branch on greater than or equal to zero
bgtz branch on greater than zero
bgezal branch on greater than or equal to zero, and link
bltzal branch on less than zero and link
blez branch on less than or equal to zero
bltz branch on less than zero
bnez branch on not equal to zero

// feel free to comment, i know this isn't a full list (i left out the 'if likely'conditionals because they are never used),
but if you see any mistakes let me know.

Adding Instructions:

add Add two registers together
addiu Add to a register

Subtracting Instructions:

Sub Subtracts two registers

Multiplication Instructions:

Mult Multiplys two registers together and puts the result in hi.

Division Instructions:

Div Divides a registers by a register.

// Im missing some here but these are the main ones we can use, I will add more at a later date.
-----------------------------------------------------------------------------------------------------------------------------------------
6. Function/ Subroutine information

A function is a block of code with a purpose, it will have a way of calling this function and will end with a jr ra.
The top of a function can be found by pressing Ctrl Up in the ps2dis. You may have to press it more then once depending on
jal r and other instructions.

There a diffrent types of functions, A stem function is a function that links to many other functions. Its in a simple term
a controller of the other functions being called and when. As well as the information needed for this instance to happen.

Functions will consist of many diffrent commands with a purpose to do something in the game, A easy understanding of this, is
an animation function, The animation will be controlled here. So in this function you may see things like when this animation should happen
the information needed for it to work. As well as maybe when the animation should not work. There could be speeds or even timing controlled in this function.
Now the memory is made up of many diffrent functions that control the game in every aspect. This includes images, movement, etc.

Now a subroutine is also known as a leaf. Subroutines are loaded during a function with some kind of jump instruction. This allows for code in the function
to work at diffrent times. It will then jump back to the original function and continue to read. This is very useful when writing code to make massize blocks
of code simple to debug later on.

------------------------------------------------------------------------------------------------------------------------------------------
7. Pointers And Hooks

// In this section i would like to breifly give an explination on pointers. Pointers are used in many instances of code making.
One of the most common is what we call hooks, hooks are just pointers. Now there are diffrent types of pointers,
Now my termonology may not be proper but i will explain them in my own understanding.

-Pointer
-Dynamic Pointer

A pointer is basically an address that points to an other address, A dynamic pointer is the same but will change occasionally.

Now Depending on if you are code hacking or writing a function or routine, A pointer may be your answer too your problem.
It can allow functions to be called by jal returns, it can also be used to point to an area where information will be loaded.
You can load a pointer and load the pointers address to get to where you need to go.

-------------------------------------------------------------------------------------------------------------------------------------------
8. Code Hacking

// Lets begin, after reading all of that you should half a good concept of mips now, so how do we hack codes?
Well there is no specific way to hack a code it all depends on what you are after.

The most common ways of Finding The area you need are:
Hex searching
String searching
Function cutting

// It helps to label your dump to fill in the blanks.

Now when you have the area of where you think your code is how can we find it? This all depends on your skill in hacking, If
you still do not understand mips very much then you will be more likly guessing and testing. This works but no efficently and is
time consuming. Now if you are a bit more advanced you should be trying to read the function you beleive your code is in, altering
specific lines of code to see if you get an effect close or similar to what you want. From here you can then read the registers and how
the game is designed. Now depending on how the function works you may need to look for a pointer, or an address loaded where data is loaded.
You may need to play with branches, or even function cut. There are many ways of manipulating code, just depends on what you think is best.
I suggest using a memory trainer and a memory dump and ps2dis. Test on lan so you do not get ban, from here if it is a banning code we can also,
learn how to make it safe. All of this and more will be explained in this guide.

Now depending on your code you may want to look at the codes you already have, check to see if anything is in the same catagory as what you are trying
to make. Let's say i wanted a grenade code, well lets check the codes that are released to the public and see if maybe there is a grenade code
we can use to pinpoint somewhere close to where our grenade code might be. If not ? maybe you should search the labels for something intresting about
grenades to figure out the area you need. You might even Know a value like the greanade iD and do a hex search and see if maybe a function is loading it.
Now lets say none of that worked for you and you couldn't find anything close to the area of code you need, well you could also look at the hooks, Using a pointer
to pointer to a jr ra will stop the pointer from working and you may be able to stop an entire function tree from working and give you an idea of what this pointer is
pointing too. Now if this does not work you could always start function cutting functions that you beleive might carry your code.

Ok, so after alot of testing we managed to find a good area we think our code may be in, So what do we do now? Well try noping branches, changing branches
to the opposite, try getting rid of stores, you might even wanna manipulate some code by altering it to do the exact opposite of what its supose too. Doing the above
is what i call skimming and help to decide if this is the proper area. Not only this but you may find some pretty intresting codes. Looking for loaded information is
also a very useful techinque.

Now lets say we have found our code but we have realized it is in a banning area in the memory, what do we do?
well there are few ways to approch this, we can try and find a version of this that does not ban or a loaded value that might give the same effect.
We can also try and rewrite the function safe, which means you will have to collect the reffering functions and a hook. This is a fail safe way, but will
deffintly be more laggy in the end when running the code. So the other way we can do this is something called dynamic memory editing. Functions will
store information in the heap where it is used in several function or maybe just needs to be stored in a specific area. Ether way you got options so do not
get worried. Now if all of this fails maybe? there is a way to routine it to work. Now this means you will need some collective information and addresses to
get the selected effect to work in your routine.


// Now i will explain what each term is and how to do the following.

Function cutting go to the top of a function place a jr ra(03e000008) in the top addresses data, now we need to also add a nop'd line after this into the
delay slot. So the next address you will put (00000000)

Hex searching This is helpful when you know a value of a code, You will write it backwards, so say it was 24080008 it will now become 08 00 80 24
we will then check the hex box in the pattern search and take a look at the results we find.

String searching This is useful when you know a word or sentece displayed in the game, we can ether look through the labels or do a search for it in the pattern search make sure to tick the string option and untick the hex search option.

Pointer cutting This is when we will point the pointer to a jr ra, cutting the specific functions for being active.

Branch Manipulation This is when we ether cut a branch or reverse it, a branch can also be placed to cut a function.

Noping This is when we will place 00000000 into an address to stop some kind of command to work.

Manipulating loaded data This is when we look for an address to be called we then will go to this address and look in our trainer from here you can freely manipulate the data.

Loading Manipulation This is where we change where information is being loaded from to an address or area we have chosen.

Storing Manipulation This is where we can actually change where things are loaded to ether view incoming information or even change where its stored.

Routine writing This is when we will actually write code and hook it to do some kind of event in game, this can be something like sticky player.

DMA Hacking This is where we will change information in the heap using a routine to manipulate the dynamic memory.

Function Copying This is where we will re-write using a stack list and copier to a ban free area, from here we will then change the jals, lui's addius,jumps, jalr
hooks etc to make the game read our functions instead of the banning ones.

// Now there are other ways of hacking these are the techniques i use daily when making codes.


Subroutines


OK, for everyone wondering how to write subroutines i will go over a few things here that will help you out.

Now in a subroutine you are basically taken a line or a few lines of code and using your sub routine to modify it in some way, i good visual example of this is animated imposter. Now you can make a simple subroutine to make it blink which would flash between 2 diffrent imposters or you can write a detailed routine which will have a timer, will load from a list of imposters and be completly animated in anyway. as you can see we are taking a line of code and modifying it how we want.

Now when writen a simple subroutine use only t0-t9 registers these registers will not need to be preserved meaning you will not have to store and reload at the end of a sub.

Read up on the commands to have a better understanding of whats going on.

Now in a subroutine you will want to load an address of some sort or many addresses this is how it should look.
lui t0 $0000 <---this is loading the first 4 numbers of the address of your code.
addiu t0, t0 $0000 <--- this is loading the last 4 numbers of the address of your code.
lw t1 $0000(t0) <--- this is loading the data from the address above.

so meaning t0 will hold the address of the code you want.
t1 as you can see is loading the data FROM t0. There are also many other commands you can use, heres a few.

lh t1 $0000(t0) This will load the last 4 digits of data from a specified address
lb t1 $0000(t0) This will load the last 2 numbers of data from a specified address

now im going to explain branches you will use these alot.

beq t0, t1 $00000000
this means branch if t0 is equal to t1 to the address specified.
bne t0, t1 $00000000
this means branch if t0 is NOT equal to t1 to the address specified.
beq zero zero $0000000 <-- this will always branch to where ever you want. I use it mostly in loops or when i need to branch to the end of a subroutine.

++ btw when you use a branch remember to leave a line after it blank this is called the delay slot, and yes u can use this in some cases but it is best not too.

Now i will explain storing, Storing is very similar to loading.

sw t1, $0000(t0) <--- this means store a full 8 numbers from register t1 into the address t0
sh t1, $0000(t0) <--- This means store the last 4 numbers from t1 into the address supplied in t0
sb t1, $0000(t0) <--- This means store the last 2 numbers from t1 into the address supplied in t0

These will be used to store the modified data back to the address you want.
I would also like to say before we go any further, when you see this $0000 this is the offset from whats already stated in the register. meaning how far from the above address will it load or store from.

Ok so now lets make a simple subroutine. I will make a adding routine here with examples on how to do it.

(hook goes here)
lui t0, $0000 <-----loads first half of the address
addiu t0, $0000 <----loads the second half of the address
lw t1, $0000(t0) <----loads the data at the address
addiu t1 t1 $0001 <----adds 1 to the data
sw t1, $0000(t0) <----stores the data back to the address
jr ra <----end

This means that everytime this hook is called it will add 1 to the data of the address we picked.

Now lets get a bit more technical using branches.
lui t0, $0000 <-----loads first half of the address
addiu t0, $0000 <----loads the second half of the address
lw t1, $0000(t0) <----loads the data at the address
addiu t2, zero $0008 <-----puts 00000008 into t2
beq t1 t2 $0000000 <----if data in t1 = t2 go to the address specified. In this case i would point it to where the jr ra is.

addiu t1 t1 $0001 <---- add 1 to the data in the address
sw t1 $0000(t0) <----stores the data back to the address
jr ra <----end

** So this will add one untill it gets to 8 when it is 8 it will stop. **


Function Copying
by: Sp0nge


I've had to explain it a whole bunch of times and instead of having it spread out everywhere I might aswell dedicate a thread to it.

What is the stack copier?

The "function rewriter" or "stack copier" is the actual sub-routine which moves the functions (specified by the stack addresses) in their given order to the new address.

What is a stack?

A stack, in the context of code hacking here, is a list of addresses which represent the starting address of a function. The specified functions are intended to be copied to a new area of memory which isn't in the ban range, so we can manipulate it freely. The order is based on the "last in first out" principal, and takes the top address first, followed by the second, and so on, until the end.

For example.

Let's just say we had the following in the memory of a ps2.

Note: Don't be frightened of the peso/dollar sign, it just identifies the proceeding numbers as a hexadecimal constant (unchanging), which in this case refers to an address. The 0x also identifies a hexadecimal number. There are a bunch of others ways to show hexadecimal FYI, including a subscript 16, and in colour referencing, they are prefixed with a # sign. Yes you have seen that in HTML and CSS.

$00000000 :: 0xFFFFFFFF
$00000004 :: 0xFFFFFFFF
$00000008 :: 0xFFFFFFFF
$0000000C :: 0xFFFFFFFF
$00000010 :: 0x03e00008
$00000014 :: 0x00000000

// Some crap in between

$00000100 :: 0x12345678
$00000104 :: 0x12345678
$00000108 :: 0x12345678
$0000010C :: 0x12345678
$00000110 :: 0x03e00008
$00000114 :: 0x00000000

Ok, so there we have 2 functions. One beginning at address $00000000 and the other $00000100. For the purpose of this tutorial, lets pretend those are in the ban range and we want to move them to a safe area. We would set up 'code' or 'stack' list like this.

Stack
20096000 00000000
20096004 00000100

The addresses are highlighted in red, and the output after running the stack copier would be as follows.

$000a0000 :: 0xFFFFFFFF
$000a0004 :: 0xFFFFFFFF
$000a0008 :: 0xFFFFFFFF
$000a000C :: 0xFFFFFFFF
$000a0010 :: 0x03e00008
$000a0014 :: 0x00000000
$000a0018 :: 0x12345678
$000a001c :: 0x12345678
$000a0020 :: 0x12345678
$000a0024 :: 0x12345678
$000a0028 :: 0x03e00008
$000a002c :: 0x00000000

The first routine is in blue and the second in green purely to aid your understanding.

The copier knows when to stop when it reaches data that reads 0x03e00008, and then it copies one more after that, because the next proceeding line after a jr (and other some other jumps) is executed.

What is the activation?

The "activation" codes define the new execution paths the game must follow in order to execute our ban-free modified functions which have just been relocated.

Unfortunately, these are especially important. Simplying moving the games code around isn't enough, and it can't automatically detect where we've moved it to.

With the above example still in mind, try to understand that throughout the game there are lines of code which jump to those functions in order to have them execute. For this tutorial, the following jumps are what jump to our hypothetical functions.

$00111110 :: 0c000000 jal $00000000 // This line "jump and link"'s to address $00000000
$00111118 :: 0c000040 jal $00000100 // This line "jump and link"'s to address $00000100

After running the copier, those lines are still in tact! Meaning they are still executing the original function. We need to point them to the ones we (essentially) created. To do this, we find out the new addresses by running the stack copier in ps2dis (a little advanced for this tutorial..) or with a little math. You can tell the new addresses by looking at the output (in blue and green) from previously.

The first function we copied will now be located at $000a0000 and the second function will be located at $000a0018.

That means the addresses need to be

$00111110 :: 0c280000 jal $000a0000
$00111118 :: 0c028006 jal $000a0018

In order to achieve this we would write the code as a 32-bit constant write (2 command ):

20111110 0c280000
20111114 0c028006

Now, the activation codes must be jokered, and only activated after the stack copier has been run. Prior to running the copier, there is just nop's at the location the activation codes would point to, so running it before the copier has copied the functions would be disastrous and guarantee you a place in freeze-land.