How To Protect Your Game From Being Rebranded (AS2)

Eric Heimburg from FlashGameLicense.com wrote an article about
How to protect your game from beeing rebranded for Actionscript3.

Because i’m developing flash-based-games here and there i found this article quite interesting. After reading this post i digged in my old experiments from the good old Actionscript2 times to get familiar again with the syntax. It’s been ‘a couple of days’ since i wrote my last lines of code in AS2. But following the idea of Eric the code is pretty much the same exept a few loops more.


Important Note: As stated in the article this makes only sense if you’re obfuscating your code using one of the encryption tools out there !

Back to topic, here is what it will look like in Actionscript2:

var bmp: BitmapData = new BitmapData(300, 225);
var result: Number = 0;
var x: Number = 0;
var y: Number = 0;
var w: Number = bmp.width;
var h: Number = bmp.height;
 
for (x=0; x<w; x++) {
  for (y=0; y<h; y++) {
    result += bmp.getPixel(x, y);
  }
}
 
trace(result); // e.g. 556977304436

For an image with e.g. 300×225 pixel it took about 90ms to summarize the “checksum”.
Below a little overview of my results for some image sizes.

  • 640×480 – 379 ms
  • 800×600 – 547 ms
  • 1024×768 – 1436 ms

Hm, approx 1.5 secs for an 1024×768 pixel sized image. This is a quite noticable duration.
Especially when you are loading a lot of large scaled images or have a lot of them in your library this would affect the user experience in a negative way.

To see if we can push this a bit further and how much this could be speed up i wrote some test-methods.
My first idea was to take just a 1-pixel line in the horzontal and the vertical direction.

Which would look like this:

/**
 * Summarize the color-values of a 1-pixel line in horizontal
 * and vertical direction to build a checksum-like value for
 * the passed BitmapData object.
 * 
 * @param   bmp The BitmapData object to build the checksum for
 * @param   offset  The offset for x and y (optional); default (10)
 * @return    The checksum
 */ 
function horizontal_vertical (bmp:BitmapData, offset:Number): Number {
 
  offset = offset == undefined ? 10 : offset;
 
  var result: Number = 0;
 
  var x: Number = 0;
  var y: Number = 0;
  var w: Number = bmp.width;
  var h: Number = bmp.height;
 
  for (x = offset;x < w; x++) {
    result += bmp.getPixel(x, y);
  } 
  for (y = offset;y < h; y++) {
    result += bmp.getPixel(x, y);
  }
 
  return result;
}

The second way is to get the values from the diagonales in both directions. Which means from “top-left” to “bottom-right” and from “top-right” to “bottom-left”. Here is the method for it.

/**
 * Summarize the color-values of a 1-pixel line in both
 * diagonal directions to build a checksum-like value for
 * the passed BitmapData object.
 * 
 * @param   o The BitmapData object to build the checksum for
 * @return    The checksum
 */ 
function diagonal (o:BitmapData): Number {
 
  var result: Number = 0;
  var x: Number = 0;
  var y: Number = 0;
  var w: Number = o.width;
  var h: Number = o.height;
 
  for (x=0; x<w; x++, y++) {      
    result += o.getPixel(x, y);
  } 
 
  for (x=w; x>0; x--, y--) {
    result += o.getPixel(x, y);
  }   
 
  return result;
}

And finally a method to combine the both values but this one is more for “cosmetic” purposes.. ;)

/**
 * combine the results of horizontal and diagonal checksum values
 * @param   bmp The BitmapData object to build the checksum for
 * @return    The checksum
 */
function combined (bmp:BitmapData): Number {
 
  return horizontal_vertical(bmp) + diagonal(bmp);
}

Now it’s time to measure the execution times for the test-methods. Lets do this quick and simple:

 var t1: Number  = getTimer();
 var chk: Number = combined (bmp);
 var t2: Number  = getTimer();
 
 trace('combined');
 trace(' - executed in: '+ (t2-t1) +' ms');
 trace(' - version: ' + chk);
 
// combined
// - executed in: 9 ms
// - version: 11356386289

9ms! That’s nice, right ? And you know what ? This is the execution time for a 1024×768 pixel image ! So as you can see, even with a large image its incredebly fast.

To complete the overview, here my results for the other image sizes and the #combine-method.

  • 640×480 – 5 ms
  • 800×600 – 6 ms
  • 1024×768 – 9 ms

They may vary on different hardware setups but i thinks it’s performant enough to use it even on older machines.

/**
// results for an image with 1024x768 pixel
 
complete
 - executed in: 1214 ms
 - version: 4442572803510
horizontal/vertical
 - executed in: 3 ms
 - version: 2505805708
diagonal
 - executed in: 5 ms
 - version: 8850580581
combined
 - executed in: 9 ms
 - version: 11356386289
*/

The validation part is pretty much the same as in Actionscript3 so read the article mentioned above to see implementation details.

After all i think this approach produces a reasonable checksum value and is fast enough and to use it your daily workflow as (game)-developer.

Thanks for reading. Feel free to share this or leave a comment.

This entry was posted in experiments and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">