We’ve been hearing a lot of complaints recently about game “rebranding theft” — where unscrupulous websites hack your newly-released game and change your sponsor splash screen, logo, and other identifying assets. This practice is mostly confined to a few countries, especially Chinese portals, and has been happening for years, but it seems to be growing more common.
This amounts to game theft, of course, and it goes completely against the sponsorship model. It’s also quite illegal to modify and redistribute a copyrighted game like this… which is why it is less common in the US, where a sponsor could easily sue another portal for such behavior. But for portals operated in other countries, it can be difficult to take legal action against them.
But you, the developer, can take action! It is actually pretty easy to protect your game from being rebranded. First, you need to know a bit about SWF files.
SWF Format Makes Image Changing Easy
The SWF file format is an open format, well documented by Adobe itself [pdf]. SWF files are made up of little individual chunks, kind of like how a .ZIP file is made up of lots of files. Your pictures are each stored as separate chunks in the file.
Much as you can unzip a .zip file, you can unzip a SWF into its parts. Then you can change some parts (such as the images) and zip it all back into a SWF again. (I’m simplifying a lot, of course — it’s more complicated than the .ZIP file format, but the idea is very much the same!) Your images, your sounds, your shapes, and your code are all stored as separate little units inside the file.
This isn’t a flaw in the SWF format — it’s a feature! Adobe has made the format quite easy to use so that it can be read and manipulated by anybody. The convenience of this format is why there are so many great tools and languages for Flash. But it has a down side, too… it means it’s easy for somebody to replace your images with their own. There are tons of very good tools that can break your SWF down into parts and then put it back together again, with new images included.
Encryption Tools Protect Source Code, Not Images…
You may be wondering, “Well then, what do the various SWF encryptors do?” These don’t encrypt your images. They encrypt your code. If we use the zip-file analogy again, your compiled AS2 or AS3 source code is stored in the SWF file as separate chunks, completely isolated from the images and sounds and so on. What encryptors like Kindisoft do is munge those particular “code” chunks so that they are much harder for human beings to figure out.
But they don’t protect your images… since those are just stored directly as JPEGs, there isn’t much that can be “encrypted” about them. If an encryptor changed the image data, the Flash player wouldn’t know how to read the file!
… So Use Your Code To Protect Your Images
So if only code is protected, how do you protect your images? You write code that verifies your images are what you expect! Then you take advantage of Kindisoft or another code-encryptor to make sure that malicious users can’t remove your code checks.
But how does your code know if the image is right? What we need are “checksums” — a small value that mathematically represents a larger data unit. You may have heard of MD5 or SHA1 checksums… same idea. But there are actually tons of ways to checksum something. Here’s the simplest (and hence, fastest-to-calculate) checksum:
This function just loops over every pixel in your image, and adds all the RGB values of every pixel together. This results in a number. If the image changes, the number will change, too. Tada! Now your game just needs to check your images at runtime to make sure that it calculates the same number that you calculated originally. If the number’s not what you expected, the image was changed.
First, write a little throw-away program to find out the checksum numbers for the image(s) you want to protect. Assuming you have a DisplayObject or Image control named “picture”, this is how you call the above function on it:
Now you should see something like this in your trace output window: “This image’s checksum is 4921452″. Collect these numbers for each image you want to protect, and then copy them into your actual game. In your game, you call the same function and just check against those numbers:
Repeat this process for each image. (Make sure the images are fully loaded before you do this!)
If your game detects that it’s been hacked, it should display a polite message and then shut down. Warning: Always be polite in these sorts of messages; never do anything unprofessional. Remember that anything you do on the internet will eventually be taken out of context! It may sound funny to show a picture of the goatse guy when you’re hacked, but somehow, somewhere, that gag is going to backfire on you. Just show a polite message and make the game stop working.
Be Double Secure – Use Two Checksums Together
The above method is all you need to protect your game from having other images stuck into it. But the checksum function I used above is mathematically pretty weak. If a hacker was willing to try enough different pictures, they would find one that has the same number as your picture. It’s probably not worth their trouble, but you never know how determined they’re going to be.
So since we’re feeling paranoid, let’s double it up with a second checksum! We’ll use the well-known SHA256 algorithm. Why? Because it’s very secure… and also because it’s easy to get ahold of! No math is required on our part. If you’re using Flex, then it’s built right in:
Or if you aren’t using Flex, you can download the source of the AS3 Core Lib, drop that into your project folder, and use the SHA256 function that comes with that, instead:
These functions work exactly like
checksum_Basic above, except they return a string like “
ce68f9ebff02e8019702a3b4bc8d93535ffcf6b4844f24c0cf37e93bb871b97b” instead of a number. So you just collect those strings and then plug them into your program, same as above. If a picture has a different string at runtime, then it’s obviously changed!
You may wonder, why use both? Why not just use the string function, since it’s harder to trick? The answer is very pragmatic: it turns out that the SWF file format stores all the strings in your game together in little bundles, separate from the code. So even if your code is encrypted, a hacker can sometimes still see and change your string literals! (Kindisoft’s encryptor has a mode that encrypts strings as well as code, but other encryptors don’t.) So a savvy hacker could look for any string that looks like a checksum value, and replace it with the checksum of their own new image, fooling your code. It would be tedious, especially if you have a bunch of images with different checksums — they’d have to experiment to figure out which checksum went with which picture. But it doesn’t pay to underestimate the patience of game thieves.
It’s much harder to track down integer values, especially if you use a lot of constants in your program. Using both a string and an integer at the same time makes it quite difficult to trick your app.
That is, unless you don’t use an encryptor! Remember, this only works if you encrypt your code. If you don’t, then all of this was a waste of time, because thieves can just view your code, see exactly what you did, and remove all those if-statements! If you still haven’t bought an encryptor, do so — it’s a necessary investment. FGL’s encryptor of choice is Kindisoft’s secureSwf product — in our tests, this is much more effective than the other encryptors we tested. It’s also quite reasonably priced for FGL members, as Kindisoft has provided us with a special coupon code for FGL users.
Finally, Beware The Cheap Trick of Moving Your Image Off-Screen!
The way the SWF file format works is both a blessing and a curse. Well, for game devs trying to keep their games safe, it’s mostly a curse. Case in point: even if you protect your images as described above, hackers may still be able to remove your branding! How? By moving it off the screen! If you use the Flash development IDE and place the image on a MovieClip frame, then that frame data gets stored separately from your code. As explained above, only your code is encrypted… so a clever hacker can simply change the x,y coordinates of your image so they’re off the screen, or shrink the width and height to be 1 pixel in size!
If you’ve placed your logo and splash screen on frames in Flash, you should write code that makes sure the images are where you intended them to be. If the picture’s supposed to be at 0, 0, and 640×480 wide (or whatever), your game code should make sure it’s where it’s supposed to be!
If you code directly in pure AS3, or if you use Flex Builder, Alchemy, or haXe, you aren’t susceptible to this problem because your code is what positions the images. The only games that are susceptible to having their images moved off-screen are the ones written directly in Flash player, when the image is placed directly onto a frame.
EDIT: pjbaron pointed out that there are more variables that can be adjusted:
alpha should be 1.0,
visible should be true, and
scaleY should be the values you expect them to be. Hmm, this is a lot of variables to validate!
EDIT #2: Rocketman had another approach: use checksums on your fully-rendered splash screens, instead of just the splash screen images. This is easy to do — just dump the entire stage to a BitmapData, get the checksum of it, and use that checksum as described above. If your stage’s checksum changes from what you expected, then something on the stage has gotten moved around somehow.
EDIT #3: But that idea doesn’t work too great because if your game gets resized on some portal, the fully-rendered splash screen checksum will come out wrong. So I don’t recommend that plan after all.
EDIT #4: My current “best recommendation” is to simply not put important branding like splash screens on a movieclip frame at all… in other words, don’t place them on the screen in the Flash IDE. Instead, write some ActionScript code on that frame that creates the image and adds it to the stage or movieclip via
addChild(). That way you bypass all of the nonsense about the variables getting manipulated, and it’s much harder to screw up unintentionally.
AS2 Users… All Of This Applies To You, Too!
Unfortunately, I don’t know how to code in AS2… at least, not well enough to make blog examples for it! But the same ideas described here apply for you, too.
AS2 has a BitmapData object also, but it doesn’t have a way to dump all of its pixels at once, so you’ll need to use BitmapData.getPixel() to get each pixel out of your image and add it to your checksum. This method will be much slower than the AS3 version, so you may not be able to do it to all the images in a large game — it might be noticeably slow — so just pick the ones that really matter!
Hopefully a savvier AS2 blogger will pick this up and provide good examples for you to work from.
So there you have it! You can protect your games from being illegally rebranded with less than an hour’s work. Definitely worth the effort to keep your sponsor logo and game branding visible.