Thursday, April 5, 2012

Decrypting AS3 SWF's

Today, I found a massive flaw in Mochicrypt and probably all AS3 encryption methods. I'm sure others already know about it, but I'll post it anyway.
Firstly, let me start by explaining how these encryptions work:
The swf is encrypted and stored (generally in the decryptor/loader).
The encrypted swf is decrypted and turned into a byteArray
The decrypted byteArray is loaded using the Loader.loadBytes() method.
The Loader is added to the stage.

and, as it turns out, getting the unencrypted swf from the loader is incredibly easy.
there's this usefull as3 class called "LoaderInfo" that will solve all our problems.
in fact, Loader.contentLoaderInfo.bytes contains the byteArray for the loaded swf.
so, what we can do is load the decrypter, scan the stage's children for Loader objects, find the one for the decrypted swf and dump it's data.

Here's a working example I made for Bloons TD 5:
 package   
 {  
     import flash.display.*;  
     import flash.net.*;  
     import flash.events.*;  
     public class BTD5Decryptor extends MovieClip  
     {  
         private var ldr:Loader = new Loader();  
         private var swf:Object;  
         public function BTD5Decryptor()  
         {  
             ldr.load(new URLRequest("btd5.swf"));  
             ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);  
             addChild(ldr);  
             stage.addEventListener(KeyboardEvent.KEY_DOWN, doKeys);  
         }  
         private function onComplete(evt:Event):void  
         {  
             var ldrInfo:LoaderInfo = evt.target as LoaderInfo;  
             swf = ldrInfo.content;  
         }  
         private function doKeys(e:KeyboardEvent)  
         {  
             if (e.keyCode == 96)  
             {  
                 var file:FileReference = new FileReference();  
                 file.save((swf.getChildAt(1) as Loader).contentLoaderInfo.bytes,"unencrypted.swf");  
             }  
         }  
     }  
 }  

To use it, place the Bloons TD 5 swf in it's folder (make sure it's called "btd5.swf"), open the decrypter, wait for the game to load and then press numpad 0 to save the decrypted swf.

Here's a link to the compiled version of the decrypter (same as the code above):
http://www.mediafire.com/?lfk94ox5ge9i85k

Also note that the above code and decrypter may work on more/all mochicrypt swfs/loaders. I've only tested it on Bloons TD 5's mochicrypt loader as that's what it's made for, but it may very well work on all mochicrypt loaders.
*edit*
it only works on some, not all. I'll release a universal SWF decrypter I've made later today.

6 comments:

david thomas said...

haha, nice work :-)

Josh Wichman said...

Do you load them both at the same time in your web browser? How does it work?

bmanatee said...

The decryptor is run in flash player, which can be in browser or in the standalone player. It may need to have elevated permissions (run as a "trusted" SWF) if you're not running it in the flash debugger.
The BTD5 SWF needs to be in the same directory, and the decryptor should automatically load the game when it opens.

If you want a SWF decryptor that works on all encrypted SWFs, go grab my "Universal SWF Decryptor" from my downloads page.
The universal decryptor is a little buggy, but I'm going to be releasing a new bug-free version soon.

Do Van Long said...
This comment has been removed by the author.
Do Van Long said...
This comment has been removed by the author.
Do Van Long said...

Thanks a lot,man. you are great.