All tools mentioned can be found here
I put time up there because it really does take time to get codes, and even longer to become a good hacker. I've only be going for a couple of years and as you go you teach yourself all sorts of tricks - by sharing those tricks with people you gain knowledge and advance yourself.
So - that's all you'll need for the meantime, between now and next lesson grab the stuff and try experimenting with some games - get used to the feel of VBA, you'll be using it a lot.
The main (and easiest) method that I will be teaching you, is known as the 'Compare and Contrast' method. Basically, this is how it works:
A copy of the games RAM [Random Access Memory] is made.
The game advances then another copy (or 'snapshot') of the RAM is made. These two snapshots are compared using a logical comparison.
Those bytes that return 'True' for the logical comparison are saved, the rest are eliminated.
This process continues until you have narrowed down to the byte you are looking for.
The most common logical operators are
These should be self-explanatory but if you aren't really that sharp...
e.g. Say a snapshot is made and some of the values are as follows:
01, 25, 62, 00, 00, 55, 97
Another snapshot is taken later, and the values are now:
01, 29, 46, 00, 78, 55, 94
If the Equal to comparison was made, the 4th (00) and 6th (55) values would remain.
If a Greater Than or Equal to was done, the 2nd, 4th, 5th and 6th values would remain.
Mini-guide - Hexadecimal
Hexadecimal is a Base-16 counting system. Below is a little guide I wrote on Base Numbers, it could be kinda confusing so if you have any questions just post them.
<snip>
Base
The first thing you must understand is how to count. To understand this, you must understand the concept of 'bases'.
Decimal, is Base-10 notation. This means, that there are ten different digits in decimal. They are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 . Count them. There's ten of them. When you're counting in Base-10 notation, you go 0, 1, 2, 3 ...¦ 7, 8, 9 then once you've used up all of the ten digits you go 10, 11.
Now, imagine if there were only 9 digits (when I say '9' I'm still talking in decimal, confused?), i.e. the digits are 0, 1, 2, 3, 4, 5, 6, 7, 8. So, when counting in Base-9 (this form of counting doesn't exist), you would go 0, 1, 2, 3, ...¦ 7, 8, 10, 11, 12 ...¦
So, that's what I mean when I'm talking about Base.
Warning: Complex Mathematical Explanation Follows.
To convert any number in any counting system to decimal, do as follows. (Note: This is optional, you can use the Windows Calculator to do any conversions necessary for code hacking).
Going from right to left
Take the value of the first digit. Multiply it by <Base Number> raised to the power of 0.
Take the value of the second digit. Multiply it by <Base Number> raised to the power of 1.
Take the value of the third digit. Multiply it by <Base Number> raised to the power of 2
You can see the pattern: Take the value of the digit and multiply it by the base number raised to the power of the digit number it is minus one. Add all of these together.
A worked example
Convert the number 74403
3 * (8 ^ (1-1) ) = 3 0 * (8 ^ (2-1) ) = 0 4 * (8 ^ (3-1) ) = 256 4 * (8 ^ (4-1) ) = 2048 7 * (8 ^ (5-1) ) = 286723 + 0 + 256 + 2048 + 28672 = 30979
Binary
Binary is a Base-2 counting system ('binary' means 2). Computers use this because there are only 2 'states' (digits), 0 or 1. These are represented by an electrical impulse (1), or a lack of an electrical impulse (0).
When counting in binary, you would go: 0, 1, 10, 11, 100, 101, 110, 111 etc...
It isn't essential to know how to convert from binary to decimal, as you can just use the windows calculator, however, the above method can also be used.
When talking about binary numbers you should add the suffix 'b' to it, e.g. 10110b to avoid confusion.
Octal
Octal is a Base-8 counting system. Octal is used very seldom and you will not need to know it for code hacking.
Hexadecimal
This is the most important section, possibly in this entire document. If you do not understand hex then you'll never code hack. The reason for this is that codes are written in hex.
Hexadecimal is a Base-16 system. Base-16?? Yes, hexadecimal comprises the following digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F . So, counting in hex would be like
0, 1, 2 ... 8, 9, A, B, C, D, E, F, 10, 11, 12 ... 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20, 21 ... 98, 99, 9A, 9B, 9C, 9D, 9E, 9F, A0, A1, A2, A3 ... A9, AA, AB, AC ... FC, FD, FE, FF, 100, 101 etc, etc.
So, time for a pop-quiz (borrowed from the Hacking Text):
What comes after 19? What comes after 2F? What comes after AF?
---
If the answers you got were 2A, 30 and B0, then hopefully you understand hex!
Hex numbers should be prefixed with '0x', e.g. 0x4F, suffixed with an 'h', e.g. A3h, or prefixed with a '$', e.g. $03E7
This section is full of some of the technical details of the GBA. Not all those specs and stuff, but mostly information on the memory map. It doesn't really matter if you don't understand most of this - I don't think any other hacking guides would include this kinda info but IMO if you understand what you are really doing it makes you better.
Memory Map
There are 8 main regions of memory that the GBA uses. These can be divided into 4 parts: General Internal, Internal Display, External and Unused.
Note: From here on in I will be using the numercy conventions mentioned in lesson two, all un prefixed/suffixed numbers are to be taken as decimal. Also, the GBA ignores the colon ( when referring to memory addresses - it is only included here for some geeky reason.
General Internal
These are all stored on the GBA itself (as is the Internal Display Memory). It consists of:
The BIOS: Ranges from 0x0000:0000 - 0x0000:3FFF. This contains the Basic Input/Output functions (hence the name). You SHOULD NOT touch this at all (you shouldn't be able to anyway).
EWRAM: Ranges from 0x0200:0000 - 0x0203:FFFF . This is the On-Board (External) Working RAM. Most of the data that the game uses (non-permanent) is stored here and we will be doing most of our modifying here.
IWRAM: Ranges from 0x0300:0000 - 0x0300:7FFF . AKA the In-chip (Internal) WRAM. Similar to the EWRAM. It isn't as commonly used as the WRAM, but is still used (you don't need to know the difference between the two - just that they're in different places physically and virtually).
I/O: Ranges from 0x0400:0000 - 0x0400:03FE . Proper name is the Input/Output registers. You won't be dealing much with these either - there's only 1 address you need to remember and that's 0x04000130 - which is where the condition of the buttons is stored (what buttons are being pressed, etc...)
Internal Display
I'm going to gloss over these quickly as they don't really concern code hackers but some of you Game Modders may be interested.
Palette: Ranges from 0x0500:0000 - 0x0500:03FF . Full name is the Background/Object Palette. Not surprisingly it contains palette specific information.
VRAM: Ranges from 0x0600:0000 - 0617:FFFF . Stands for Video RAM. This contains all of the Video data - including what is being displayed on-screen.
OAM: Ranges from 0x0700:0000 - 0x0700:03FF. Object Attribute Memory, holds information about sprites.
External Memory (Game Pak)
All of this data is on the actual cart itself. This is kind of confusing because there are actually 3 ROM/FlashROM data areas - 0x0800:0000 - 0x09FF:FFFF, 0x0A00:0000 - 0x0BFF:FFFFand 0x0C00:0000 - 0x0DFF:FFFF . They are accessed depending on the WaitState, with the first when it is 0 and last when it is 2 (you don't have to understand any of this). Finally there's the SRAM - 0x0E00:0000 - 0x0E00:FFFF , which is intended as an extension to the WRAM (your save games end up here).
The only area of the External Memory we will be dealing with is the 0x08000000 - 0x09FFFFFF block. All devices except the Codebreaker/Xploder (currently) are able to 'write' to this area. The GSA V.1 can only hold 1 'patch', the AR V3 up to 3. I'll breifly explain how they do this.
There is a special chip in these devices called the FPGA (I don't know what this stands for, don't ask). Basically, what it does is intercepts any reads from a particular ROM address and replaces it with what is determined by the code. Therefore, the actual ROM is not written to, merely it's data is intercepted and changed.
So - that's about as complex as this guide will get - if you don't understand any of it, don't be too worried. Now - onto something a bit simpler.
There's also SRAM at 0x0E00:0000, but I'm going to ignore that for the time being.
About Us HackersFinally, we'll start doing some hacking. Today, we'll start with the simplest code possible - Infinite HP. I'll walk you step-by-step through the hacking of an infinite HP code for Final Fantasy Tactics Advance (a game I've being doing A LOT of work on recently).Finally, we'll start doing some hacking. Today, we'll start with the simplest code possible - Infinite HP. I'll walk you step-by-step through the hacking of an infinite HP code for Final Fantasy Tactics Advance (a game I've being doing A LOT of work on recently).
* 1. Boot up VisualBoyAdvance. Load up the ROM (it's up to you to find this).
* 2. We'll be wanting to hack an INF HP code for the main character (Marche). So, go to the Cheats Menu and select 'Search for Cheats' [Note: You should set a hotkey for this dialog - the default is Ctrl+C . I suggest you leave it like this but if you want to change it goto Tools -> Customize -> CheatsSearch and set the desired key combination].
* 3. Now, in lesson two, I said that comparisons are made between two RAM snapshots. Well, that was a teensy lie. There's another way. You can also make comparisons against a specified value. In VBA, you can switch between the two by either selecting 'Old value' or 'Specific Value', the latter being the method I just mentioned. So, select Specific Value and you'll notice that the edit box at the bottom is enabled. Now - what kind of search type will we use? Well, the obvious one would be Equal (by doing this, we can specify the HP, and VBA will search for all values 'Equal' to this value - thereby giving possible HP addresses). So, select Equal. For the other options, set datasize to 16 bits, and Signed/Unsigned to Unsigned. Also, check the Update values box.
* 4. Now, to start searching. To start a new search, press... Start. Now, in the Enter value box, type in how much HP Marche has (if you're not sure, press OK, check, then return to the dialog).
* 5. Hopefully, around 15 values will appear in the search results area at the top. We need to narrow this down, to get Marche's HP. So, what should we do? Easy, change the value of Marche's HP. How do we do this? Easy - go get hurt. So, return to the game and let Marche lose some HP.
* 6. Great, now Marche's HP has changed. Go back to the Cheat Search box. Leaving everything else the same, type in Marche's new HP in the edit box and press Search (note: if you stuff anything up, just press 'Start' to start again). Hopefully - you'll only have one value left. If not, repeat steps 5 and 6 until you only have one value in the box.
* 7. Wahoo! We've got Marche's HP address. So - how do we make a code. Well, I'm not going to explain this this lesson (<groan>), however, we can still make a cheat. Select the address in the Search Results box and click on Add cheat. Under value, put in the value you want Marche's HP to be. Fill in the description if you want to.
* 8. Return to the game - if you did everything correctly Marche's HP should now have been changed (HINT: If you got the address $02000098 , then you done it right!)
Congratulations! You've hacked your first code! Next lesson I'll be showing you how to make a functioning Codebreaker code from the address you found (and maybe do a bit more hacking as well).
Last lesson you hacked your first code - infinite HP for Marche. So, how do we turn the address we had into a functioning Codebreaker code (we will deal with Gameshark and Pro Action Replay another lesson)? Well, each device has a set of code types that it supports. So, we just find the right code type and substitute the values we want into it. Instead of posting every codebreaker codetype here (which would only confuse you at the moment), I'm just going to show you the one we need. For an infinite HP code we'd want a 'constant-write' code. This means that the device will always be writing this value to that address. We also need to know the data size - remember I told you to specify it as 16-bits when we searching for the code? So - the code we need is in this format
8xxxxxxx yyyy
Usually, the x's will stand for the address, and the y's for the value.
So, substituting our address (which we found in the previous lesson) into the code gives
82000098 yyyy
What value should we set the HP to? It doesn't really matter, but we might as well set it to the max, which is 999 or 0x03E7 in hex (all numbers in codes are in hex). So, our completed codebreaker code for Inf HP Marche is
82000098 03E7
Now - for your second code we're going to do something very similar, but as you'll find there is a slight twist - a score modifier for Harry Potter Quidditch World Cup...
Before I throw that curly QWC code at you - I think I should build up your code-hacking confidence a bit. So, we're going to hack a score modifier for Pokemon Pinball RS.
Try and find it yourself, you shouldn't have any problems. Just make sure you set the data-size to 32-bits - I might as well explain what that means now.
Data-size, funnily enough, refers to how big the data is, i.e. how much space is allocated to it. If you're not a computer geek - 8 bits is equal to 1 byte, 16 is 2 bytes and 32-bit is 4 bytes. So, if you're looking for small data (anything between 0 and 255), you'd set the search to 8-bits. If the data can get quite large (like a pinball score), you'd set it to 16 or 32 bits.
So, did you find it? If you didn't - read lesson four again. If you did, then you'll know the address is $02000044 . We're not going to make a code for this yet - because I'll have to talk about the concept of bit significance, which I plan to do next lesson.
Now, onto that Harry Potter code QWC I was talking about. Get the game and start searching. Unless you know more than I've taught you so far (in which case you don't really need to be reading this lesson, though you may find the later ones more interesting), you won't get it.
There are now two things we can do. We can give up, or we can think smart. I'll be teaching you how to do one of these.
So, we don't know how the game is storing the score. But I think it's safe to say that when your score goes up, the value that holds your score will also go up. What do we do? Think back to the first theory lesson - comparing different RAM snapshots - also known as the 'Unknown' (or Old Value) method ('Unknown' because we don't know what the value is). This is how we hack this code.
1. Start a new search. Set the Search type to Old Value. Set the datasize to 8-bit and Signed/Unsigned to Unsigned (you won't be hacking signed codes until I tell you what signed is ). Now, what about the Compare type. Whenever you start an Old Value search you should select 'Equal' (there are certain exceptions, e.g. if you're doing a mixed type search - forget I said that). This basically 'establishes' the search (you'll get a message saying that there are too many values to display).
2. Go score a goal!
3. You've scored a goal. Your score has gone up. The value holding your score has gone up. So, select as the compare type, 'Greater than'. Press Search. You probably won't get anything.
4. Move around, don't score a goal, then go back to the search dialog. Since your score hasn't changed, select Equal.
5. Repeat steps 3 and 4, varying the order (remember to choose the correct compare type, depending on whether your score has increased or stayed the same. You should eventually end up with the address $03002B5D .Press Add-Cheat and put in any value, say 8. If you did put in 8, you'll find that you have 80 points! So, the game stores 10 points as 1 (incidentally, each goal is worth 10 points).
Now, let's make a code. Let's make it so that you have 500 points.
500 / 10 = 50. 50 in hex is $32. The codebreaker code template for an 8-bit code is
3xxxxxxx 00yy
so, putting our values in we get
33002B5D 0032
It works! Awesome!
As you can see, I've chosen to devote an entire lesson to this concept, as it is very important and if I didn't explain it properly I'd be getting heaps of 'why does it do this' questions.
The GBA stores data in the Little-Endian format. This is a format where the least significant bits are stored in the first byte. Confused? Good. To show what I mean, we're going to have to go back to our old friend binary.
Note: You only need to worry about this when talking about 16bit or 32bit data.
Lets say that we have the value 0x94D6 in memory. In binary, this would be
1001010011010110
However, this is not how the GBA would store it. Remember, the least-significant bits are stored before the most significant. How do we know what is more significant? Remember how we convert from binary to decimal? You multiply the 1st digit (starting from the right), by 1, the 2nd by 2, the 3rd by 4, and so on, then add up all the values. Well, the least significat bit is the one that you multiply by the lowest number. [If you don't understand this it is VERY important that you do, so read that paragraph again].
So, our least significant bit is the rightmost '0'. You can now forget all of this complex binary stuff if you want because I'm going to demonstrate this visually.
To help illustrate this further, let's go into VBA. Load up any old game and then go to Tools -> Memory Viewer.
This tool shows all of the GBA memory. From the dropdown box at the left, select 0x02000000 - WRAM . This takes the memory viewer to the start of the WRAM. Now see those radio buttons to the right. These determine what format you view the data in. Now, put in on 8-bit and edit the first two hex pairs (those numbers in the big middle section) and change them to 01 and 02. Now - change the data size to 16-bit! What happens? The numbers turn into groups of four, and the order of the first group is 0201!
Now, change it back to 8-bit and change the first 4 pairs to 01, 02, 03, 04. Put in onto 32-bit! You get 04030201! The moral of the story is: When you're using 16-bit or 32-bit, the group of bytes are in the REVERSE order to what they were when they were single 8-bit bytes.
So, let's have some practice at converting between datasizes. (If you want you can use the memory viewer to help you).
The values are (as 8-bit): 06 8D 47 E5 98 12 3C 96
Re-arrange them into 16-bit, and then 32-bit groups. The answers are below (don't look!)
---
16-bit: 8D06 E547 1298 963C
32-bit: E5478D06 963C1298
If you did not get this right, read the ENTIRE lesson over again until you know what I've done.
For those of you who are interested, let's go back to our binary analogy. We had the value $94D6, as binary, 1001010011010110 . Let's split this into two bytes (8-bits).
10010100 11010110
Now, the least significant values come first, so we need to swap these two bytes around to
11010110 10010100
Now, if you convert these back to hexadecimal, you get ... $D694 !!! See, the bytes have just swapped around!
I hate Interact. I hate Datel. I hate MadCatz. Reason: Their devices use encrypted codes!
For those of you who haven't heard of the term, it means they foobar their codes with loads of fancy algorithms until we don't know what they are. This is a real pain for code hackers because it means every code we make must be encrypted so that their cheat device can decrypt it and understand what we are telling it to do.
All encrypted codes have a corresponding 'RAW' code. The 'RAW' code is what the code looks like before it is encrypted. The raw code should be thought of as the actual code type, as it is, the encrypted code is just that, the code having been encrypted.
Now, it would be a real pain if we had to encrypt these codes for ourselves. Just for interest, here is the Gameshark/AR v.1/2/3 code encryption algorithms in C++, written by Parasyte who I believe was the one who reverse-engineered it in the first place, thus allowing code hackers like us to take advantage of programs such as GSACrypt and ARCrypt.
typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; u32 seeds[4]; u8 v3enc; //seed tables for AR v1 u8 v1_deadtable1[256] = { 0x31, 0x1C, 0x23, 0xE5, 0x89, 0x8E, 0xA1, 0x37, 0x74, 0x6D, 0x67, 0xFC, 0x1F, 0xC0, 0xB1, 0x94, 0x3B, 0x05, 0x56, 0x86, 0x00, 0x24, 0xF0, 0x17, 0x72, 0xA2, 0x3D, 0x1B, 0xE3, 0x17, 0xC5, 0x0B, 0xB9, 0xE2, 0xBD, 0x58, 0x71, 0x1B, 0x2C, 0xFF, 0xE4, 0xC9, 0x4C, 0x5E, 0xC9, 0x55, 0x33, 0x45, 0x7C, 0x3F, 0xB2, 0x51, 0xFE, 0x10, 0x7E, 0x75, 0x3C, 0x90, 0x8D, 0xDA, 0x94, 0x38, 0xC3, 0xE9, 0x95, 0xEA, 0xCE, 0xA6, 0x06, 0xE0, 0x4F, 0x3F, 0x2A, 0xE3, 0x3A, 0xE4, 0x43, 0xBD, 0x7F, 0xDA, 0x55, 0xF0, 0xEA, 0xCB, 0x2C, 0xA8, 0x47, 0x61, 0xA0, 0xEF, 0xCB, 0x13, 0x18, 0x20, 0xAF, 0x3E, 0x4D, 0x9E, 0x1E, 0x77, 0x51, 0xC5, 0x51, 0x20, 0xCF, 0x21, 0xF9, 0x39, 0x94, 0xDE, 0xDD, 0x79, 0x4E, 0x80, 0xC4, 0x9D, 0x94, 0xD5, 0x95, 0x01, 0x27, 0x27, 0xBD, 0x6D, 0x78, 0xB5, 0xD1, 0x31, 0x6A, 0x65, 0x74, 0x74, 0x58, 0xB3, 0x7C, 0xC9, 0x5A, 0xED, 0x50, 0x03, 0xC4, 0xA2, 0x94, 0x4B, 0xF0, 0x58, 0x09, 0x6F, 0x3E, 0x7D, 0xAE, 0x7D, 0x58, 0xA0, 0x2C, 0x91, 0xBB, 0xE1, 0x70, 0xEB, 0x73, 0xA6, 0x9A, 0x44, 0x25, 0x90, 0x16, 0x62, 0x53, 0xAE, 0x08, 0xEB, 0xDC, 0xF0, 0xEE, 0x77, 0xC2, 0xDE, 0x81, 0xE8, 0x30, 0x89, 0xDB, 0xFE, 0xBC, 0xC2, 0xDF, 0x26, 0xE9, 0x8B, 0xD6, 0x93, 0xF0, 0xCB, 0x56, 0x90, 0xC0, 0x46, 0x68, 0x15, 0x43, 0xCB, 0xE9, 0x98, 0xE3, 0xAF, 0x31, 0x25, 0x4D, 0x7B, 0xF3, 0xB1, 0x74, 0xE2, 0x64, 0xAC, 0xD9, 0xF6, 0xA0, 0xD5, 0x0B, 0x9B, 0x49, 0x52, 0x69, 0x3B, 0x71, 0x00, 0x2F, 0xBB, 0xBA, 0x08, 0xB1, 0xAE, 0xBB, 0xB3, 0xE1, 0xC9, 0xA6, 0x7F, 0x17, 0x97, 0x28, 0x72, 0x12, 0x6E, 0x91, 0xAE, 0x3A, 0xA2, 0x35, 0x46, 0x27, 0xF8, 0x12, 0x50 }; u8 v1_deadtable2[256] = { 0xD8, 0x65, 0x04, 0xC2, 0x65, 0xD5, 0xB0, 0x0C, 0xDF, 0x9D, 0xF0, 0xC3, 0x9A, 0x17, 0xC9, 0xA6, 0xE1, 0xAC, 0x0D, 0x14, 0x2F, 0x3C, 0x2C, 0x87, 0xA2, 0xBF, 0x4D, 0x5F, 0xAC, 0x2D, 0x9D, 0xE1, 0x0C, 0x9C, 0xE7, 0x7F, 0xFC, 0xA8, 0x66, 0x59, 0xAC, 0x18, 0xD7, 0x05, 0xF0, 0xBF, 0xD1, 0x8B, 0x35, 0x9F, 0x59, 0xB4, 0xBA, 0x55, 0xB2, 0x85, 0xFD, 0xB1, 0x72, 0x06, 0x73, 0xA4, 0xDB, 0x48, 0x7B, 0x5F, 0x67, 0xA5, 0x95, 0xB9, 0xA5, 0x4A, 0xCF, 0xD1, 0x44, 0xF3, 0x81, 0xF5, 0x6D, 0xF6, 0x3A, 0xC3, 0x57, 0x83, 0xFA, 0x8E, 0x15, 0x2A, 0xA2, 0x04, 0xB2, 0x9D, 0xA8, 0x0D, 0x7F, 0xB8, 0x0F, 0xF6, 0xAC, 0xBE, 0x97, 0xCE, 0x16, 0xE6, 0x31, 0x10, 0x60, 0x16, 0xB5, 0x83, 0x45, 0xEE, 0xD7, 0x5F, 0x2C, 0x08, 0x58, 0xB1, 0xFD, 0x7E, 0x79, 0x00, 0x34, 0xAD, 0xB5, 0x31, 0x34, 0x39, 0xAF, 0xA8, 0xDD, 0x52, 0x6A, 0xB0, 0x60, 0x35, 0xB8, 0x1D, 0x52, 0xF5, 0xF5, 0x30, 0x00, 0x7B, 0xF4, 0xBA, 0x03, 0xCB, 0x3A, 0x84, 0x14, 0x8A, 0x6A, 0xEF, 0x21, 0xBD, 0x01, 0xD8, 0xA0, 0xD4, 0x43, 0xBE, 0x23, 0xE7, 0x76, 0x27, 0x2C, 0x3F, 0x4D, 0x3F, 0x43, 0x18, 0xA7, 0xC3, 0x47, 0xA5, 0x7A, 0x1D, 0x02, 0x55, 0x09, 0xD1, 0xFF, 0x55, 0x5E, 0x17, 0xA0, 0x56, 0xF4, 0xC9, 0x6B, 0x90, 0xB4, 0x80, 0xA5, 0x07, 0x22, 0xFB, 0x22, 0x0D, 0xD9, 0xC0, 0x5B, 0x08, 0x35, 0x05, 0xC1, 0x75, 0x4F, 0xD0, 0x51, 0x2D, 0x2E, 0x5E, 0x69, 0xE7, 0x3B, 0xC2, 0xDA, 0xFF, 0xF6, 0xCE, 0x3E, 0x76, 0xE8, 0x36, 0x8C, 0x39, 0xD8, 0xF3, 0xE9, 0xA6, 0x42, 0xE6, 0xC1, 0x4C, 0x05, 0xBE, 0x17, 0xF2, 0x5C, 0x1B, 0x19, 0xDB, 0x0F, 0xF3, 0xF8, 0x49, 0xEB, 0x36, 0xF6, 0x40, 0x6F, 0xAD, 0xC1, 0x8C }; //seed tables for AR v3 u8 v3_deadtable1[256] = { 0xD0, 0xFF, 0xBA, 0xE5, 0xC1, 0xC7, 0xDB, 0x5B, 0x16, 0xE3, 0x6E, 0x26, 0x62, 0x31, 0x2E, 0x2A, 0xD1, 0xBB, 0x4A, 0xE6, 0xAE, 0x2F, 0x0A, 0x90, 0x29, 0x90, 0xB6, 0x67, 0x58, 0x2A, 0xB4, 0x45, 0x7B, 0xCB, 0xF0, 0x73, 0x84, 0x30, 0x81, 0xC2, 0xD7, 0xBE, 0x89, 0xD7, 0x4E, 0x73, 0x5C, 0xC7, 0x80, 0x1B, 0xE5, 0xE4, 0x43, 0xC7, 0x46, 0xD6, 0x6F, 0x7B, 0xBF, 0xED, 0xE5, 0x27, 0xD1, 0xB5, 0xD0, 0xD8, 0xA3, 0xCB, 0x2B, 0x30, 0xA4, 0xF0, 0x84, 0x14, 0x72, 0x5C, 0xFF, 0xA4, 0xFB, 0x54, 0x9D, 0x70, 0xE2, 0xFF, 0xBE, 0xE8, 0x24, 0x76, 0xE5, 0x15, 0xFB, 0x1A, 0xBC, 0x87, 0x02, 0x2A, 0x58, 0x8F, 0x9A, 0x95, 0xBD, 0xAE, 0x8D, 0x0C, 0xA5, 0x4C, 0xF2, 0x5C, 0x7D, 0xAD, 0x51, 0xFB, 0xB1, 0x22, 0x07, 0xE0, 0x29, 0x7C, 0xEB, 0x98, 0x14, 0xC6, 0x31, 0x97, 0xE4, 0x34, 0x8F, 0xCC, 0x99, 0x56, 0x9F, 0x78, 0x43, 0x91, 0x85, 0x3F, 0xC2, 0xD0, 0xD1, 0x80, 0xD1, 0x77, 0xA7, 0xE2, 0x43, 0x99, 0x1D, 0x2F, 0x8B, 0x6A, 0xE4, 0x66, 0x82, 0xF7, 0x2B, 0x0B, 0x65, 0x14, 0xC0, 0xC2, 0x1D, 0x96, 0x78, 0x1C, 0xC4, 0xC3, 0xD2, 0xB1, 0x64, 0x07, 0xD7, 0x6F, 0x02, 0xE9, 0x44, 0x31, 0xDB, 0x3C, 0xEB, 0x93, 0xED, 0x9A, 0x57, 0x05, 0xB9, 0x0E, 0xAF, 0x1F, 0x48, 0x11, 0xDC, 0x35, 0x6C, 0xB8, 0xEE, 0x2A, 0x48, 0x2B, 0xBC, 0x89, 0x12, 0x59, 0xCB, 0xD1, 0x18, 0xEA, 0x72, 0x11, 0x01, 0x75, 0x3B, 0xB5, 0x56, 0xF4, 0x8B, 0xA0, 0x41, 0x75, 0x86, 0x7B, 0x94, 0x12, 0x2D, 0x4C, 0x0C, 0x22, 0xC9, 0x4A, 0xD8, 0xB1, 0x8D, 0xF0, 0x55, 0x2E, 0x77, 0x50, 0x1C, 0x64, 0x77, 0xAA, 0x3E, 0xAC, 0xD3, 0x3D, 0xCE, 0x60, 0xCA, 0x5D, 0xA0, 0x92, 0x78, 0xC6, 0x51, 0xFE, 0xF9, 0x30 }; u8 v3_deadtable2[256] = { 0xAA, 0xAF, 0xF0, 0x72, 0x90, 0xF7, 0x71, 0x27, 0x06, 0x11, 0xEB, 0x9C, 0x37, 0x12, 0x72, 0xAA, 0x65, 0xBC, 0x0D, 0x4A, 0x76, 0xF6, 0x5C, 0xAA, 0xB0, 0x7A, 0x7D, 0x81, 0xC1, 0xCE, 0x2F, 0x9F, 0x02, 0x75, 0x38, 0xC8, 0xFC, 0x66, 0x05, 0xC2, 0x2C, 0xBD, 0x91, 0xAD, 0x03, 0xB1, 0x88, 0x93, 0x31, 0xC6, 0xAB, 0x40, 0x23, 0x43, 0x76, 0x54, 0xCA, 0xE7, 0x00, 0x96, 0x9F, 0xD8, 0x24, 0x8B, 0xE4, 0xDC, 0xDE, 0x48, 0x2C, 0xCB, 0xF7, 0x84, 0x1D, 0x45, 0xE5, 0xF1, 0x75, 0xA0, 0xED, 0xCD, 0x4B, 0x24, 0x8A, 0xB3, 0x98, 0x7B, 0x12, 0xB8, 0xF5, 0x63, 0x97, 0xB3, 0xA6, 0xA6, 0x0B, 0xDC, 0xD8, 0x4C, 0xA8, 0x99, 0x27, 0x0F, 0x8F, 0x94, 0x63, 0x0F, 0xB0, 0x11, 0x94, 0xC7, 0xE9, 0x7F, 0x3B, 0x40, 0x72, 0x4C, 0xDB, 0x84, 0x78, 0xFE, 0xB8, 0x56, 0x08, 0x80, 0xDF, 0x20, 0x2F, 0xB9, 0x66, 0x2D, 0x60, 0x63, 0xF5, 0x18, 0x15, 0x1B, 0x86, 0x85, 0xB9, 0xB4, 0x68, 0x0E, 0xC6, 0xD1, 0x8A, 0x81, 0x2B, 0xB3, 0xF6, 0x48, 0xF0, 0x4F, 0x9C, 0x28, 0x1C, 0xA4, 0x51, 0x2F, 0xD7, 0x4B, 0x17, 0xE7, 0xCC, 0x50, 0x9F, 0xD0, 0xD1, 0x40, 0x0C, 0x0D, 0xCA, 0x83, 0xFA, 0x5E, 0xCA, 0xEC, 0xBF, 0x4E, 0x7C, 0x8F, 0xF0, 0xAE, 0xC2, 0xD3, 0x28, 0x41, 0x9B, 0xC8, 0x04, 0xB9, 0x4A, 0xBA, 0x72, 0xE2, 0xB5, 0x06, 0x2C, 0x1E, 0x0B, 0x2C, 0x7F, 0x11, 0xA9, 0x26, 0x51, 0x9D, 0x3F, 0xF8, 0x62, 0x11, 0x2E, 0x89, 0xD2, 0x9D, 0x35, 0xB1, 0xE4, 0x0A, 0x4D, 0x93, 0x01, 0xA7, 0xD1, 0x2D, 0x00, 0x87, 0xE2, 0x2D, 0xA4, 0xE9, 0x0A, 0x06, 0x66, 0xF8, 0x1F, 0x44, 0x75, 0xB5, 0x6B, 0x1C, 0xFC, 0x31, 0x09, 0x48, 0xA3, 0xFF, 0x92, 0x12, 0x58, 0xE9, 0xFA, 0xAE, 0x4F, 0xE2, 0xB4, 0xCC }; void decrypt_code(u32 *address, u32 *value); void encrypt_code(u32 *address, u32 *value); void deadface(u16 value); u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2); void decrypt_code(u32 *address, u32 *value) { int i; u32 rollingseed = 0xC6EF3720; for (i = 0; i < 32; i++) { *value -= ((((*address << 4) + seeds[2]) ^ (*address + rollingseed)) ^ ((*address >> 5) + seeds[3])); *address -= ((((*value << 4) + seeds[0]) ^ (*value + rollingseed)) ^ ((*value >> 5) + seeds[1])); rollingseed -= 0x9E3779B9; } if (*address == 0xDEADFACE) deadface(*value); } void encrypt_code(u32 *address, u32 *value) { int i; u32 rollingseed = 0, oldaddr = *address, oldval = *value; for (i = 0; i < 32; i++) { rollingseed += 0x9E3779B9; *address += ((((*value << 4) + seeds[0]) ^ (*value + rollingseed)) ^ ((*value >> 5) + seeds[1])); *value += ((((*address << 4) + seeds[2]) ^ (*address + rollingseed)) ^ ((*address >> 5) + seeds[3])); } if (oldaddr == 0xDEADFACE) deadface(oldval); } void deadface(u16 value) { int i; u8 *deadtable1, *deadtable2; if (v3enc) { deadtable1 = (u8*)(&v3_deadtable1); deadtable2 = (u8*)(&v3_deadtable2); } else { deadtable1 = (u8*)(&v1_deadtable1); deadtable2 = (u8*)(&v1_deadtable2); } for (i = 0; i < 4; i++) seeds[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2); //printf("Encryption Seeds Have Changed!\n"); } u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2) { int i; u32 newseed; for (i = 0; i < 4; i++) newseed = ((newseed << 8) | ((deadtable1[(i + upper) & 0xFF] + deadtable2[seed]) & 0xFF)); return newseed; } As you can see, that would really suck.
As you can see, that would really suck.
So, we have programs to do this for us. For Gameshark and Action Replay (any version) we use a program called ARCrypt.
For MadCatz Gameshark SP/Codebreaker we use a program called CBACrypt
Slight Digression: The Codebreaker Advance also supports encrypted codes and has it's own encryption algorithms, although no one ever encrypts CBA codes because they don't need to be. The MadCatz GS SP, however, is actually a Codebreaker - MadCatz encrypts their codes, which is why they look so weird.
---
Now, I will be teaching you how to use these tools to create codes. We'll be creating the codes we hacked previously, Inf Marche HP and the Pinball score and the HP QWC score codes.
Infinite Hp - Marche
The RAW 16-bit GSA code is 1xxxxxxx 0000yyyy . So, let's substitute our values in and we get:
12000098 000003E7
Now to encrypt it. Boot up ARCrypt. In the big box on the left, enter in the code. Under 'From' select RAW, under 'To', select AR V.1/2 (the Action Replay V.1/2 is the same thing as a Gameshark). Click proceed. You should get
D0D63EAA FD4C724B
Now, let's do the ARV.3 code for it. The RAW ARformat is very complex - I won't be showing you it until the later lessons (there's some very complex maths involved). However, we can convert V.1/2 codes to V.3. Put in the V.1/2 code in the left box, set 'From' to AR V.1/2, 'To' to AR V.3, and CHECK THE BOX AT THE BOTTOM that says\'Convert AR V.1/V.2 to AR V.3'. It is very important you do this. Press Proceed and you\'ll get
EC840F80 42C79FE7
So, that's that code.
Pokemon Pinball R/S score
The RAW 32-bit GSA code is
2xxxxxxx yyyyyyyy
You should be able to encrypt this yourself. We haven't done the Codebreaker code for this yet (next lesson), but you should be able to encrypt this code easily using the same principle. You can put any value in for the y's (if you set them all to F's then this is the max value).
The code I encrypted was
22000044 FFFFFFFF
and I got
CAB4E063 D7BEA4C4 for V.1/2
and
D49661E2 BE4355E3 for V.3.
Harry Potter QWC score
This should also be easy - I'm not even going to tell you what to encrypt, however, the 8-bit GSA code is
0xxxxxxx 000000yy
I got
37BD139D 86E9F12A for the V1/2 code
and
2C97D110 1849180B for the V3 code.
First of, a summary of the code types we know thus far.
8-bit Constant Write
CBA: 3xxxxxxx 00yy
GSA: 0xxxxxxx 000000yy
16-bit Constant Write
CBA: 8xxxxxxx yyyy
GSA: 1xxxxxxx 0000yyyy
32-bit Constant Write
CBA: N/A - you have to use two 16-bit codes
GSA: 2xxxxxxx yyyyyyyy
Now, let's make that pinball code for codebreaker. Our GSA raw code for this was 22000044 FFFFFFFF . Just to illustrate the concepts I'm going to use, let's change the value to 22000044 12345678 . Since the CBA doesn't have a 32-bit code, we can instead split this into 2 16-bit codes. So, we need to split the 32-bit value 12345678 into 2 16-bit value. How do we do this? Easy - just cut it down the middle (so there are 2 bytes in each group - 16 bits) and we get 1234 5678. Now, remember that I said that in the GBA the LEAST significant bits come first. So, in reality, this is 5678 1234 .
So, let's make the code.
The first address is 02000044. Let's stick this into the CBA 16-bit template and we get
82000044 5678
That's the first half of the code. For the second half, we have to increase the address by two. Why? Just imagine it visually. The full 32-bit takes up four bytes, the code we just made takes up the first of those 2 bytes. Now we want to fill up the 3rd and fourth bytes.
So, the complete code is
82000044 5678
82000046 1234
Now, let's hack an HP code for The Invincible Iron Man (we will probably be using this in a later ASM lesson). There is one trick to this code: The address changes depending on the level you're playing. So let's hack the code for level one.
(NOTE: For those of you who don't know, your health is the right bar).
Since the game doesn't tell you the value of the HP, we have to use the Unknown / Old value method. So, start an old value search the way I taught you earlier:
1. Set the datasize to what it should be [in this case, 8-bit]
2. Set Compare type to Equal
3. Press Start
4. Press Search
As I said before, this is the 'Establishing search'.
* Now, make your HP change somehow (the easies way is to get hit )
* Go back to the search dialog. If your HP went down - choose less than and hit search. If your HP (somehow) went up - choose
* Greater than and hit search.
* Go back to the game, run around WITHOUT getting hit (if you do, then do the step above) set the search type to equal, and press search.
Continue going through this process, with Less than searches along with some equal searches. You should eventually end up with around five addresses, that you can't narrow down any further. (this sometimes happens, you may have to change them all, or may only have to change one - you have to experiment).
Your searches should have turned up 5 addresses. If you had tested the first four you would have found that the bar stays still but after a while you still die. The last address ($020200ED) however is different.
Set it at any value and you won't die. This is the 'master value' which affects all of the other values (you'll notice that if you set this at a different value to your current HP the status bar will change as it usually does in the game - a gradual change instead of an instantaneous change).
The value you should have set it at is 100 - however for some strange reason it'll only set the other values to 90.
Nevertheless, the answers below assume you set the value to 100 [$64].
CBA: 320200ED 0064
GSA: 7EAB5894 A012512C
AR V3: F9951D58 109B0B25
Now for a different code. I actually thought of this code when I was checking the answers I gave above. You'll notice that when you jump into the air, you can jump in mid-air ONCE more (and you'll see a green air burst by your feet). Only once.
Wouldn't it be cool if you could keep on jumping in mid-air as many times as you like? Let's get hacking.
For this code you (or rather me, for you) will have to do a bit of thinking. It's not one of those straightforward mod the value codes. We need to think like a programmer.
I'm *guessing*, that there is a value that when you're:
* in the air, ABLE to jump a second time, is set to xxxx
* in the air, after jumping a second time, is set to yyyy
So, let's start searching. Obviously we'll be using the unknown method (although I could take a pretty accurate guess as to what the values are) - so do the establishing search.
Now you'll have to perform some comparisons. You don't have to do exactly what I do but make sure your searches are in agreement with my 'guess' above. Anyway, this is what I did.
1. Jumped into air. Establishing search [8-bit].
2. Jumped second time. Not Equal.
3. Landed. Jumped, into air, jump 2nd time. Equal.
4. Jumped. Not Equal.
5. While Falling. Equal.
6. Landed. Jumped. Equal.
7. Jumped 2nd time. Not equal.
8. Falling. Equal.
I basically continued this pattern until I was reduced to around 8 values. I would have tested each one in turn - setting it to the value that it is when you are able to jump again and seeing if it let me jump multiple times. However, I was smart and picked the correct value straight away. How did I know? Well, this value was the only one that when you could jump again was 0, and when you couldn't jump again was 1 (programmers will often use 1 and 0, because these represent the boolean TRUE and FALSE). It acted like a switch - once you couldn't jump the switch was thrown, and wouldn't let you jump again. This is why I had a pretty good idea what the values were going to be - although they may have switched the 1 and 0 around [which would have made more sense. 1 when you can jump (can jump=TRUE), 0 when you can't jump (can jump=FALSE). When in doubt, or you can't find the code, use and Unknown search, although known is always faster.]
Note: In case you didn't know, TRUE is 1, and FALSE is 0
So, what is the code? Well, like most values in this game it depends on the level, so I'm assuming we're still working on level 1. The address I got was $02020258 . The codes are:
CBA: 32020258 0000
GSA: E47E62B0 B5DD1727 (RAW: 02020258 00000000)
AR V3: FA6B3E89 342A2DEA
The concept of slots is very important - most hacking documents don't explain it as I am, but I find my description makes them easier to understand.
Think of a slot as a box. You can put anything into that box, but the box stays in the same place.
Slots are used to store many types of data - the most common that you will come across are items and abilities. (For the programmers out there, we're talking about an array, or something similar).
This is how a slot works: A particular address is assigned to represent something, say the first item in your inventory. This address contains a value. This value represents the first item in your inventory (continuing the example). You could think of this value as the ID for that certain item - if you were to put that ID into another slot, say for the second item, then that item would be in the second slot of your inventory.
If you don't understand this, hopefully this hacking exercise will. We'll be hacking an equipment modifier for Final Fantasy Tactics Advance - Marche's 1st equipment slot.
Unless you already know the IDs of what you are hacking, your searches will only use the Equal and Not-Equal compare types.
So, let's begin!.
* We're hacking the top equipment slot for Marche so empty this and do an establishing search [data size: 16 bit].
Important tip. When doing these types of codes it's often a good idea to do searches without the menu open, i.e. in-game, as well as on the equipment selection screen.
* Put something into the slot and do a not-equal.
* Close the menu, and do an equal.
* Change the item and do a not-equal.
* Now, let's do something sneaky Put the search type onto 'Specific Value', type in 0 in the value box and set the compare type to not equal. What we're doing here is getting rid of all values that are 0, as it's a pretty good bet that when there's an item in the slot the value won't be 0.
* Okay, empty the slot, set the search-type back to Old value, and do a not-equal.
* By now you should have a list of addresses in the result box, along with the values. We could keep on going, narrowing down our search, or we could use a bit of what +ORC (the legendary Software Reverse Engineer, aka Cracker) would call Zen. We've already hacked Marche's HP. It's a pretty could bet that all of Marche's data will have been stored in one area. Marche's HP was $02000098 . So, let's look for an address near there.
*looks quickly*
Aha! The top address (for me anyway), is $ 020000aa. Let's try changing that, to say, 43 (click Add Cheat and type in 43 as the value).
Ooh, cool! Ragnarok is now in the first slot. So, we've found the address. Now, to get all those IDs, so we can make up a big list and be able to get any item we want. There are several ways of doing this. If the game stores the data in the right way, and you've done a bit of Rom hacking then you may be able to rip the names out in the right order, though the method I'm going to show you is much easier.
We're going to use the memory editor. Open it - Tools -> Memory Viewer. The address we're dealing with is $020000aa so enter that into the box (without the "$"), and press go. Set the view to 16-bit.
You're screen will look something like this
0x00000000 - BIOS || O8-bit O16-bit O32-bit | 020000AA | | Go | 020000AA | 002B 0000 0000 0000 0000 028E 0000 0000 | +............... 020000BA | 0000 000B 0000 0000 0000 0000 0000 0000 | ................ 020000CA | E480 0000 0000 0000 0000 0000 0000 0000 | ................ 020000DA | 0000 0000 0000 0000 0000 0000 0000 0000 | ................ 020000EA | 0000 0000 0000 0000 0000 0000 0000 0000 | ................ 020000FA | 0000 0000 0000 0000 0000 0000 0000 0000 | ................ 0200010A | 0000 0000 0000 0000 0000 0000 0000 0000 | ................ 0200011A | 0000 0000 0000 0000 0000 0000 0000 0000
etc, etc...
It may not look exactly the same (the values will probably be different), but pretty similar.
What we're going to do, is manually edit the slot, which is currently the value '002B'. Remove the cheat we had on (Cheats->Cheat List->Remove All) and change it to 0001.
Go to the equipment screen, and you'll see Marche has a Shortsword. So, '0001' represents Shortsword. Change it to '0002'. See what Marche has now and write it down. This can be a very time consuming process, however it's necessary to make a complete code.
Presenting slot codes
When presenting slot codes, you write it as a normal code, substituting the value with a variable, usually x's. You then list all of the IDs below. e.g.:
- CBA -
820000AA xxxx
0001: Shortsword
0002: Blah blah
0003: Blah blah blah
Obviously, for GSA and AR you can't do this with encrypted codes, however you can present the unencrypted codes. When I'm writing code FAQs I usually provide some encrypted codes (e.g. for the first slot only) in the Appendices. For an example, see my Code FAQ for Golden Sun: The Lost Age at GameFAQs
Today I'm going to show you something really cool you can do with these cheat devices. You may or may not remember me telling you to remember the address $04000130 . Now you're going to find out why. This is where the state of the buttons you're pressing down is held.
This wouldn't be special - apart from the fact that all devices have an 'if' code. An if code works like this. If value at aaaa is equal to yyyy, then execute the next code. If not, then the following code is not used.
Therefore, you can set codes that are only activated when certain buttons are pressed. Us codehackers call this a 'jokered' code, the if code that does this is called a 'joker' (don't ask me why, there's probably a story I haven't heard that explains this).
The code types are as follows:
CBA
7aaaaaaa yyyy
GSA
Daaaaaaa yyyy
If the value at aaaaaaaa is equal to yyyy, execute the next line.
Note: CBA also has a 'D' code type which can be used exclusively for pad activators.
Note: The 16-bit if equal modifier for AR V3++ is Type 05. There are additional 'if' codes available as well. See AR V3 Code Types for the full list.'
So, our joker codes are
74000130 yyyy
D4000130 yyyy
where yyyy is the value that represents the buttons we want the code to be activated by.
So, how do we get this value? There are two approaches.
1. The easy way. Open any ROM in VBA. In the memory viewer, goto $4000130. Set the view type to 16-bit and in the game hold down the buttons you want.
The value at $4000130 is the value you want.
2. The complex mathematically correct (eughh) way. Each button is assigned a value as follows:
$0001: A $0002: B $0004: Select $0008: Start $0010: Right $0020: Left $0040: Up $0080: Down $0100: R $0200: L
To get the correct value, find the values of the buttons you want, and OR (bitwise operator) them together. Then XOR the result with $03FF. All of this can be done with the Windows calculator in Scientific Mode with Hex selected.
E.g., we want B, Select and L.
$02 OR $04 = $06
$06 OR $0200 = $0206
$0206 XOR $03FF = $01F9
For example, let's take Marche's infinite HP code. Say we want it activated if the player holds the two trigger buttons (L and R). The value we want is
$0100 OR $0200 = $0300
$0300 XOR $03FF = $00FF
So, our Jokers are
CBA: 74000130 00FF
GSA: D4000130 000000FF
Then we get Marche's infinite HP code and stick it directly underneath it. The codes MUST BE ENTERED IN THE CORRECT ORDER.
CBA
74000130 00FF
82000098 FFFF
GSA
D4000130 000000FF
12000098 0000FFFF
The CBA code is now complete. You'll have to encrypt the GSA code before use, which results in
FB089E40 B13D1214
3E59CECF 16AA9139
Again, you'll have seen I haven't given you the AR V3 code. Next lesson, I'll show you how to make these, but in the meanwhile, you can convert the encrypted V.1/2 code to V3 using the method I showed you earlier (In ARCrypt: From - AR V.1/2 . To - AR V.3 . Checked 'Convert AR...' box.) The result is
B6C5368A 08BE8FF4
86D39A0B 9BF67FBB
This lesson will be entirely devoted into the workings of the Action Replay V.3. First, it must be noted that there are two 'forms' of the V3 - software and hardware. Software V3's are in essence V.1/2 hardware with V3 software (there is an upgrade that can be downloaded). Hardware V3's are the real thing (the difference only really comes into play when creating ROM patch codes, which will be covered in the advanced ASM hacking series).
The creation of codes for the V3 is one of the most complex things in the GBA code hacking world. There are no easy 'code templates' - a variety of mathematical operations are performed to gain the RAW codes that are then encrypted (the V.3 uses the same encryption algorithm as the v.1/2, but uses different encryption seeds).
Luckily, all of this has been implemented into ARCrypt which simplifies the process of creating V.3 codes greatly.
Things you will need: ARCrypt, The V3 Code Type Guide
Below is a more detailed explanation of how to create codes than the one provided in the above document.
This is the kind of thing you will find in the guide
--------------------------- 1) Normal RAM Write Codes : --------------------------- Type 00 0.0.0.x.x XXXXXXXX : (02024EA4 -> 00224EA4) YYYYYYZZ : Fill area (XXXXXXXX) to (XXXXXXXX+YYYYYY) with Byte ZZ.
The important part is the 0.0.0.x.x and 'Type 00'
The first part is the data size. The second part is the code type. The third part is code subtype. The fourth part is 'Special' The fifth part is 'Unused'.
i.e.
dataSize.codeType.codeSubtype.special.unused
The last two can be used to create 'signature' codes - this will be explained later.
These are the values you'll have to input into ARCrypt. To show this, we'll make a code - the Harry Potter QWC code. Remember the CBA code for this was 33002B5D 0032.
Boot up ARCrypt, and set it to Menu -> Expert Mode.
We want the 8-bit constant write code (writes an 8-bit value to a RAM address), which is Type 00 (the one in the example above). So, in the top center combo box select 'Type 00'. You will notice that the Datasize, type, subtype, special and unused value boxes change, to match the '0.0.0.x.x' part. Now, we have to tell the program what we want the code to do. The guide says
XXXXXXXX : (02024EA4 -> 00224EA4)
YYYYYYZZ : Fill area (XXXXXXXX) to (XXXXXXXX+YYYYYY) with Byte ZZ.
We want to fill the area 03002B5D - 03002B5D (just the one byte, so YYYYYY is 0) with the value 32.
So, in the left big edit box type in (don't separate the code into two lines, each line should have 16 characters)
03002B5D 32
Set the 'From' box to RAW, the 'To' box to AR V.3, and press CREATE (NOT proceed).
In the right hand side, AF20AB81 3A81A1F2 appears. This is your code!
Just to re-inforce, let's make another code - the Pokemon Pinball score. The address we want to change is $02000044 and we want to change it to $ffffffff .
So, let's look up the Code type guide and we find the 32-bit constant write code (a 32-bit value is also known as a 'Word') is
Type 02
2.0.0.x.x :
XXXXXXXX : (02024EA4 -> 04224EA4)
ZZZZZZZZ : Write the Word ZZZZZZZZ to address XXXXXXXX.
So, select 'Type 02' and type in
02000044 ffffffff
in the left hand side. Press create and we get D49661E2 BE4355E32 !
Note: if you don't get the results I'm getting - it's probably because your Special and Unused values have been set to other values. This doesn't matter - the codes will still work, and this is why we can create codes with special 'signatures'. If in the code type guide there is an 'x', this means that you can set this to any value at all. As a result, the code will be encrypted differently, but the codes still work. This is useful if you've made a particuarly cool code and want to make sure no-one steals it and claims they hacked it - just set the 'x' values to some odd numbers and if they legitimately hacked and encrypted the codes themselves, they probably won't get the codes you did (unless by some strange 'coincidence' they happened to choose the same values for the 'x's as you did :P)
So, that's how you make V3 codes, as we do more hacking I'll be giving more examples of how to create these codes.
Complex Mathematical Information (optional)
For those of you who are interested (I can't really imagine anyone would be), this (as far as I can ascertain, this is only coming from my observations) is how to create the xxxxxxxx part of RAW AR V3 codes without ARCrypt (all values in hex)
Raw Code = (((Address >> 4) & 00F00000) | (Address & 0003FFFF) | (Data Size << 19)
| (Type << 1B) | (Sub Type << 1E) | (Special << 18) | (Unused << 12))
>> is Right Shift
<< is Left Shift
& is Bitwise AND operand
| is Bitwise OR operand
Crazy, ain't it...
First off I'd just like the say that I haven't been working as much on these lessons as I would have liked to because I'm currently tied up with Rockman EXE 4 [j] - which is one of the toughest games I've done for a while - there'll be some ASM lessons to be had from that, hopefully.
So, let's get started on todays hacking. We'll be starting off timers. Timers can either be really easy, or a real pain to hack.
Timers come in many shapes and forms, and can be used for a variety of purposes - keeping in-game time, timing game events etc... Most of them will either count up or down (although there was one occasion where the timer went 1,3,2,4,5,7,6,8 or something similar). So, the easy ones will be found with greater than/less than searches.
The problem is though, how the game stores the data. It could have one value for minutes, one for seconds, one for milli-seconds, or it could just have one 32-bit value which is formatted into those. If the timer is not one that is displayed, it is probably just one value - though you can never be sure. If your search fails to turn up a result then try a different approach.
The example today is a simple in-game timer for Fire Emblem.
In the below search I'm making the following two assumptions (which luckily were correct - call it intuition ):
* The timer counts up (as it is an in-game timer for the entire game if it counted down then eventually the timer would stop when it reached 0 - and I doubt the developers would have allowed this to happen - if it were a 'time limit' timer - i.e when it reached a certain value it triggered something - it could possibly have been counting down)
* The timer is a single 32-bit value (a bit of a gamble - it could be made up of separate 8-bit values for hours, minutes, seconds - if this search hadn't had worked I would have tried those next)
So, let's get hacking. For those who aren't familiar with the game, the game timer can be accessed in battle by selecting 'status' from the menu.
Now, it is useful if you have many savestates from the game (which is why hacking with VBA is so easy), as you can just load these up if say you wanted to do a less than search (obviously you couldn't do this with only one save).
As always, the hacking procedure can vary, as long as your searches are in agreement with my two assumptions then you should turn up the correct address.
1. Set datatype to 32-bit unsigned, do unknown establishing search.
2. Wait a couple of seconds. Greater than.
3. Wait a little more and do another greater than.
4. Load up a previous savestate. Less than.
5. Wait a while. Greater than.
Continue through a similar type of pattern (by now you should be able to do your own searches by using a little thought), until you're narrowed down to around 15-20 values. Let's use a little 'zen' to guess which address is correct.
First off - the time between your last search and the current search shouldn't have been very big, so you can mentally eliminate any values whose difference between 'old value' and 'new value' are substantial (i.e. more than a thousand - unless we are very unlucky and this timer includes mili-seconds as well).
Now, you probably won't have many addresses left on your list (you should be careful, however, not to be over-zealous with your culling or else you may have to start again). Let's take a look at the remaining addresses. One in particular caught my eye - $03000010 . It seems to be the perfect place to have a timer - very early in the IRAM - it is very indicative of a timer. So, as a test - Add Cheat - value to 0. Awesome! The timer is now zero.
Just for interest - you can open up the memory editor, removing the cheat, and observe the address as the game progresses.
You will notice it counts up very quickly. If you wanted to you could find out how to convert between this value and the game-time but it is not necessary for this code.
To round off let's make the code "timer is always zero".
Remember, it's a 32-bit data size - so we need to 16-bit CBA codes. Before looking at what I got below, try making them yourself.
CBA
83000010 0000
83000012 0000
GSA
RAW - 23000010 00000000
Encypted - AB16F415 61F7E1A5
AR V3
This can be obtained by either converting the GSA code with ARCrypt (remembering to check 'Convert Ar V.1/2 to... ') or by using the 'create' button, which I will show now.
The 32-bit constant write code type for AR V3 is
Type 02
2.0.0.x.x :
XXXXXXXX : (02024EA4 -> 04224EA4)
ZZZZZZZZ : Write the Word ZZZZZZZZ to address XXXXXXXX.
So, select 'Type 02' and type in
03000010 00000000
into the left hand side and hit create.
If you set the Special and Unused both to 0 you would have got 85E4A651 CDD882EC (the same thing you would have got if you
converted from the GSA code). However, say you set special to 1 and unused to 2. The code would be
12C5782B 042C784E
Remember, you can change the special and unused to anything you like with this code and it will still work, because they are listed as 'x's in the code listing.
Hopefully this lesson has taught you the basics of timers. However, it is important to remember that not all timers are created equal - you may even have to resort to not-equal searches if it's one of those really weird ones. It is not uncommon to spend half an hour on a timer code - so don't be discouraged if your first searches don't yield results.
This lesson I'll be teaching you how you can hack some WTW codes.
As I said before, this method will allow you to hack some walk through walls codes. There was a time when this method worked on almost all games but now this may not always work (probably won't) and other advanced ways have to be used to make a WTW code.
This method works on the assumption that in the game, there is a 'Collision-Detection' value. Basically, this tells the game whether you are able to continue walking, or if there's an obstacle in the way (such as a wall) and you cannot proceed. By setting this value so that it always tells the game that you can keep on walking - you'll be able to walk anywhere on the map.
Note: This is a crucial point. With a WTWs code you are still confined to the boundaries of the map. Don't forget this.
I said that this seldom works anymore... and the embarassing part is I couldn't find a game in my collection that had a WTW code that worked like this (apart from some GBC ones and some other GBA ones on my other comp which I was too lazy to look up on).
However, I'll walk you through the hacking of a fictitious WTW code which uses this method.
1. 8-bit Unknown Establishing Search while walking.
2. While walking - Equal.
3. While walking into wall (you're walking, but not moving). Not equal.
4. Walking into another wall. Equal.
5. Walking - Not equal.
And you get the picture... Sometimes you may only find a code that works in one direction (i.e. only if you're walking right). If this happens, put a Joker on it, which is activated by that particular direction key. I'll give an example of this next lesson when we hack a WTW for Golden Sun TLA.
As I said in the previous lesson, there are several methods for hacking WTW codes - the one I'll be showing you next is for Golden Sun: The Lost Age.
The idea for this method is that there are two 16-bit values for each axis (x and y, or horizontal and vertical). They are sort of Collision Detect values, but they also have 2 extra states. For example, in Golden Sun TLA, if the value (for the y axis) is -2, then you are walking up, if it's 1, then you are walking downwards, if it's 0 then you are moving (on the y axis). You'll see what I mean when we get hacking.
Mini guide - Signed
I guess I need to explain all of that Signed/Unsigned stuff now. A Signed number, is a number that can be negative. That's what the sign is. For example, and Unsigned 8-bit number has a range of 0 - 255. A Signed 8-bit number has a range of -128 - 128. So, as you can see, they can only be half as big but can be negative as well. I can't recall the proper way to work it out - but I *think* it's something like this:
! (Absolute value of number - 1)
E.g. if you wanted -48 (hex) you would go !(48-1) = B8 (! is the bitwise NOT operand)
If in doubt, use the Windows calculator: Convert the Absolute value of the hex number (absolute value means it doesn't have a sign, i.e. it's positive) to decimal. Multiply it by -1. Convert back to hex. You can disregard the extra 'F's at the start so that it is the right datasize (or you can change the datasize in Hex mode - those radio buttons on the right.
Important thing to remember: FF (signed) is -1. Don't forget that.
So, that's all there is to signed values - next time you see the word you can impress your friends with what I've just told you (it isn't as effective as a pick-up line however)
Remember, these codes only work in one direction, so it's a good idea if you hack the code while walking in only one direction. The steps I followed were (always walking downwards)
1. While walking down - 16-bit Signed Unknown Establishing Search
2. While walking. Equal.
3. While walking into wall (by this I mean you pressing down but not moving anywhere). Not equal.
4. In another spot, walking into wall. Equal
5. Walking down. Not equal.
And you get the picture...
You'll narrow down your search to about 10-15 values. Let's take a look at them. It's likely that when you can't walk, the value is 0 (not always though, you have to be careful with the assumptions you make). So, let's check those addresses one of those addresses out ($02032318). Open up the memory viewer, go to that address and make sure you've got Automatic update on. Walk up and down, and observe the values changing. You'll see that when you are walking down $0203231A is 1, when you're walking up it's -2. So, let's try something. Go back to the cheat search menu - select $0203231A and click add cheat. Hmmmm, nothing happens. If you look at the memory viewer you'll see that the value flashes occasionally - this is because this value is constantly being written to by some kinda function. The solution: Disable that function. We could get into some tricky ASM or... press <A> to open the menu. All of a sudden you start moving upwards! If you disable that cheat and Add Cheat again, setting the value to 1 then you start moving downwards when the menu is open.
Now, the problem is, we want to be able to control where we walk - not just constantly moving upwards or downwards. By now, you should know how to do all of this (see the section on jokers if you can't remember), so herein ends the hacking for today - the codes you should get are below. If you have any problems with how I got the codes below, just post your queries here.
* CBA
74000130 03BF
8203231A FFFD
74000130 037F
8203231A 0002
74000130 03DF
82032312 FFFD
74000130 03EF
82032312 0002
* GSA
6FD25109 89E24953
F6444AE8 FA4197B9
BEE79199 32F493D0
86989708 13348FAB
9C1C1838 9DAC6B9F
E609C403 2FAFB446
410097DA 3BE99FBC
397377E0 7B4C1EFE
* AR V3
00A8C534 E4E6DA6A
318499D2 AE539E2E
F87DAD26 9E4C93EA
E17EEB50 61774F0A
B01A6B02 EA97B0C8
298C2FA0 5372EFDC
E18D243E B809572E
548FC56F ED0829D0
As you've seen today - WTW codes can get very tricky. And this method won't work for all games either! I'll probably post some more methods in some of the later lessons, in the meantime we'll be moving on to some other codes.
The topic of todays lesson is Moon Jumping! Like Walk Through Walls, Moon Jump codes work in a number of different ways.
Variation 1
The moon jump value is a y-axis position modifier relative to the ground. By this, I mean that when you are standing on a surface, not moving either up or down, this value is 0.
Variation 2
The moon jump value is a signed value which contains your y-axis speed (i.e., negative value while falling, positive when going up).
Variation 3
The moon jump value is a y-axis position modifier relative to the absolute ground (not common)
Those are the ones that I can remember offhand - there will be others, and of course variations on the variations above. You'll have to try each one in turn to see which your game uses.
For the example hack we'll be using good ol' Iron Man, level one.
1. On ground. 8-bit Unsigned Establishing Search.
2. Jumping. Greater than.
3. Falling. Less than.
4. On ground. Less than.
5. Jumping. Greater than.
6. Still jumping (same jump). Greater than.
7. Falling. Less than.
etc, etc...
Note: If this search doesn't work on some other game - try skipping out step 4. Also, you'll note I didn't do two step 7's in a row (like 5 & 6). This is because if I had the search would have turn up a blank. So as you can see, you'll have to experiment a bit to find the code.
I got to about 12 values, then stopped searching. Now, which address is it? Remember that 'jump as many times as you like code' we hacked in lesson nine? The address for that code is $02020258 . Well, it's zen time again. I'm *guessing* that our moon jump address will be pretty close to that. Let's take a look...
The closest address to that is $0202024C. Add cheat, and set the value to 1. Jump. Iron man will jump up to the top of the screen then fall slowly down. Remove that and set the value to 20. Iron man will jump, but he can't get that high. So, we need a value in between 1 and 20. Try 10. Hmmmmm. Iron man jumps up then starts rising slowly. I think we'll stick with 1.
If we made this as the code it would be pretty dumb because you have to float all the way to the top before falling. So - let's joker it! How you do this is up to you but I'll be setting the joker to the L trigger.
The codes Code: CBA 74000130 01FF 8202024C 0001 GSA 89AD87D7 23990C6E A37A41BC ACF8D111 AR V3 (with special set to 1, Unused to 2 for both codes) 7C724802 312649C9 9B1D7C6B BC36B9C8
With this code, hold down L and then tap A. You'll continue rising. If you press any other key while in the air then this will kind of stuff it up - though since you're still in the air you'll continue to rise. Release L and you'll fall back to the ground at normal speed.
This lesson will be devoted to several different types of codes. I'll just be going over the basic concept of how these codes work - no examples. At the end we'll be hacking another Moon Jump code.
Infinite Money/Lives/Ammo/Coins/Whatever
For these you can usually use a known value search - the data type should be at your discretion - obviously things like money will be around 32-bits - just think of what the maximum value *would* be and make sure it fits within the size constraint. If for some reason this doesn't work - try an unknown value search. If this still doesn't work then it's a safe bet that the game is foobarring the values some how - though this is uncommon.
Have/Unlock xxxx
This can be hard - the idea is you do an unknown search - comparing when you have/have unlocked whatever it is, and when you haven't. These values are often stored together with similar things. Note: A game may use a system, where 1 bit represents one particular object that can be unlocked (or a status). As a result, 8 of these can be stored in one byte. See below for more info.
Let me elaborate. As you should know by now, a byte consists of 8 bits. A bit can be 1 or 0. Programmers can utilise this - if a particular bit is 1, then you have unlocked an object. If it's 0, then you haven't. As a result, one byte can control 8 different 'objects' (they aren't necessarily objects, for example in FFTA all of the character status ailments (e.g. sleep, confused, etc..) are stored in 5 bytes, that's 34 statuses in 8 bytes! note: 5 bytes means a possible 8 * 5 statuses - so 6 bits weren't used. The trick to searching for these is just to use unknown 8-bit searches - remembering though that if any of those 8 bits changes then that value will change.
When you find one of these values, you should test each bit separately - i.e. make the codes so that only one bit is 'set' - that way you can see which bit does what.
Things to remember: $01 sets the first (least significant) bit only
$02 sets the second bit only
$04 sets the third bit only
$08 sets the fourth bit only
$10 sets the fifth bit only
and so on (this is just a matter of some bin -> hex conversions. Also $ff sets all bits.
---
(Max) Stats/Quick level up/One hit kill
These usually can be accomplished with known searches. Quick level up codes are simply modding experience (it's not a good idea to actually make a code which changes the level - as your stats may not upgrade as expected). One hit kills are just HP mods for the enemy - set them either to 0 or 1 (sometimes if you set them to 0 they don't work). Use a known or unknown search depending on whether you know how much HP your enemy has.
Names
There are a number of methods to hack codes that modify your character's name. One is the trusty old unknown search (because you don't know what values the letter will have). The other - which I prefer - is to pull out the memory viewer and start looking around the character datablock (I haven't explained what a datablock is - you should be able to take a good guess but I'll write more about this later). You can often find them quite easily - though sometimes you'll have to resort back to searches. Occasionally, the name value for a character could actually be a string pointer (FFTA uses this system).
Slots
I could list plenty of things that slots are used for. But I'm not going to. Just don't forget them.
Moon Jump
Okay, now for that Moon Jump code. The game is Shrek: Reekin Havoc. If you for some reason already have this game in your collection then there is something wrong with you - but I thought we'd use this just to show how developers sometimes choose to do things differently.
Go through the normal procedures of an unknown 16-bit Unsigned search. Only do greater than's while going up and less than's while you're on the ground. Because of the weird way this game does this I only stumbled upon it co-incidentally. You may not find this, but the address is at $0200943C. Open up the mem viewer and go to that address. What happens is when you jump up $0200943E is set to $FFFF, the high $0200943C byte is set to FF and the low byte counts up. When you are falling the FF bytes are set to 00 and the other byte counts up. (All this was observed from the memory viewer). If you wanted to make a moon jump for this code you would just attach a joker to a 16-bit modifier for $0200943C but as no-one in their right mind would play this game I'm not going to bother with the codes.
It's unlikely that you'll come across any other game that does this - I've just included it to show that game developers can do what they want - you may have to resort to some unusual methods of code hacking if the ones I've given you don't work.
Today we'll be looking into Position modifiers. As the name states, they modify the position of your character on a map. You may be thinking, what is the point of a code like this? Well, if you can find a point you ought to be congratulated - the only real use I've ever had for one is to use as a Breakpoint in ASM hacking.
Imagine a map as a grid. Each 'tile' has a set of co-ordinates - x and y. Your position is recorded as 2 values - your x and y position on the map. All a position mod does is modify these.
There are two searching methods - the Greater/Less than and the Not-equal.
The Greater/Less than method assumes that the further right you go, the larger the x value gets (this is usual practice but may not always be the case). So, if you move right, your x value increases. If you move left, it decreases. The same goes for the y value - if you move downwards it increases, upwards it decreases. You shouldn't have much of a problem with this - and if that doesn't work, just switch it around (up=increase, down=decrease, left=increase, right=decrease). Don't forget to chuck in a couple of equal-to's as well to narrow down your search (i.e. if you're hacking an x axis mod, if you move up without moving sideways it won't have changed).
If you need any practice - the addresses for Golden Sun TLA are $020322F6 and $020322F6. If you mod the values in the memory editor you will 'teleport' to that place on the map - if you make it a cheat then you'll be stuck there (if it's only an x axis modifier you'll still be able to move up and down, and vice versa for y-axis). You can often find these codes in close proximity to WTW codes.
The Not-Equal method is very rarely used as the two variations on the Greater/Less than method should cover all eventualities - unless the game is doing something really weird with the values - like that timer I told you about. If you do have to use this method I'll be very surprised. Basically, if you've moved - do a not-equal. If you haven't, then don't
Note: In 3D games it can be a bit hard to tell which axis is which if the camera view rotates - in that case the not-equal method could come in handy - it would be dangerous to use equal-to searches at all.
This lesson will deal with two forms of 'Easter Eggs' - Debug Rooms and Debug menus.
Debug Rooms
The general concept behind Debug Rooms is that it is a map, like any other - the secret is getting to it. The type of code used for Debug Rooms is the same as 'teleport' codes - codes that, on a certain trigger (e.g. walking into a door or pressing a combination of buttons), will teleport your character to another map.
The basic idea, is that when you are in a room, there is a value that tells the game what room you are in (the ID no. of the room). This value can be used for a variety of functions - mainly to know where to find data for that map in the ROM. Teleport codes usually modify this value.
You should have a pretty good idea of the searching method of this - walk in a room, equal-to, walk into another room, not-equal to, etc... There are a couple of tricks you can try to speed up searching (which you may have to use if you have too many results) - use Greater/Less than searches. Generally, developers make maps (and assign IDs to them) in a chronological order, though this is not always the case.
Once you find this value you'll need to do a bit of experimentation - try freezing the value to a known Map ID. If, whenever you go through a door (or something similar), you end up in the same room, then you've got it easy - all you need to do is find the ID's of all maps, and if you're lucky a Debug Room will be in there somewhere.
If this doesn't happen, but you're sure you've got the right value, change the value to something else then save the game (use the in-game save function NOT VBA savestates). Reset the game and load up your save - hopefully you'll be in a different room.
You may have problems catching this value - sometimes it only appears when you are 'teleporting' from room to room, or, it may only be set for a fraction of a second. All of these problems can be overcome (theoretically) with ASM hacking.
Debug Menus
Debug Menus are usually easier than debug rooms. Here's the principal: When you move your cursor (or whatever it may be) over menu items, they get highlighted. There is a value somewhere that tells the game which option your selector is over. To search for this you can use a simple combination of equal and not-equal searches while the selector is over different options. It's best to try this on a single menu first, though the value may be same on other values as well (for example, in FFTA the address $0202ddd9 is used for all 'first level' menus. The first topmost option is 0, the second is 1, and so, on [programmers will know this as a zero-based index]). By modifying this value you can trick the game into thinking you've got your cursor over an option that it's not showing (for obvious reasons in the case of debug menus). The trickiest part in finding debug menus is knowing which menu you should be searching in.
Note: The method I use to hack Debug Menus involves disassembly. As I have explained previously, there's no dead set method to finding these, however you should be able to pick up some tips from the ASM lessons that follow.
Well, in this lesson we will be hacking a couple of codes based on Intelligent System's Fire Emblem (makers of the Advance Wars series).
Infinite HP
First up, an infinite HP code for Lyn. An interesting thing in this game is that, the same addresses are used for different characters, depending on the episode you're playing - so watch out for that.
Okay, let's set up a known search - Unsigned, as I doubt that they'd let HP enter negative values, and 8-bit (range of values for 8-bit searches is 0-255, more than adequate). I'm basing my search on the first 'mission'.
Hit start, enter her current HP into the edit box, set search type to EQUAL (because the address holding her HP will be EQUAL to the value in the box), and hit search.
The results come up, too much to deal with at the moment.
Right, back into the game, I'll advance her a bit, and do another search. She's still on 16 HP so I leave that in the edit box.
Back to the game - Lyn's taken some damage and she's down to 6 HP. This step is the potential stuff-up for code searchers - and I fell for it as well. If you do your search whilst still in the battle screen you won't find the address, because it only gets updated once you get back to the map. In case you're wondering - there's no way you would have known this - after you've been hacking for a while you'll cotton on to some of these tricks. So, let's do another search, once you've left the battle screen, replacing 16 with 6 and hitting search.
Okay, I've narrowed it down to one address $0202bd63. Let's make the code!
We want to set the value to something... duh - so we want a constant write code. It's also an 8-bit value, so we'll use an 8-bit code (there's also another reason why we have to use an 8-bit code - the address isn't aligned with 2 [you would say that it's an odd number], so we can't use a 16-bit code, and besides, the previous address is used for something completely different).
Let's do the CBA code first. The 8-bit prefix is 3, so our code is:
3202BD63 00xx
where xx is the hex value you want to set her HP to - experiment with the values to see which works best.
Now for GS V.1/2. The prefix for 8-bit codes is 0, so our unencrypted GS code is
0202BD63 000000xx
where xx is you-know-what.
Now, we need to encrypt it. I'm going to set the xx to 1, since that'll be pretty funny. Type in the code into the left box, set from to RAW, to to (lol) AR V.1/V.2, and hit proceed. You will get CB0CE9F2 2419617A
Finally, the AR V3 code. Let's do this the proper way. Looking in the V3 code types manual - 8-bit constant write is type 00, or 0.0.0.x.x (the format for this is Data-Size.Type.Subtype.Special.Unknown)
So, boot up ARCrypt. In the left box type in
0202BD6300000001
(if you don't know why, read the previous tutorials and the V3 manual)
Set the type to 00, Data size to 0, Type to 0, Subtype to 0, Special to anything you like (coz it's an x) - I set it to 1, and set unknown to anything you like (me - 2).
Click create!
and you get D2E64C51 83B3CA04
So, those are the codes.
Max HP
I've chosen Max HP as the other code we'll be doing in this tutorial because it'll give me a chance to teach you a little trick. Stats related to the same character are often stored close to each other, especailly in RPGs. Your Max HP value and your HP value are often very close to each other, if not directly next to. So, let's open the memory editor. Type in the HP address, click Go, then scroll up a couple of lines so you can see previous values as well.
Now, convert your HP into hex, if you can't do this in your head (and I don't expect you to be able to), pull out the windows calculator. I'm still on the first mission, so I'm looking for 10 (16 in hex).
Here's the cool part - the value directly before the HP address is 10! Mod it, change it to anything else...
and Lyn's Max HP changes! Now to make the codes - this is also an 8-bit code so I'm not going to go through the steps but the codes are (value set to 50)
*CBA*
3202BD52 0032
*GSA*
C652A048 22F3B144
*AR V3*
3685D523 624FC4E6
'Datablocks' are yet another concept that, if you want to be a good hacker, you will have to get to know. They are the basis to all of those 'Character Generator' programs you see.
First, the obvious question: what in ******* **** is a datablock? Well, if you're familiar with classes in programming, then you should get this easily. Basically, it is just a group of variables, stored together, that define the attributes of a particular object, in this case, a character in a game. These are especially useful in RPGs when there are many characters that have to be kept track of.
For example, a simple game may have a datablock that contains:
Current HP
HP
Current MP
MP
Item 1
Item 2
Item 3
Level
Experience
You could then use this same structure for the data of each character. If there were 2 characters, with information stored
directly after each other (which is often the case), that particular area of the memory would be a bit like this (I've allocated 2 bytes for each 'field', though they can be of any size):
02000010: Player 1 Current HP
02000012: Player 1 Max HP
02000014: Player 1 Current MP
02000016: Player 1 Max MP
02000018: Player 1 Item 1
0200001A: Player 1 Item 2
0200001C: Player 1 Item 3
0200001E: Player 1 Level
02000020: Player 1 Experience
02000022: Player 2 Current HP
02000024: Player 2 Max HP
02000026: Player 2 Current MP
02000028: Player 2 Max MP
0200002A: Player 2 Item 1
0200002C: Player 2 Item 2
0200002E: Player 2 Item 3
02000030: Player 2 Level
02000032: Player 2 Experience
Of course, most games will have much larger datablocks - each character in FFTA has 264 bytes worth of information.
Okay, so you're hacking a game, and you suspect the game uses datablocks. How do you find it? Simple - just try hacking a code for anything related to a character. Easy ones are HP, stats and experience. The next thing you'll want to do is find out how big the datablock is - this includes where the relevant information starts and where it ends. The easiest way to do this is, if there are multiple characters in the game, hack the same code for the next character, i.e. if you hack an exp mod for the 1st character, do the same for the 2nd. Now, take the address (all of this is in hex) of the 1st character's exp (or whatever it was you hacked), and subtract that from the address of the 2nd character's. The result should be the length of the datablock (how many bytes it consists of).
Now you have to find out where the datablock starts. This can be a bit trickier - I usually open the memory editor, go to one of the 1st characters addresses and scroll up until I 'see' where it starts. You can usually tell - preceedint it will be a large block of empty bytes. Sometimes this doesn't work - so you'll have to skip this and go on to the next step - during which you'll probably find out.
Finally, you need to know what each address does! It's not much use to you if you've got no idea what the values control. To do this, you can hack codes the traditional way and match them up with addresses. This will work with obvious things like stats, etc... The second way is to open up the memory editor and manually edit the values. This is a useful technique to use if you've been trying to hack a code like an ability slot and you haven't had much luck - just go through modding the values in the memory editor. Using this you should also be able to figure out where the data for one character stops and another begins.
You may come across bytes which you can't figure out the purpose for. This is quite common - don't worry if this happens - just leave them as they are - if you're making a new character from scratch in an empty slot then set them to the same values as other characters.
Well, that's it as far as the theory of datablocks go for today, I'll leave you now with the datablock for Final Fantasy
Tactics Advance Characters for you to have a look at. Next lesson, which I'll probably write now anyway, will be dealing with cool things you can do with datablocks.
This is in 16-bit format Little-Endian format (remember what that means?) - the way it appears in 16-bit mode in the memory viewer. It was compiled by Mastersord with input from myself and some of the other GSCCC hackers. We chose the 3rd character slot to work on as it is the first fully customizable slot (the first two slots are taken up by you and Montblanc, who cannot leave the clan). You'll notice that values for some bytes are included, such as the behaviour value. Also note the gap between 20002ce and 2000360 - this area contains the AP values for all skills, and as the values determine different skills depending on your race this has been left out, though I have compiled a list for this in excel format.
Character Datablock for FFTA Characters - Addresses are for the 3rd character slot 02000290 Name 02000292 Level/name 02000294 appearence/?? 02000296 job/race 02000298 also gets affected by skills 0200029a Experience 0200029c 0200029e 020002a0 020002a2 020002a4 020002a6 020002a8 current HP 020002aa Max HP 020002ac current MP 020002ae Max MP 020002b0 Stats Attack 020002b2 Stats defence 020002b4 Stats power 020002b6 Stats Resistance 020002b8 Behavior (8001 makes it an enemy, c001 for leednar and Rememdy as enemies, needs more study) 020002ba Equipment slot 1 020002bc Equipment slot 2 020002be Equipment slot 3 020002c0 Equipment slot 4 020002c2 Equipment slot 5 020002c4 ??/Primary skill 020002c6 secondary skill/?? 020002c8 020002ca s-skill/r-skill 020002cc combo skill 020002ce Job and abilities learned/mastered section goes in this gap 02000360 02000362 Stats Speed 02000364 02000366 JP 02000368 0200036a 0200036c 0200036e 02000370 02000372 02000374 02000376 02000378 status (1000 = invisible to enemies) 0200037a status 0200037c 0200037e 02000380 02000382 02000384 02000386 unit collision (0b03 makes unit pass-through) 02000388 0200038a 0200038c 0200038e 02000390 02000392 red card/yellow card 02000394 02000396
In the last lesson I taught you about datablocks - in this lesson I'll be demonstrating some nifty things that can be done with them. I'll be stepping you through the hacking of the Golden Sun TLA block (one of my favourite RPGs) and show you some cool tricks you can do once you know where it is.
I'll be basing my searches on Felix, since you get him very early on. First I do a search to find his HP (you can do these searches if you want for practice), and come up with the address $02000A84. So, I jump into the memory editor, go to that address and get a pleasant surprise. In the ASCII character representation of the data (the right hand part of the memory viewer - all of those '.' are undisplayable characters that aren't on a standard keyboard), I see the word Felix! (I left Felix's name as Felix ). The letter 'F' is at $02000A50. Before that, is the value $03 and before that a big block of $00's. I don't know for sure where Felix's information starts, so i'm going to choose an arbitary point. It's handy if it's a 16-bit aligned address (or even 32 if you get the choice), and since it doesn't really matter which address I choose I'll pick $02000A4C, which is '4' aligned (the number is divisible by 4), and therefore a good place to start.
Now I need to find out how big the datablock is. I could hack the code for the next characters HP to work this out, though I'm not sure who the next character is (actually I am, apart from the fact that I already have hacked all of the codes, I've also worked out the party modifier digits - Felix is 4, and Jenna is 5). So, I'm just going to scroll down the memory viewer looking for another recognisable name. Aha! At $02000B9C is... Jenna! Now - where did I say the datablock
started at. Well, Felix's name starts at $02000A50, and I said that the datablock will start at $02000A4A, so simple arithmetic tells me that to get the start of Jenna's datablock I just minus 4 from her first letter - getting $02000B98.
Okay, now how big is the datablock. $02000B98 - $02000A4C = $14C . That's quite a lot of data, so I'm not going to go through what every value does.
Right, now I'm going to show you something which I think is pretty cool (and not too many hackers know about). VBA has a function that lets you to 'dump' the contents of memory into a file, then load it back up again [note: there is a bug in version 1.7 that gives you an error when you try to load memory - hopefully this will be fixed soon, in the meantime use an older version of VBA - I'm using 1.5.1)
Go to the address $02000a4c in the memory editor. Now click on the 'Save' button in the mem editor. Make sure 02000A4C is in the 'Address' block, and for size, type in 14C (which is the length of the datablock, and the amount of data we want to dump). Save it as a file somewhere. Now, go to the start of Jenna's block. Click load, find the file with Felix's data, click
open, and under Address, make sure 02000b98 (the start of Jenna's block) is there. Click O.K. Now for the cool part. Open the ingame menu. Notice, that Felix and Felix (!! name has changed) have the same HP and MP. Open the Psynergy menu. They have the same Psynergy. You'll find they also have the same Djinni, Items, and Stats. The only thing that isn't the same is the face pic - which obviously isn't stored there.
And it gets even better! A lot of the time you will fine that enemies use the same data structure as playable characters (like in Golden Sun and FFTA). You can try this if you want. Hack an HP mod for one of the enemies (the first value is at 02030900 0001). Scroll up, find the name of the enemy, subtract 4 (bytes) from the first letter. Dump $14C bytes and load it up into one of your characters - they'll have what the enemy had! Also note that the character's class is 'NPC'. Your in battle sprites will also be changed although it is a bit buggy - probably because there are no enemy sprites as viewed from behind.
This also works the other way - you can fight yourself in battle! Your enemy will have the same name, same abilities, same items, and in GS, the same Djinns (though I don't think he can use them). Also the character always seems to defend (I haven't done many tests though), so possibly there's a behaviour mod value somewhere in there - if you want to you can try and find it!
Finally, I've written a program called DMP2CODE. Basically what is does is takes VBA ram dump files and transforms them into CBA or GSA Raw codes. It works in 16-bit format for CBA and 32 for GSA. It was written in QBASIC (coz I was lazy and it was easy to code ), but if I get round to it I'll port in to Windows. You get download it at www.geocities.com/labmasternz/dmp2code.zip (note: it's very buggy and has a poor interface, but it works for me anyway. I didn't really intend to release it to the public but I though it might come in handy). It asks you for a Base Address to start from and generates codes that basically act if you were loading the dmp file through VBA, starting at that address. This is useful for creating codes to generate custom characters from your own save games without going through memory manually.
Note: DMP2Code is now a Windows GUI program, which can be downloaded at http://metawire.org/~labmaster/files/
This is a quick and dirty guide for creating mastercodes for the AR V3. The only reason why this guide exists is that AR Crypt has a useful tool for finding master codes. I won't be going into all of the details off finding master codes - this will come in a later ASM lesson. I'm not even going to tell you why you need one
However, I will point out what does what in an AR V3 master code. There are two lines in a master code. One is known as the 'hook', and the other, the 'id'. To find an AR V3 master code you must have the ROM.
Okay, open up ARCrypt. On the menu at the top, select 'special' then select 'Find ID code'. Open up the ROM and ARCrypt will spit out the ID code on the right. There is only ever one possible ID code. An example is:
ID Code for ROCK EXE4 BM B4BJ.
F3A0B626 E1A86DF7
Now, to find the 'hook'. Go to the special menu and select 'Find Master Code'. Open up the ROM. ARCrypt will go through the ROM and search for possible places to hook. A typical output (on the right side) may look like this:
Master Code Set #1 : -------------------- Slow Down on AR Button Code : DBBA3A89 4CB74B94 Master Code #1.1 for ROCK EXE4 BM B4BJ. 1F03E8F9 886A21C0 Master Code #1.2 for ROCK EXE4 BM B4BJ. 602B9E7D DA27FF2E Master Code #1.3 for ROCK EXE4 BM B4BJ. 2978100C 1357ED29 Master Code #1.4 for ROCK EXE4 BM B4BJ. BF0B62BE AF93B3A5 Master Code #1.5 for ROCK EXE4 BM B4BJ. D1D24058 6163D918 Master Code #1.6 for ROCK EXE4 BM B4BJ. 7DA55BE8 AEF96D69 Master Code #1.7 for ROCK EXE4 BM B4BJ. A518672B 757F866A Master Code #1.8 for ROCK EXE4 BM B4BJ. 5A88B041 B776B625 Master Code #1.9 for ROCK EXE4 BM B4BJ. 1B838344 9097EF6E Master Code #1.10 for ROCK EXE4 BM B4BJ. D1F5F00D 88B5A0CF Master Code #1.11 for ROCK EXE4 BM B4BJ. 9426DB90 CECCA830
There may be more than 1 Master Code set. To create a working Master code, you have to use ONE of the master codes and the ID code. For example, a working master code for this example may be
1F03E8F9 886A21C0
F3A0B626 E1A86DF7
The reason why there are so many possible master codes is that they don't always work. If one of the hooks doesn't work - try another one. Doing this you should get a working master code.
So, you may not know what a master code is, or why you need one - but now at least you know how to make one for the AR V3.
After a couple more introductory ASM lessons I'll write up a tutorial on finding Master codes for all devices.
btw - if you're wondering, the example game I was using was Rockman EXE4 - Blue Moon.