This tutorial is made by ZuckeR. I have permission to post it here. All credits go to ZuckeR.

The very basics

Let's talk about what the computer or in this case the Flash Player sees when looking at a file. When creating a game in Flash the language you use is ActionScript 1/2/3 (AS). For an experienced user this is fairly easy to read and understand. But the Flash Player does not work that way as it thinks in Opcodes (Operation Codes). So Flash CS3/4 or whatever the creator of a game uses translates the AS code to these Opcodes.

Now how does these opcodes look like could one ask so lets look. There are not that much Opcodes, just like 160 or so. Yeah still quite a lot but for hacking a game there are like 5-20 for very basic hacking and like 10-40 for more advanced stuff. But you don't even need to learn all those as this would be overkill. For figuring out the code you need additional programs anyway, if you are not an Übergeek. By doing more hacks you will remember more and more and learn how to use them without looking somewhere.

The Opcodes them self are always 8 bit represented in hex code as 0x02, 0xd4, 0xff or something like that. Some are followed by other values like a number or special values also represented as hex values. When i write 0x in front of them it is just so that you know i mean Hex Code and not the number or a string.

Code:
BIT   HEX  DEC # BIT   HEX  DEC  # 8 bit combined are 1 byte
0000  0    0   # 1000  8    8    #
0001  1    1   # 1001  9    9    # Examples:
0010  2    2   # 1010  a    10   # 1011 0101 = b5
0011  3    3   # 1011  b    11   # 0000 0010 = 02

0100  4    4   # 1100  c    12   # 1010 0001 = a1
0101  5    5   # 1101  d    13   #
0110  6    6   # 1110  e    14   #
0111  7    7   # 1111  f    15   #
Programs like flasm (only AS2) and Sothink SWF Decompiler can translate these Opcodes into a readable form (pushbyte, pushtrue, setproperty etc). But while flasm is capable of recompiling the SWF with the changed values it gets harder with AS3 which flasm cannot handle. Getting the Opcodes is still not a big problem but now you have to change it yourself inside the SWF file. That is what i want to teach you how.

Programs

Before it can start you need to have some programs. It may look much but you do not need all of them from the beginning. Also all the programs used in this tutorial are free to use. Just Sothink SWF Decompiler costs money or maybe not Before you start you should have a decompiler, a decompresser and an Hex Editor ready to go. The bold ones are the most important.

Decompiler that can show you the opcodes:

Other important tools
  • Swifty Compress & Decompress
    http://www.mediafire.com/?zl7za4py44hh169
    To save bandwidth every swf file is compressed. To work on the file it needs to get decompressed which you can do with these two small tools.
  • HxD
    http://mh-nexus.de/en/downloads.php?product=HxD
    Any Hex Editor will do it but this one i will use here as it is free and comes in like over 9000 languages or so.
  • Notepad++
    http://notepad-plus.sourceforge.net/
    Many might know this from the flasm tutorials and worked with it. There is an Hex Editor plug-in but it is buggy so i try to not use it anymore. I still use it when it comes to embedded XML streams but more about this later.


A game

Besides the programs it is really important to have a game that you want to hack. It can be AS2 or AS3 but as AS2 is easy to hack with flasm we gonna settle for AS3 games here. Oh and just to remind you Mochicrypt? Forget it! Amayeta encrypted? Forget it! Editing in low level does not magically makes it possible to hack encrypted games. Those games need a proper decrypter before they can be hacked with whatever method.

For the first game we need an easy one so i looked through my previous hacks and found one on which i changed only one variable. If you want to find a game that is relatively easy to hack just go for the ones that aren't too complex. Also if you see someone hacking such an easy game why don't you also try to do it. In the beginning it should be the hacking itself and not the submitting of it that counts.

Max Dirt Bike 2



Step 1
Download the game! Yeah it really is that easy At least if it is not Kongregate... OK and do not forget to make a backup!!

Step 2
Lets look if we can hack this game. This should always be the first thing to check. If Sothink is installed correctly it should appear when right-clicking on an swf file. And thats what we are going to do now:


The result should look somewhat like this:

We have the explorer and the files of the current selected directory on the left. In the middle is the game and later there the AS will be displayed. On the right is the resources panel which lets you look at all the stuff inside the game. On the top you have some menus, the most important menu is open in the picture. The ActionScript menu where you can search inside the script and switch between Source Code and Raw Data which is what we will need.

Clicking on the plus sign infront of the swf file on the right side will show all resources that could be found by the decompiler. Interesting for us is only one folder which is called "Action" and holds are the ActionScript. Opening it gives list of AS classes/files but how do we find the right one. We can go on all of them and look, here many are almost empty and do not help us at all. But in the subfolder "bike_fla" there is a script called "MainTimeline" which is a pretty promising name huh?!

By clicking on it the game in the middle disappears and the code appears. This is the ActionScript that the decompiler was able to retrieve from the file by interpreting the opcodes. It is amazingly accurate the most time thanks to the guys at Sothink. Now it would be really good if you would know some AS3, but also any other Object Oriented Programming language. But even if you don't know it you can still find the needed code.

What you see here is a package ("bike_fla") which is just the name and includes a class ("MainTimeline"). The first thing you gonna notice in the class are definitions for variables it uses, they are called properties.

Code:
public var time1:Object;
public var run1:Object;
public var restart:Object;

public var loader:MovieClip;
public var extra:Object;
public var titleDisp:TextField;
We not going to change these as it is a little harder to find them. More interesting are the many function inside this class which are called methods. Normally they have names that give you an idea of what they do. Names like "InitGame" are really promising but in this game here it is a different function we need. It is called "frame2" and functions with such a name are also a good start. A function with "frame" and a number is usually called when the frame with the same number is accessed.

You can use the search function to find the right function or look through the code manually and search for this:

Code:
function frame2()
{
  if (started == undefined)
    {
  started = true;
  unlockedLevel = 1;
If you are a careful reader you have figured out by now how i found that this function will suit my needs in the first place. Yeah, when searching for something like health or life you use these words to let the program search the whole code for you. The newest version of Sothinks Decompiler is capable of searching all scripts which is awesome.

We wanted to unlock all the levels so "unlockedLevel" just looked like the right variable to change. Sometimes it can be hard to find the right variables, sometimes almost impossible. I say do not give up easy on this as this is the most important thing. You need to know what you want to change before you can change it. OK, thats it we have what we want lets change it.

Step 3
It would be cool to know all from the head but variables have hex values that you do not know. We need the help of the Raw Data Mode of the decompiler. When clicking on it in the ActionScript menu at the top the script will change and shows you the Opcodes inside of functions. Just scroll down a bit and you will see the code has changed to gibberish

Lets take a look at the function "frame2" now in the Raw Data Mode. You can scroll and find it by yourself again or search for "unlockedLevel" in this script to find it. The right place should be found after searching for it two times. Here is the same code as shown before just in raw this time.
Code:
function frame2()
{

//d0 
_as3_getlocal <0> 
//30 
_as3_pushscope 
//60 ff 01 
_as3_getlex started
//60 9d 04 
_as3_getlex undefined

//14 5c 00 00 
_as3_ifne offset: 92
//5e ff 01 
_as3_findproperty started
//26 
_as3_pushtrue 
//68 ff 01 
_as3_initproperty started
//5e 8c 02 

_as3_findproperty unlockedLevel
//24 01 
_as3_pushbyte 1
//68 8c 02 
_as3_initproperty unlockedLevel
See it and love it as this tells you what really is going on when playing the game. Every Opcode has two lines here, the first represents the Hex Code and the second one is the human readable version. How much of this are we going to need? In this case the last three Opcodes which set the variable "unlockedLevel" to 1. We definitely want to change that to 30 as there are 30 levels in Max Dirt Bike 2.

Lets ask, can we do this? I tell you yes but why is that? Well, what we gonna change right now is only the 1 to 30. So the code we are changing is this here:
Code:
//24 01 
_as3_pushbyte 1
According to Adobe (ActionScript Virtual Machine 2 (AVM2) Overview) 24 is the Hex Code for pushbyte. Such a byte is only 8 bit long ranging from 0x00 to 0xff which is 0 to 255 in decimal. Only problem is that it is a signed variable which means it can be plus or minus. If you would go to high the value turns negative. Explaining this would go to far as you only need to know the range and not why. If you wan't to read it up here is a link: http://en.wikipedia.org/wiki/Two's_complement

For now i tell you that 0x00 to 0x7f is 0 to 127 and 0x80 to 0xff is -1 to -128. Right now we want to know what 30 is in hex for which you can use windows calculator or a site like this http://easycalculation.com/decimal-converter.php which does the conversion for you. By doing this we get the hex value 0x1e which lies in the range that is possible to change when using pushbyte.

To clear things up a bit see this what we want the code to change to.
Code:
from
24 01 which is 1
to
24 1e which is 30
Now lets go and find this in HxD our Hex Editor.

Step 4
Remember that i told you that we would need Swifty Decompress? We have to use it now before we can search for the hex values inside the game. To make the game smaller all swf files are compressed but this also prevents us from finding the values we want to change. If you have the "swfdecomp.exe" in the same folder as your swf file just drag the swf file onto the exe.



Doing so will decompress the file you dragged onto the exe. You will notice that the size changes if you check the file properties. It will be pretty quick so don't wonder and just see if the file got bigger. Swifty Decompress will give you errors when something is not working. Usually it works like a charm never had any problems with it.

Now we have a file that is ready for hacking.

Step 5
Open HxD now and open the wanted file from wherever you saved it.

You are now looking at a swf file in Hex Code. If it starts with FWS (0x46 57 53) you've done it right with the decompressing. A compressed swf file would start with CWS (0x43 57 53). By scrolling here you will barely find anything at all, we will need the infos from Sothink and the search function of HxD now. We could search for (0x24 01) but that would give us 48 results as there seem to be more variables which are set to 1 with this Opcode.

Why not use this "5e 8c 02 24 01 68 8c 02" to search? How i got that? Well, lets take a look at the info we got from Sothink again:
Code:
//5e 8c 02 
_as3_findproperty unlockedLevel
//24 01 
_as3_pushbyte 1
//68 8c 02 

_as3_initproperty unlockedLevel
You should see that i took the findproperty and initproperty to have a more specific value to search for. Now search for "5e 8c 02 24 01 68 8c 02" which should give you only one result which means we have found it.



In HxD you can change the "24 01" to "24 1e" and then save the game. When playing it the next time all the levels should be unlocked. Now you can play all the levels and still fail at half of them like me

Summary
We did a lot of stuff just to change 1 single byte from 0x01 to 0x1e.
  • Download the game.
  • Checking what is possible.
  • Learning to look at Raw data.
  • Decompressing the data to be able to edit it.
  • Using the Hex Editor to find and finally change the byte.


This is the very very basic stuff and i will explain more in the following hacks. A good idea is to make a hacklog to be able to know what you have done after you haven't looked at the hack for a while. So for the end of this i post my hacklog:
Code:
# MAKING ALL LEVELS AVAILABLE
# bike_fla/MainTimeline::frame2()
# Just needed to change the number of levels unlocked to 30.


CODE: unlockedLevel = 1;
BYTE: 5e 8c 02 24 01 68 8c 02

CODE: unlockedLevel = 30;
BYTE: 5e 8c 02 24 1e 68 8c 02
Deeper into the matter

Before we are going to do the next game lets learn some of the Opcodes that we need in almost every hack. In the most cases it is enough to change a specific numeric value like money, health, ammo and such. And numbers get assigned to a variable with pushing a number onto the stack and then initialize the variable with this value.

Lets think about the stack as something like the towers of Hanoi if you ever played this game. When stacking a number or a variable onto the stack you can only get them of the stack in reversed order. I constructed an little example after one that was given on Wikipedia so that it shows the AS Opcodes.

Code:
Changed example from http://en.wikipedia.org/wiki/Stack_(data_structure)

Input   Opcode  Opcode Hex   Stack (after op)
1  pushbyte   24 01  1
2  pushbyte   24 02  2, 1
4  pushbyte   24 04  4, 2, 1

*  multiply   a2  8, 1
+  add  a0  9
3  pushbyte   24 03  3, 9
+  add  a0  12
As you can see operations like multiply and add only affect the last two variables pushed onto the stack. This is important to know if you really wan't to understand the Opcodes given by Sothink SWF Decompiler. For me it really helps to switch between the AS code and the Raw Data, that can be done with opening the decompiler two times, one for Opcodes and one for the AS.

Having worked with flasm and knowing how assembler work in general can really help you out. Sometimes it can be somewhat confusing as Flash works weird in some ways. For the start we only want to look at numeric values:

Code:
Pushing values directly.
pushnull  20    (null)
pushundefined  21    (undefined)
pushbyte  24 ?? (0 to 127 and -1 to -128)
pushshort  25    See http://bluecork.net/cheats/short.php for converting values
pushtrue  26    (true)
pushfalse  27    (false)
pushnan  28    (NaN)


Mathematical operands
add    A0  (+)  Add the last value on the stack to the 2nd last.
subtract  A1  (-)  Subtracts the last value on the stack from the 2nd last.
multiply  A2  (*)  Multiplies the last value on the stack with the 2nd last.
divide  A3  (/)  Devides the 2nd last value on stack by the last.
negate  90  (-X) Negate the last value on stack.
increment  91  (++) Adds 1 to the last value on stack.
decrement  93  (--) Substracts 1 from the last value on stack.


Pushing variables that are saved in the constant pool.
pushint  2D ?? 
pushuint  2E ??
pushdouble  2F ??
Always keep in mind that you cannot change the size if an opcode. Lets say you want to change life from 100 (0x24 64) to 99 (0x25 bf 84 3d) it is not possible. The pushshort is two bytes to long and it would corrupt the file. For such changes you need pushint (0x2d) or pushuint (0x2e) and luck that a number like 99 is in the constant pool. Also you need RJTs Disassembler for finding the constant pool ids.

Usually these values get assigned to an variable then to be used further in the game. This happens with setproperty (0x61) or initproperty (0x6 like we had in the first example Max Dirt Bike 2.

Some links with further informations:
http://osflash.org/swf9opcodes
http://www.anotherbigidea.com/javaswf/a ... tions.html
http://www.adobe.com/devnet/actionscrip ... erview.pdf

Isoball

OK, after this introduction to some of the most important Opcodes we can take another game which we are hacking.
  • The game: http://www.freewebarcade.com/game/isoball/
  • Hacks we are doing: Unlock all normal and bonus levels, Stop the timer and making it easier to score perfect.
  • Programs used: Sothink SWF Decompiler, Swifty Tools, HxD


Unlocking all levels

Lets look at what we have in the ActionScripts on the right side. There are a lot of scripts again like in the first game we did. But there is also a folder "isoball_fla" which includes the class "MainTimeline". Again this is the place we are going to look, but remember that i must not always be "MainTimeline". Sometimes there isn't even such a script but something like "game" or so. You can either search or guess where to find what you wan't.

I normally fly over the whole code by scrolling and see what i can find. In this game i can find a function called "initlevel" it includes a switch statement which sets stuff like the time and what pieces you have for each level.
Code:
switch(level)
{
  case 1:

  {
    gamestart = [2, 19];
    gamefinish = [0, 15];
    leveltime = 60;
    piecelimits = [1, 2, 0, 0, 0, 0];
    tip = "PLACE PIECES TO MAKE A TRACK FOR THE BALL";
    break;
  }
We want to unlock the levels but not change them so we have to look further. Quite a bit down in the script there is a function called "frame1" and like i told you before frame functions normally start when the frame with the same name is shown in the Flash Player. And i found an promising part in which an Array is filled with the value you scored on each level.

Code:
while (i <= NROFLEVELS)
{
  if (DATA.scores[i] == null)
  {
    DATA.scores[i] = 0;
  }
  var _loc_2:* = i + 1;

  i = _loc_2;
}

...

while (i <= NROFBONUS)
{
  if (DATA.bonus[i] == null)
  {

    DATA.bonus[i] = 0;
  }
  var _loc_2:* = i + 1;
  i = _loc_2;
}
The first one sets the score for the normal levels to 0 as you have not played them when you start the game the first time (DATA.scores[i] = 0. The second part sets the score for the bonus levels (DATA.bonus[i] = 0. I just guessed that changing these variables to something more than 0 would enable the levels. Often this is trial and error so you never know before you haven't done the hack.

When you get more experienced you can check other parts of the code by searching to find out if you do the right thing. For now i can tell you that setting the initial score to 1 will enable all the levels. Now switch to Raw Data Mode and go to the function by searching for "function frame1" which will get you to the beginning of the function. Further down you can find the first part:

Code:
//60 86 03 
_as3_getlex DATA
//66 d6 05 
_as3_getproperty scores
//60 b9 01 
_as3_getlex i
//24 00 
_as3_pushbyte 0

//61 93 05 
_as3_setproperty {}

this translates to: DATA.scores[i] = 0;
So our first search in HxD would be "66 d6 05 60 b9 01 24 00 61 93 05" with the bold part as the one we want to change to 24 01.

Code:
_as3_getlex DATA

//66 db 05 
_as3_getproperty bonus
//60 b9 01 
_as3_getlex i
//24 00 
_as3_pushbyte 0
//61 93 05 
_as3_setproperty {}


this translates to: DATA.bonus[i] = 0;
The second search would then be "66 db 05 60 b9 01 24 00 61 93 05" again with the important part bold.

So open up HxD or your Hex Editor of choice and search for part one. It should give you only one result so you can straight go to changing the 24 00 to 24 01. Then use the second search values to find and change it to 24 01 also. Save the game and open it to check if your hack worked. Every level should be unlocked and have the score of 1.



Alright that is really cool, now we can play all the levels even if we haven't made it through the previous levels yet. But if you are like me you may encounter more problems which is the time. So lets disable this!

Disabling time or how i stopped the time without using drugs!

Switching back to ActionScript mode i searched for "time" which was found quite often in "MainTimeline" but after a while it lead me to a function called "timeUpdate". Now that sound just like a function which would update the time probably. Here is how the time that is left is calculated:
Code:
timeleft = Math.ceil(leveltime - (_loc_2.getTime() - starttime.getTime()) / 1000);

and in Opcodes:

//5e b7 01 
_as3_findproperty timeleft
//60 9b 05 

_as3_getlex Math
//60 b3 01 
_as3_getlex leveltime
//d2 
_as3_getlocal <2> 
//46 e9 05 00 
_as3_callproperty getTime(param count:0)
//60 ac 02 

_as3_getlex starttime
//46 e9 05 00 
_as3_callproperty getTime(param count:0)
//a1 
_as3_subtract 
//25 e8 07 
_as3_pushshort 1000
//a3 
_as3_divide 

//a1 
_as3_subtract 
//46 ea 05 01 
_as3_callproperty ceil(param count:1)
//68 b7 01 
_as3_initproperty timeleft
This can be found in the very beginning of the function. Now there are different methods to change this timer from going down. We will look at both of them. First the easier one which is to set the 1000 to a much higher number. This will make the time that gets subtracted from timeleft so small that it wouldn't even affect the game anymore.

You should know by now how to find this in the Hex Editor, just make sure you use enough values to get only one result. The part we want to change is 25 e8 07 which means 1000 to lets say 9999. http://bluecork.net/cheats/short.php?val=9999 should do the trick and give you the new value which would be 25 8f 4e. You could try bigger values but first it is enough with 9999 and much higher values would need to add one byte to the pushed value. 99 for instance would mean 25 9f 8d 06 but that is to long as you would overwrite the next Opcode or corrupt the file by inserting a byte.

You have to keep this in mind:
  • You cannot change the file size
  • You cannot overwrite other Opcodes that are needed to work properly

But there is a way to overwrite code that you do not need or do not want with an opcode that does absolutely nothing. It is nop or "no operation" (0x02) and can be used to delete code without changing the file size.

Changing the timeleft value every time to leveltime would do the trick really good. Here is how it would look like:
Code:
timeleft = leveltime;


//5e b7 01 
_as3_findproperty timeleft
//60 b3 01 
_as3_getlex leveltime
//68 b7 01 
_as3_initproperty timeleft
As you can see we only use 9 bytes of code here so all the other Opcodes need to disappear and that can be done with nop (0x02). See the part of my hacklog to understand what i mean:
Code:
CODE: timeleft = Math.ceil(leveltime - (_loc_2.getTime() - starttime.getTime()) / 1000);
BYTE: 5e b7 01 60 9b 05 60 b3 01 d2 46 e9 05 00 60 ac 02 46 e9 05 00 a1 25 e8 07 a3 a1 46 ea 05 01 68 b7 01

CODE: timeleft = leveltime;
BYTE: 5e b7 01 60 b3 01 68 b7 01 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
The first part of bytecode is what i have created above and all the other operations have been "nopped out". And yes, you have to change that in the Hex Editor to be able to play the game with a stopped time.

That shows how a different approach can lead to the same result. Maybe you come up with a whole different way and still do the same thing. Nothing is right and nothing is wrong maybe just more elegant or complicated.