Protect your ActionScript with Amayeta’s SWF Encrypt

Ok... you made it... you made the Flash game that will kick asses and you are sure nobody knows Actionscript like you. Nobody will clone your game because you know ActionScript better than the rest.

If you really know ActionScript, you should now that even if SWF files are compiled, they can be easily decompiled with a lot of softwares available on the net. Just Google for Flash Decompiler to see the most famous ones.

This means that once you published your file, everybody can do reverse engineering on your file and know how did you coded it.

And even if bigger projects are hard to understand, someone may decompile your game, change your logo with another one and submit it in all portals before you do it.

If you think people won't waste their time decompiling your game, you are wrong. They will do it... maybe to hack your highscores, or maybe to put their name in the credits and show their friends what a cool game they made... for a reason or for another, they will do it.

That's when Amayeta comes in our help with its SWF Encrypt. Available both for Windos and Mac OSX encrypts your Adobe Flash SWF files, protecting them from the most popular Flash Decompiler Tools on the market.

Sounds good... here I am for a test drive...

Amayeta's SWF Encrypt (ASWFE from now on) takes less than 5MB on your hard drive, and once you lauch it you will see this screen:

Amayeta SWF Encrypt

ASWFE shows your unprotected SWF files with a red background and the protected ones with a green background.

In the bottom window you can preview the movie you currently selected. As you can see, I am trying to protect my prototype of Metro Siberia Underground game.

Now just press Encrypt File(s) and you will find a SWF file with the _secure suffix. In my case, the original file was 1butt3.swf, and the new one is 1butt3_secure.swf. Please notice that I did not change any option, and I don't play with strange setups. ASWFE works very well with default options, and all you have to do is pressing a button.

But the final question is: will it work? I tried to decompile 1butt3.swf, the unprotected file, and that's what I got:

ACTIONSCRIPT:
  1. // Action script...
  2.  
  3. // [Action in Frame 1]
  4. var ship_filter = new flash.filters.GlowFilter(65280, 8.000000E-001, 4, 4, 2, 3, false, false);
  5. var smoke_filter = new flash.filters.GlowFilter(16711680, 8.000000E-001, 4, 4, 2, 3, false, false);
  6. var tunnel_filter = new flash.filters.GlowFilter(16776960, 8.000000E-001, 4, 4, 2, 3, false, false);
  7. var fuel_filter = new flash.filters.GlowFilter(65535, 8.000000E-001, 4, 4, 2, 3, false, false);
  8. var rock_filter = new flash.filters.GlowFilter(16777215, 8.000000E-001, 4, 4, 2, 3, false, false);
  9. var score_filter = new flash.filters.GlowFilter(16711935, 8.000000E-001, 2, 4, 2, 3, false, false);
  10. gravity = 1.000000E-001;
  11. thrust = 2.500000E-001;
  12. yspeed = 0;
  13. xspeed = 5;
  14. distance = 0;
  15. smoke_interval = 10000;
  16. frames_passed = 0;
  17. tunnel_height = 150;
  18. fuel_freq = 10;
  19. gasoline = 500;
  20. rock_freq = 50;
  21. engines = false;
  22. _root.attachMovie("ship", "ship", _root.getNextHighestDepth(), {_x: 150, _y: 200});
  23. _root.createEmptyMovieClip("fuel_movie", _root.getNextHighestDepth());
  24. _root.createEmptyMovieClip("deadly_movie", _root.getNextHighestDepth());
  25. _root.attachMovie("score", "score", _root.getNextHighestDepth());
  26. ship.filters = new Array(ship_filter);
  27. score.filters = new Array(score_filter);
  28. ship.onEnterFrame = function ()
  29. {
  30.     score.sc.text = "Distance: " + distance + " - " + "Fuel: " + gasoline;
  31.     if (gasoline> 0 && engines)
  32.     {
  33.         yspeed = yspeed - thrust;
  34.         smoke_interval = smoke_interval - 2.500000E-001;
  35.         gasoline = gasoline - 1;
  36.     } // end if
  37.     if (Math.random() * 1000 <fuel_freq)
  38.     {
  39.         fuel = fuel_movie.attachMovie("fuel", "fuel" + fuel_movie.getNextHighestDepth(), fuel_movie.getNextHighestDepth(), {_x: 510, _y: Math.random() * 400 + 50});
  40.         fuel.filters = new Array(fuel_filter);
  41.         fuel.onEnterFrame = function ()
  42.         {
  43.             this._x = this._x - xspeed * 1.200000E+000;
  44.             dist_x = ship._x + 28 * Math.cos(angle) - this._x;
  45.             dist_y = ship._y + 28 * Math.sin(angle) - this._y;
  46.             dist = Math.sqrt(dist_x * dist_x + dist_y * dist_y);
  47.             if (dist <10)
  48.             {
  49.                 gasoline = gasoline + 100;
  50.                 this.removeMovieClip();
  51.             } // end if
  52.             if (this._x <-10)
  53.             {
  54.                 this.removeMovieClip();
  55.             } // end if
  56.         };
  57.     } // end if
  58.     if (Math.random() * 1000 <rock_freq)
  59.     {
  60.         rock = deadly_movie.attachMovie("rock", "rock" + deadly_movie.getNextHighestDepth(), deadly_movie.getNextHighestDepth(), {_x: 510, _y: Math.random() * 400 + 50, _rotation: Math.random() * 360});
  61.         rock.filters = new Array(rock_filter);
  62.         rock.onEnterFrame = function ()
  63.         {
  64.             this._x = this._x - xspeed;
  65.             if (this._x <-10)
  66.             {
  67.                 this.removeMovieClip();
  68.             } // end if
  69.         };
  70.     } // end if
  71.     yspeed = yspeed + gravity;
  72.     this._y = this._y + yspeed;
  73.     angle = Math.atan2(yspeed, xspeed);
  74.     this._rotation = angle * 180 / 3.141593E+000;
  75.     ++frames_passed;
  76.     distance = distance + xspeed;
  77.     if (frames_passed>= smoke_interval)
  78.     {
  79.         sm = _root.attachMovie("smoke", "smoke" + _root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x: this._x - 2, _y: this._y});
  80.         sm.filters = new Array(smoke_filter);
  81.         sm.onEnterFrame = function ()
  82.         {
  83.             this._x = this._x - xspeed;
  84.             this._width = this._width + 2.000000E-001;
  85.             this._height = this._height + 2.000000E-001;
  86.             this._alpha = this._alpha - 2;
  87.             if (this._alpha <= 0)
  88.             {
  89.                 this.removeMovieClip();
  90.             } // end if
  91.         };
  92.         frames_passed = 0;
  93.     } // end if
  94.     if (this._y> 400 || this._y <0 || deadly_movie.hitTest(this._x + 28 * Math.cos(angle), this._y + 28 * Math.sin(angle), true) || deadly_movie.hitTest(this._x + 8 * Math.cos(angle + 1.570796E+000), this._y + 8 * Math.sin(angle + 1.570796E+000), true) || deadly_movie.hitTest(this._x + 8 * Math.cos(angle - 1.570796E+000), this._y + 8 * Math.sin(angle - 1.570796E+000), true))
  95.     {
  96.         yspeed = 0;
  97.         this._y = 200;
  98.         gasoline = 500;
  99.         distance = 0;
  100.         deadly_movie.removeMovieClip();
  101.         fuel_movie.removeMovieClip();
  102.         _root.createEmptyMovieClip("fuel_movie", _root.getNextHighestDepth());
  103.         _root.createEmptyMovieClip("deadly_movie", _root.getNextHighestDepth());
  104.     } // end if
  105. };
  106. _root.onMouseDown = function ()
  107. {
  108.     engines = true;
  109.     smoke_interval = 10;
  110. };
  111. _root.onMouseUp = function ()
  112. {
  113.     engines = false;
  114.     smoke_interval = 100000;
  115. };

It changed some logical operators (or with ||) and made some minor changes, but the code is perfectly readable.

Now, let's decompile the protected file:

ACTIONSCRIPT:
  1. // Action script...
  2.  
  3. // [Action in Frame 1]
  4. function ()
  5. {
  6.     \x03 = 2568 % 511 * 5;
  7.     return (eval("\x03"));
  8. } // End of the function
  9. var \x01 = 439 + \x04\x05();
  10. for (\x01 = eval("\x01") - 372; eval("\x01") == 590; \x01 = eval("\x01") + 140)
  11. {
  12. } // end of for
  13. if (eval("\x01") == 933)
  14. {
  15.     \x01 = eval("\x01") - 21;
  16.    
  17. }
  18. else
  19. {
  20.     \x01 = eval("\x01") - 51;
  21.     var null = true;
  22.     if (eval("\x01") == 810)
  23.     {
  24.         \x01 = eval("\x01") + 123;
  25.        
  26.     } // end if
  27.     if (eval("\x01") == 636)
  28.     {
  29.         \x01 = eval("\x01") - 46;
  30.        
  31.        
  32.     } // end if
  33.     if (eval("\x01") == 132)
  34.     {
  35.         \x01 = eval("\x01") + 504;
  36.         if (!null)
  37.         {
  38.         }
  39.         else
  40.         {
  41.             \x01 = eval("\x01") - 46;
  42.         } // end else if
  43.        
  44.     } // end if
  45.     if (eval("\x01") == 594)
  46.     {
  47.         \x01 = eval("\x01") - 8;
  48.        
  49.     } // end if
  50.     if (eval("\x01") == 872)
  51.     {
  52.         \x01 = eval("\x01") - 142;
  53.        
  54.     } // end if
  55.     if (eval("\x01") == 96)
  56.     {
  57.         \x01 = eval("\x01") + 714;
  58.         if (!null)
  59.         {
  60.         }
  61.         else
  62.         {
  63.             \x01 = eval("\x01") + 123;
  64.         } // end else if
  65.        
  66.     } // end if
  67.     \x01 = eval("\x01") + 223;
  68.     if (eval("\x01") == 116)
  69.     {
  70.         \x01 = eval("\x01") - 20;
  71.        
  72.     } // end if
  73.     if (eval("\x01") == 687)
  74.     {
  75.         \x01 = eval("\x01") - 571;
  76.        
  77.     } // end if
  78.     if (eval("\x01") == 953)
  79.     {
  80.         \x01 = eval("\x01") - 574;
  81.         if (true)
  82.         {
  83.         }
  84.         else
  85.         {
  86.             \x01 = eval("\x01") + 319;
  87.         } // end else if
  88.        
  89.     } // end if
  90.     if (eval("\x01") == 912)
  91.     {
  92.         \x01 = eval("\x01") - 912;
  93.        
  94.     } // end if
  95.     \x01 = eval("\x01") - 199;
  96.     if (eval("\x01") == 379)
  97.     {
  98.         \x01 = eval("\x01") + 319;
  99.        
  100.        
  101.     } // end if
  102.     if (eval("\x01") == 698)
  103.     {
  104.         \x01 = eval("\x01") - 112;
  105.        
  106.     } // end if
  107.     \x01 = eval("\x01") + 351;
  108.    
  109. } // end else if

What a mess! The script s full of strange variables and if you try to execute it in Flash, it will produce tons of errors.

The script is definitively unreadable.

Try before buy

You can download a trial version limited to 15 encryptions and displaying a watermark on your file (useless if you publish your work in the web, useful if you submit a game to Flash Game License) or buy it at $125. If you want to get serious in ActionScript development, you need to protect your work, and at the moment ASWFE is the perfect solution.

Improve the blog rating this post
Tell me what do you think about this post. I'll write better and better entries.
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...

» Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.

17 Responses to “Protect your ActionScript with Amayeta’s SWF Encrypt”

  1. Livesinabox on February 11th, 2008 1:35 pm

    It’s not totally fool proof, but it’s pretty good. It uses unprintable characters and other things to trick most decompilers. The decompilers usually get updates in 3-6 months so eventually someone will be able to decompile it, but they will have fairly untidy code with weird names for variables and functions (but still usable).

    The most important things for protecting your code with obfuscation are

    identifier renaming (turns smoke_interval into h8I9we0U)

    and

    string encryption (turns all text in “” to encrypted versions)

    both of these make it hard to read decompiled code. Not impossible, just hard.

    A good place to read about this stuff is ASVGuy’s blog http://www.asvguy.com/2007/02/swf_encrypt_swc.html

  2. Orava on February 11th, 2008 3:48 pm

    this is good if you’re better game/animationmaker and want to sell ur creations to somewhere!

    Hey Emanuele, would you have time to do an interview (with email)
    i’d like that and that would be great addition to my schoolproject about flash.
    is there a email i can send the questions (if this is even okay with you…..) or can you see mine (”E-mail (will not be published) (required)”)
    or i say my email out loud here?

  3. Xavi on February 11th, 2008 5:42 pm

    why 125$ for an encrytion program?
    I know I defenitely won’t spend that much…

  4. andrew on February 11th, 2008 6:18 pm

    Emanuele, check your email. I sent you the mega roll swf. I would really appreciate it if you could publish it.

  5. Ed on February 11th, 2008 6:23 pm

    $125 is a lot if, as Livesinabox says, will be outdated in a few months. I’m surprised Adobe/Macromedia haven’t implemented an Actionscript code to stop people decompiling SWFs.

  6. Emanuele Feronato on February 11th, 2008 7:34 pm

    That’s why you should download the trial and send 15 games to flashgamelicense.

    With 15 games sponsored, it won’t be a problem purchasing the original :)

  7. Gabriel on February 11th, 2008 8:49 pm

    Isn’t there any free similar program? I’m poor…

  8. Gabriel on February 11th, 2008 9:50 pm

    Continuation:

    Look this link…

    http://www.hallpass.com/developers/api.html

    Hall Pass is offering 50 dollars for games with their API… But they don’t explain how… Well, not easily enogh to me to understand… Can you do a tutorial?

  9. Emanuele Feronato on February 12th, 2008 1:21 am

    I tried to use Hallpass highscores API but I never got paid, and the game seems not to send any score to hallpass server.

    Maybe I made something wrong… I’ll try the luck again with my next game

  10. Gabriel on February 12th, 2008 8:03 pm

    But can you explain what should i do?

  11. Gabriel on February 12th, 2008 8:03 pm

    And one more thing… Your RSS Feed contais errors… I can’t see it…

  12. Aaron on February 13th, 2008 5:31 pm

    $125 is good value, it would be cheap at twice the price. See how long it would take you to obfuscate your code thoroughly yourself.

    People are always mewling about wanting stuff for free, perhaps you’ll find a free software to go along with your free food, free car, free house.. You’ll find out when you leave highschool life doesn’t work like that.

  13. Luiz Fernando on February 13th, 2008 5:51 pm

    I have used it for a few SWFs and it work very nice!

    I may buy it as soon as posible!

  14. Experiment: monetizing a Flash game - Part 8 : Emanuele Feronato - italian geek and PROgrammer on March 4th, 2008 7:12 pm

    [...] (I’ll write a tutorial about it next days) and encrypt it with a software like Amayeta’s SWF Encrypt. The software costs $125, that’s less than 10% of a single interesting sponsorship, and you [...]

  15. Flasher on March 9th, 2008 8:47 pm

    I didn’t think that encryption was necessary until I visited a very nasty site where almost every game was ripped to some degree. From complete re-branding to the “more games” link.

    Since Boxhead Zombie Wars has been released, the new Amayeta with AS3 should be out soon. I doubt that it will be a free upgrade, so I think I’ll hold off on buying until it comes out. It better be backwards compatible, though.

  16. Tomo on March 25th, 2008 10:49 pm

    Flasher, what is the website’s name?

  17. fefe on April 1st, 2008 7:48 am

    Nice tutorial. But unfortunately, the tool doesn’t work for actionscript 3. But I just found another tool named ‘irrfuscator’, it works quite similar.

Leave a Reply