Protect your ActionScript code with SWF Protector
Posted on 22nd July 2010 in ActionScript, Developer tools | 3 Comments »
Even though the point of code obfuscation will always remain arguable, it may sometimes be a good idea to mess around a bit and make your ActionScript code harder to steal. The following review will highlight the features of SWF Protector, analyse the code and impact on SWF file size as well as performance.
Interface
The interface of SWF Protector is pretty straightforward and easy to follow:
It was a 1-second process for a 50 KB ActionScript 3 SWF. It also preserves your original SWF file renaming it to [yourSWFFilename]_original.swf.
Decompiling the protected SWF
To test the protection, 2 programs were used:
- Flash Decompiler Trillix
- Sothink SWF Decompiler
Allegedly, protectors have some built in functionality to crash the decompilers and that is exactly what happened in both scenarios:
Whilst Trillix’s decompiler crashed consistently, Sothink’s counterpart finally worked and made it possible to get some ActionScript out of the SWF.
Resulting ActionScript
Here’s the original ActionScript 3 file before protection:
package { import flash.display.StageQuality; import flash.events.Event; import nl.demonsters.debugger.MonsterDebugger; import org.papervision3d.view.BasicView; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.stats.StatsView; public class SWFProtectorTest extends BasicView { private var debugger:MonsterDebugger; private var pivotDO3D:DisplayObject3D; private var sphere:Sphere; private var stats:StatsView; public function SWFProtectorTest() { stage.frameRate = 40; stage.quality = StageQuality.BEST; init(); startRendering(); } private function init():void { debugger = new MonsterDebugger(this); pivotDO3D = new DisplayObject3D(); addSpheres(5); scene.addChild(pivotDO3D); stats = new StatsView(renderer); addChild(stats); MonsterDebugger.trace(this, "SWFProtectorTest initialised!"); } private function addSpheres(amount:int):void { while(amount--) { var radius:Number = 200 + 30 * amount; sphere = new Sphere(null, radius, 24, 24); pivotDO3D.addChild(sphere); } } override protected function onRenderTick(event:Event = null):void { pivotDO3D.localRotationY--; super.onRenderTick(); } } } |
and here’s the very same code after being protected and then decompiled by Sothink SWF Decompiler:
import SWFProtectorTest.*; import flash.display.*; import flash.events.*; import nl.demonsters.debugger.*; import org.papervision3d.objects.*; import org.papervision3d.objects.primitives.*; import org.papervision3d.view.*; import org.papervision3d.view.stats.*; package { import SWFProtectorTest.*; import flash.display.*; import flash.events.*; import nl.demonsters.debugger.*; import org.papervision3d.objects.*; import org.papervision3d.objects.primitives.*; import org.papervision3d.view.*; import org.papervision3d.view.stats.*; public class SWFProtectorTest extends BasicView { private var debugger:MonsterDebugger; private var pivotDO3D:DisplayObject3D; private var sphere:Sphere; private var stats:StatsView; public function SWFProtectorTest() { if (true){ // label } // label // Jump to 26; // label // Jump to 37; // label switch(-92) branch count is:<0>[-3] default offset is:< -8>; fewymrzygqh.ztg(this); stage.frameRate = 40; stage.quality = StageQuality.BEST; this.init(); startRendering(); return; } private function init() : void { // label if (true){ // label // Jump to 17; } else{ // Jump to 26; // label // Jump to 37; // label switch(-1) branch count is:<0>[-28] default offset is:< -8>; this.debugger = new MonsterDebugger(this); this.pivotDO3D = new DisplayObject3D(); this.addSpheres(5); scene.addChild(this.pivotDO3D); this.stats = new StatsView(renderer); addChild(this.stats); MonsterDebugger.trace(this, "SWFProtectorTest initialised!"); return; } } private function addSpheres(:int) : void { if (true){ // label // Jump to 16; } else{ // label // Jump to 26; // label // Jump to 40; // label switch(0) branch count is:<1>[-8, -13] default offset is:< -3>; var _loc_2:Number; while (--){ // label _loc_2 = 200 + 30 * ; this.sphere = new Sphere(null, _loc_2, 24, 24); this.pivotDO3D.addChild(this.sphere); } return; } } override protected function onRenderTick(:Event = null) : void { if (!true){ // label // label // label } // label // Jump to 27; // label // Jump to 38; // label switch(0) branch count is:<0>[-8] default offset is:< -3>; var _loc_2:* = this.pivotDO3D; _loc_2.localRotationY = this.pivotDO3D.localRotationY--; super.onRenderTick(); return; } } } |
So the 2nd codepiece is in a pretty bad shape. Anyone trying to make sense here should wonder if it’s worth it – a strong argument for using such obfuscation tools.
SWF file size
Obviously any such protection algorithm will have its impact on file size. The above ActionScript made a 78 KB SWF that went up to 115 KB with both protection and obfuscation applied to all classes incl. those of Papervision3D. That’s +47%.
Without Papervision3D protection it went up to 98 KB, +25%. Also, the fact that you may want to uncheck a library of a size of Papervision3D will set you unchecking each and every class in a library one by one. A serious usability setback that the makers of SWF Protector have missed entirely.
Performance
Measuring FPS and memory usage on a busy Papervision3D loop (as per above ActionScript) didn’t reveal any setbacks, StatsView was identical.
Even so, it’s always hard to cope with anything that is going to mess with your code. In fact, it’s the very reason to avoid obfuscation tools or any other tools in that matter.
SWF Protector business licence for one user is $59.95. Personal licence is $39.95.
Related resources and articles:







3 Responses
What is this software encryption code. I have never seen
function ()
{
\x01 = 2990 + 1481;
return (“\x01″ ? (null + (eval(“\x01″) + true)) : (null));
} // End of the function
var \x10!2 = \x10 ();
if (eval(“\x10!2″) == 54350)
{
} // end if
if (eval(“\x10!2″) == 45047)
{
} // end if
if (eval(“\x10!2″) == 4472)
{
} // end if
if (eval(“\x10!2″) == 31211)
{
} // end if
if (eval(“\x10!2″) == 36402)
{
} // end if
if (eval(“\x10!2″) == 20860)
{
} // end if
eval(“-\nL”)[""] = -UL.UL(eval(“)6″).UL / 2);
eval(“-\nL”).UL = -UL.UL(eval(“)6″).UL / 2);
I am flash developer i use Flash Secure Optimizer from http://www.eramsoft.com
By the way, Jonas. Why have you used “Flash Secure Optimizer” by eramsoft if there available FREE solutions from DComSoft software? here http://www.dcomsoft.com/
SWF Compressor-Decompressor
SWF Optimizer