Basic Game Security
As has been said before, many games have some sort of security be it encryption, a checksum, some mathematical manipulation, or a combination of these. The easiest (and the one I will be discussing first) is mathematical manipulation.
Mathematical Manipulation:
Even the name sounds imposing huh?
Well it isn't as scary as it sounds. All it means is that the value we're looking for has had some math done to it. Say we're looking for our gold which is 100. We look through our saves but don't find any values of 100 but we know that it isn't encrypted because we can read it. Well we go through the file compare method and find a value that changed when we got another gold. The values that were changed are 800 and 808. We know that our gold values are 100 and 101 and this is the only thing that changed so they
must correspond. This allows us to realize "hey, all they did was multiply our value by 8". That's mathematical manipulation and is quite easy to implement. For the more code-savy of you I will give an example code that could be found in-game.
Autoit:
Code:
$iVal = 800
$iGold = $iVal/8
GUICtrlSetData($txtGoldVal,$iGold)
C++:
Code:
int iVal = 800;
int iGold = iVal/8;
printf(iGold)
All this code does is take the value (800) and divide it by 8 to show you your real gold value. Since the game would add in increments of 8 for every gold piece we wouldn't find the display value (100) but only the
real value of 800. Now onto checksums ^_^.
Checksums:
Checksums are bits of data that the game reads before the save is loaded to verify that it hasn't been tampered with. Some common checksums are the SHA1 or MD5 value of the data (not including the checksum itself of course), a proprietary key (such as the PSV header of a PSP's PS1 savegame), or sometimes even something as simple as your profileID. Most checksums are found at or close to the beginning of the file. Since it's the first thing read to verify security it makes sense that it would be there, but sometimes it's at the end of the file in an attempt to throw us off. Going back to our original example of "sysSettings1sysSettings2sysSettings3.........weapon_023464........63" we know the hex is
Code:
73 79 73 53 65 74 74 69 6E 67 73 31 73 79 73 53 65 74 74 69 6E 67 73 32 73 79 73 53 65 74 74 69 6E 67 73 33 2E 2E 2E 2E 2E 2E 2E 2E 2E 77 65 61 70 6F 6E 5F 30 32 33 34 36 34 2E 2E 2E 2E 2E 2E 2E 2E 36 33
but in our savegame we see
Code:
6d ed b1 c4 ff 91 39 9c 75 b4 bc fe fe 0e 69 63 73 79 73 53 65 74 74 69 6E 67 73 31 73 79 73 53 65 74 74 69 6E 67 73 32 73 79 73 53 65 74 74 69 6E 67 73 33 2E 2E 2E 2E 2E 2E 2E 2E 2E 77 65 61 70 6F 6E 5F 30 32 33 34 36 34 2E 2E 2E 2E 2E 2E 2E 2E 36 33
We can clearly see that "6d ed b1 c4 ff 91 39 9c 75 b4 bc fe fe 0e 69 63" is before the actual data we want but we don't know that that is because on the "readable" side of our editor it looks like this "m.....9.u.....ic". What do we do in this situation? Well first we swear, then we see if it matches up with any of the "common" checksums. We try the SHA1 of our data which is "fbce6651fad6a8461c9bc0751cf153dd044addb". Nope, not that one. We try the MD5 which is "6dedb1c4ff91399c75b4bcfefe0e6963", hmm...let's spread that out. "6d ed b1 c4 ff 91 39 9c 75 b4 bc fe fe 0e 69 63", bingo exact match. Now we know that it uses an MD5 hash of the data as its checksum. All we need to do if we change something is recalculate the MD5 value. There are several ways to do this an I won't go into specifics (google is your friend). Following our old example let's say we wanted to unlock menu 4. We would set our data to "sysSettings1sysSettings2sysSettings3sysSettings_04.........weapon_023464........63" and get the MD5 which is "388ff38b741b00fbbd1fc84f69362002". Now all we do is insert our new checksum in place of the old one to make our hex data look like this
Code:
38 8f f3 8b 74 1b 00 fb bd 1f c8 4f 69 36 20 02 73 79 73 53 65 74 74 69 6E 67 73 31 73 79 73 53 65 74 74 69 6E 67 73 32 73 79 73 53 65 74 74 69 6E 67 73 33 73 79 73 53 65 74 74 69 6E 67 73 5F 30 34 2E 2E 2E 2E 2E 2E 2E 2E 2E 77 65 61 70 6F 6E 5F 30 32 33 34 36 34 2E 2E 2E 2E 2E 2E 2E 2E 36 33
Notice how our checksum is at the very beginning? It's the same place as the original checksum we found. We
never want to put it in another location. We always want to keep the data as close to the original as possible so we don't break our game or get a corrupted save.
Proprietary Checksums:
These are a *****. I'll be honest I don't know how to crack stuff like this so the best bet is to wait until someone figures it out or get help if you don't already know how. I'll give an example anyway. Using the same example we see our hex data as
Code:
fd fc 0c f4 4d b7 cf 1b 87 e6 78 46 58 ea 3b 04 73 79 73 53 65 74 74 69 6E 67 73 31 73 79 73 53 65 74 74 69 6E 67 73 32 73 79 73 53 65 74 74 69 6E 67 73 33 2E 2E 2E 2E 2E 2E 2E 2E 2E 77 65 61 70 6F 6E 5F 30 32 33 34 36 34 2E 2E 2E 2E 2E 2E 2E 2E 36 33
which means our checksum is "fd fc 0c f4 4d b7 cf 1b 87 e6 78 46 58 ea 3b 04". We run our data through the more common checksums and even some others we find out about through searching but we don't find any publicly available method of making the same checksum. First thing to try is leave the checksum alone and still change your data, then load it up and see if it runs. If it does then it's probably just an identifier, if it doesn't then it really is a checksum and we need help.
Encryption:
I've already talked about encryption
. It's basically a type of mathematical manipulation but on a larger scale than just our data (for the techies more than just on variables/userdata). Normally they have an algorithm, a mathematical formula, that they run the
entire save file through to make it totally confusing and unreadable. Well, if the game can read it so can we right? It's just a matter of figuring out how it works. Using our standard example I'll show you some
very basic encryption. We already know what the hex of the file
should be, but under encryption it looks like this
Code:
88 94 88 68 80 89 89 84 21 82 88 46 88 94 88 68 80 89 89 84 21 82 88 47 88 94 88 68 80 89 89 84 21 82 88 48 88 94 88 68 80 89 89 84 21 82 88 20 45 49 17 17 17 17 17 17 17 17 17 92 80 76 85 21 21 20 45 47 48 49 51 49 17 17 17 17 17 17 17 17 51 48
which translates on the "readable" side to
Code:
X^XDPYYTRX.X^XDPYYTRX/X^XDPYYTRX0X^XDPYYTRX-1\PLU-/013130
.
Gibberish right? Well we don't know the encryption algorithm so we're stuck with using the filecompare method and hoping they don't also have a checksum.
In all of these examples when data would be loaded onto your 360 you would need to rehash/resign your save somehow (Modio, Horizon, etc) to make sure the 360 recognizes it as proper data, even if the game won't. These are the basic concepts behind checksums. Simple(ish) right?
P.S. For those of you interested here's the basic encryption program I whipped up for this example. It just reads the binary values one-by-one and adds F to them but hey it works. It's written in AutoIt.
Code:
#include <file.au3>
Dim $i, $string, $hex
$file = FileOpen("test.txt",16)
$num = FileRead($file)
$num = @extended
While $i < $num
FileSetPos($file,$i,0)
$data = FileRead($file,1)
$data = StringReplace($data,"0x","")
$new_data = $data + 0xf
$hex &= $new_data & " "
$string = $string & ChrW($new_data)
$i += 1
WEnd
MsgBox(0,"",$hex)
MsgBox(0,"",$string)