Prevent cheating in Flash games
Have you ever seen ridiculously high high scores in a Flash game? I have. Our games’ scores have been hacked a few times as well. This is understandable as scores can be hacked or cheated in many ways and Flash swf simply isn’t a secure file format. Those bloody script kiddies won’t give up - they have always the newest tools and toys and they will try to break anything you build - believe me. There is absolutely no way you can make hacking high scores impossible, sorry. Still, most of these so-called hackers are just script kiddies trying some new toy to push their scores through. If they fail, they will give up pretty soon and go on and try it with some other game. The thing is not to make your game 100% secure - it is enough that you block the most common holes. I will now describe the most common ways of cheating in Flash games and how to deal with them.
A buggy game is the worst case. Often bugs can be used to players’ advantage. Player might be able to find a place to never die and scores keep running. For example, one quite common bug I have seen is in those mouse avoider games. Clicking right mouse button deactivates the game and allows user to go through obstacles that would otherwise kill you. So, before even thinking anything else, fix your bugs. Do a lot of testing - try things that don’t make sense as well - otherwise your players will do that for you. All the rest is pretty useless if you have a buggy game.
I guess one of the easiest and most used hacking methods is hacking the variable values directly in memory with a tool. One such tool is Cheat Engine. This allows user to search for a variable value in Flash memory and alter it. For example, you know that your score is 123,456 (usually presented in game screen). Search for that value and change it to any score you wish and wow, score is hacked.
Now how to avoid this? Many free APIs contain a special class or function for saving critical values. Remember that often you don’t want to protect only the score variable but also some other variables. Such values might be, to mention a few: time survived, multiplier and level. You could protect all the variables, but be aware that protecting values causes a small overhead in performance. One such API is provided by Mochiads. It includes (undocumented but easy to understand) class MochiDigits. You can save floating point numbers (sure, integers as well) safely with it. These classes are usually implemented so that the a random value somehow is applied to actual variable and thus make it impossible to search for value in memory. They can also calculate some sort of a hash to secure the value and if hash calculation fails, class can react to illegal altering of variable.
When you play a Flash game, the game is downloaded to your computer. On the other hand, high scores are located on Internet server - not on your computer. When you achieve a new record the game sends the score to server. Now, how about catching that score while sending it, then altering it, and finally sending altered variable? Yep, that’s possible and easy. One way is to use a simple proxy program on your computer. When Flash submits your score as HTTP request, proxy catches it, views it to you. You don’t need to understand a lot of HTTP messages to be able to find the score variable in that request and alter it. And let proxy send it to server. Once again, score hacked.
If you are using some leader boards/high scores API, then it’s most likely that this is handled for you and you don’t need to care about this. If however, you are sending scores to eg. your own script, then you must take care of this problem on your own. One way is to share a secret between server and a game swf and crypt score variable with this shared secret.
Decompiling: Your secrets are not safe
But then, there are handful of free Flash decompilers available. These tools allow you to take any Flash file and transform it back to source code - even variable and function names are as they were. Now the attacker knows how you are preventing his previous attacks from working and he can find a way around them (well, if he/she is determined enough). If you have shared secrets in your code, attacker has them now too.
How can you prevent decompiling. Firstly, your code can be obfuscated. This means that variable names and function names can be changed so that your code becomes unreadable after decompiling. This makes it a lot harder to read your code and finding important parts in there. Tools, such as “Amayeta”:http://www.amayeta.com, will obfuscate your code and do some magical stuff so that decompilers cannot decrypt it. Mochiads also has a nice version control + encryption service which automatically encrypts your game and gives you the ability to push live updates to your game - wherever it is distributed. Amayeta is a commercial program but you can try it with free trial version. Notice that Flash Player still have to understand your code after these obfuscations and encryptions and thus these tools will still produce code that works - this means that code is still vulnerable to decompiling. Amayeta is designed so that it takes advantage in decompilers’ weaknesses.
Some people are against these encryption tools. They think that decompiling is ethically wrong (hell yeah it is!) and illegal and shouldn’t be done and thus encryption programs are unnecessary. Yes, that’s how it should be. In the real world, if someone steals your content, it is very unlikely that you really can/will put charges against him. That’s why encryption is often needed.
Framedrop against slowdown
What if your game is played on a slow computer? What if somebody is overloading his computer to slow down your game? Often both game logic and view are implemented in ENTER_FRAME event. This is bad if frame rate has any affect in your game since if there is not enough execution time for your game, this even will simply occur less often. Sure, if it’s a puzzle game where speed does not have a meaning, then you have no problems. Now you might think that you can fix this by running events in timer tick event? No - that does not give you any more execution time magically. The solution is to divide game to two parts: logics and drawing. Drawing is something you would like to happen in sync with frame rate but if there is not enough execution time available this is where you must give up. Game logics is the thing that changes your models, moves your things and interacts between objects. This is something that MUST keep going even if there is not enough time.
You can choose between a few possibilities here. First and the simpliest one is to use a more advanced timer class as compared to one default Timer class. Here is a good and free alternative. Basically this class detects the actual frame rate and if it’s lower than the requested one, it calls listener function multiple times to keep up to date. Of course, if you have implemented everything - drawing and logics - in this function, your Flash application will suck all the performance and kill Flash Player. With variable frame rate, this may however cause a bit dodgy movement as sometimes your logics is run once between frame updated and sometimes twice.
There are more sophisticated methods to fix your timestep. This article provides more explanations and solutions on fixing your time step.
Don’t expect others to see what you see
Your game may be embedded with a different background colour. If your game does not have a background of it’s own, this might affect how your game looks like. It might even show some secrets… In addition to background color, your game can easily be scaled up and that too may reveal some hidden stuff you meant to bee off-screen. There are other variables that can be defined with embed code as well. Get familiar with those.
That’s not the end
There are many other ways and if attacker has enough time and skill, he most likely can hack your game. But usually attackers are just people trying a method or two and once those do not work, they will give up. Now, that’s a lot to do, but it’s all pretty simple stuff. Get used to it.