CODE STAGE http://blog.codestage.ru DEVELOPMENT & RESEARCH Mon, 06 May 2013 14:53:16 +0000 en-US hourly 1 Advanced DoSWF encryption? Challenge accepted! http://blog.codestage.ru/2013/05/06/decrypting-doswf/ http://blog.codestage.ru/2013/05/06/decrypting-doswf/#comments Mon, 06 May 2013 14:53:16 +0000 focus http://blog.codestage.ru/?p=1046 Continue reading ]]> Greetings!
As I previously wrote about flash files unpacking, you can achieve that using static unpacking or dumping swf file from memory usually. There are some exceptions however, and I’ll tell you about one such exception in this article.

Developer of the DoSWF protector (made in China) used few simple yet interesting tricks to prevent revealing of the original SWF, I like something harder than clicking one button)
I guess many poor “hackers” (as they like to name themselves) have no idea why dumped files are not working, and can’t do anything about it.

Let me show you an example how to unpack SWF encrypted with DoSWF (many pictures ahead!)…
Let’s start from picking some nice SWF, like this demo of the Stardust particles engine for example:
Stardust

It can be decompiled easily:
Clean SWF

Now about DoSWF itself a bit. I used latest available ATM trial version (5.2.9) usually available online here: http://www.doswf.cn/swfencrypt/
Since we wish to know how to unpack (decrypt) protected SWF, we should use options from the Encrypt tab:
DoSWF Encrypt
I disabled all other options to keep this example clearer and let us focus on the unpacking.

We should have something similar to this after protected SWF decompilation:
DoSWF Loader

It looks standard for any kind of packed SWF file – we can see few classes for encrypted SWF decryption and loading. We can see embedded ByteArray or BitmapData nearby – that’s where encrypted SWF (or its parts ;) ) is stored usually.
I should mention not any decompiler capable of dealing with DoSWF obfuscation – some hang forever, some just crash while trying to read and decompile such messy bytecode. I strongly recommend to use Action Script Viewer (ASV) or AS3 Sorcerer for decompilation. These tools can save you a lot of time and usually capable to munch any kind of obfuscated bytecode – tools developer makes his work very well! Hey, Burak! xD

Protected SWF runs fine but we can see DoSWF logo watermark since we used trial version of the protector:
DoSWF Watermark
SWF opens DoSWF main site sometimes as well.

New we are about to try unpack this SWF and since we can play it we should be able to dump it.
You could use whatever tool you want for this or even make dumps by hands, but I’d suggest to use SWF Revealer Ultimate – advanced dumper / unpacker from the ASV author. Docs quote: “if you can view the SWF in the standalone player, you will be able to see it and reveal any and all of the data”.
BTW: SWFRUL makes his job different way comparing to usual SWF Revealer (tool for ASV). This tool is sold as limited edition – there are about 15 licenses worldwide available now in total so hurry if you’re interested in this tool!

SWFRUL reveals to SWF files in our target:
SWFRUL

Let’s get them out and look into them a bit.

We’ll not see working original SWF while trying to run these reveals SWFs. One will show us nothing, second one – buggy GUI of our original SWF. Okay, let’s dive a bit deeper and look what exactly happened to our original SWF.

After opening first SWF in the decompiler, we can see something similar to what we saw in original SWF:
Dumped SWF with code
First thing we could notice – absence of the document class. Something is really wrong here. Moreover, if we’ll try to look for any library items in this SWF we will fail! There is no any library at all!
Looks like in this SWF we have abc bytecode only… And we’ll confirm this after looking into the SWF with any inspector, like Adobe SWF Investigator for example – there is no any tags except the FileAttibutes, DoSWF and ShowFrame. That’s why we didn’t saw a document class – SWF should contain SymbolClass tag for that.
SWF with code tags

Now we can guess all other content of the original SWF is stored in the second revealed SWF especially counting we saw a buggy GUI of our original file there.
And this can be easily approved after looking into this SWF in the inspector:
Investigating second SWF
We can see here our original SymbolClass tag with document class specified (Symbol with zero refid) as well.

Looks like we should try to merge both revealed SWF files to restore the original one. And I’d like to suggest to move DoABC tag from first file to the second one. This can be achieves using different tools. I use old and good SWiX for tasks like this – it’s a useful XML-based SWF editor. You can open both files there and copy-past what you want from one file to another, that’s it. Okay, copy-pasting DoABC tag and saving result:
Editing SWF in SWiX

We’ll see something like this after running output file:
Corrupted SWF

Pretty scary show =) We can see numerous bugs in GUI, not working particles or any other functionality malfunction, a lot errors thrown by Debug Flash Player. From the other hand, we can see the DoSWF logo watermark and Stats working there! This is a good sign – DoABC tag is working as expected!

Now we should investigate why all this working so bad. Let’s decompile main class and look into its constructor code.
Decompiled corrupted SWF

Clever ASV replaced ugly obfuscated names with _SafeStr*. Since I didn’t use original SWF obfuscation we can easily distinguish original code from DoSWF added one – usually it’s somewhat harder to do this, but extra clarity is not an issue for this typical example.

So, we see suspicious method _SafeStr4() right in the beginning of the constructor code. And we can see strange empty _SafeStr3() as well (I guess it’s just a garbage).
If we’ll study the main class further we’ll see a lot of the extra code added by DoSWF, and looks like all it can be disabled just with removing _SafeStr4() call.
So let’s clean constructor’s code a bit. You can use any tools you prefer for this, I prefer RABCDAsm and any kind of GUI for it, like WinRABCDAsm.

Well, after disassembling the SWF we should find the main class constructor bytecode (Waypoints.class.asasm). Here it is:

     getlocal0
     pushscope

     getlocal0
     callpropvoid        QName(PackageNamespace(""), "@doswf__mnɿ"), 0

     findproperty        QName(PrivateNamespace(null, "Waypoints#0"), "matrix")
     findpropstrict      QName(PackageNamespace("flash.geom"), "Matrix")
     pushdouble          0.5
     pushbyte            0
     dup
     pushdouble          0.5
     constructprop       QName(PackageNamespace("flash.geom"), "Matrix"), 4
     initproperty        QName(PrivateNamespace(null, "Waypoints#0"), "matrix")

     getlocal0
     constructsuper      0

     findpropstrict      QName(PackageInternalNs(""), "__setProp_xml_btn_Scene1_XMLbtn_1")
     callpropvoid        QName(PackageInternalNs(""), "__setProp_xml_btn_Scene1_XMLbtn_1"), 0

     returnvoid

We can see the call of the @doswf__mnɿ (ASV renamed it to the _SafeStr4) method right at the beginning of the bytecode list.
Okay, let’s remove this call (I’ll not cover how to edit bytecode right way in this article, it’s simple enough – just read the specs – that’s all you need for this) and re-assemble the SWF file.
Run it and see almost nothing have changed except the DoSWF logo watermark is absent now ;)

So we still have buggy SWF and it still opens DoSWF site sometimes.
Let’s remove this noisy site opening code. The easiest way to find a place where it happens is to look for any navigateToURL () calls through the whole sources. And we can easily find it after such lookup – in my case there were not so many matches for this search and target code was found in the idv.cjcat.stardust.common.particles.Particle class. Please note it can be any other class in your case since placement of this code is selected randomly when DoSWF encrypts SWF file.
I noticed such ugly yet effective method for doswf.com link hiding there:

var _local2 = "ht" + "tp:/" + "/ww" + "w.d" + "osw" + "f.c" + "om";

Low compiler effectiveness makes this possible.

Okay, let’s look at the disasm listing of the “infected” class) We should search for any anomalies at the class static constructor since protector inlines his method there.

    getlocal0
    pushscope

    findpropstrict      Multiname("Particle", [PackageNamespace("idv.cjcat.stardust.common.particles")])
    getlex              QName(PackageNamespace(""), "Object")
    pushscope

    getlex              QName(PackageNamespace(""), "Object")
    newclass            "idv.cjcat.stardust.common.particles:Particle"
    popscope
    initproperty        QName(PackageNamespace("idv.cjcat.stardust.common.particles"), "Particle")

    newfunction         "idv.cjcat.stardust.common.particles:Particle.sinit/inline_method#0"
    pushnull
    call                0
    pop
    returnvoid

Gotcha! We can see the suspicious inline method call right at the end of the constructor. We can ensure this is a protector’s code just looking into inline_method#0 bytecode.
Removing this method call from static constructor, reassembling SWF file and voilà! Our restored SWF doesn’t open protector’s main site anymore.
As you could notice, we just removed all visible watermarks of the protector’s trial version ;) There are a lot of unused junk bytecode now in the SWF though so it’s easy to reveal we used trial protector’s version – we need to clean SWF further to remove any trial version signs, but this article is not about that.

Okay, we still have buggy SWF and looks like it’s time to look into errors Debugger Flash PLayer throws to us.
In my case first error stack trace ended with this:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at fl.core::UIComponent/setSize()
at …

Let’s inspect the fl.core::UIComponent/setSize() method to find what’s wrong there.
Here is a source code of this function

_width = _arg1;
_height = _arg2;
invalidate(InvalidationType.SIZE);
dispatchEvent(new ComponentEvent(ComponentEvent.RESIZE, false));

We have null object reference error so we should look for any possible null references there. Two first lines can’t harm us, but third have InvalidationType.SIZE constant usage. It could be null.
So let’s view the InvalidationType class source code:

    public class InvalidationType 
    {

        public static const ALL:String = "all";
        public static const SIZE:String = "size";
        public static const STYLES:String = "styles";
        public static const RENDERER_STYLES:String = "rendererStyles";
        public static const STATE:String = "state";
        public static const DATA:String = "data";
        public static const SCROLL:String = "scroll";
        public static const SELECTED:String = "selected";

        public function InvalidationType()
        {
            if (!ApplicationDomain.currentDomain.hasDefinition("Ȋ"))
            {
                return;
            };
            super();
        }

    }

    import flash.system.ApplicationDomain;

    if (!ApplicationDomain.currentDomain.hasDefinition("Ȋ"))
    {
        return;
    };

Aha! Looks like we just found the source of the null reference error! Protector added the simple definition (it can be any public class, function or namespace with specified name) existence check in both regular and static constructor. I guess this definition exists in the DoSWF loader, so checks works fine if this code is running in the loader’s domain. But we have no loader with such definition, so checks will not pass and all static variables will not be initialized! That’s why InvalidationType.SIZE is null.

Let’s inspect this checks in the disassembler. We’ll look into the static constructor bytecode since regular constructor is empty (excluding that check):

    getlocal0
    pushscope

    findpropstrict      Multiname("InvalidationType", [PackageNamespace("fl.core")])
    getlex              QName(PackageNamespace("flash.system"), "ApplicationDomain")
    getproperty         QName(PackageNamespace(""), "currentDomain")
    pushstring          "Ȋ"
    callproplex         QName(PackageNamespace(""), "hasDefinition"), 1
    iftrue              L9

    returnvoid

L9:
    getlex              QName(PackageNamespace(""), "Object")
    pushscope

    getlex              QName(PackageNamespace(""), "Object")
    newclass            "fl.core:InvalidationType"
    popscope
    initproperty        QName(PackageNamespace("fl.core"), "InvalidationType")

    returnvoid

We can clearly see the definition check right at the constructor’s bytecode start. Se as I said before – we will have static constants not initialized in case check will not pass.
Let’s remove this check, reassemble and run our SWF file. Well, debug Flash Player is not throwing this error anymore and we can see some visual changes in the SWF as well (at least semitransparent panel is absent now):
Fixed error

We can guess there are lot of such checks in the SWF – that’s why we see all this errors and broken SWF. So we could search for the ApplicationDomain.currentDomain usage through all sources or just create needed fake definition to let that checks pass normally ;)
But I like a clean code so my choice is a first approach which one can be easily automated BTW.
After processing SWF and removing all such checks we get the normally working SWF finally! Looks like there is no any other additional checks there.

Let me warn you protector adds this checks to the randomly selected classes, so every single protected file is unique but common check removing tactics is still the same.

As you can see yourself even such tricky hacks as separating SWF and loading them into the same domain, inlining different checks and watermarks can’t guarantee SWF will not be revealed and restored. The only one real thing is the names obfuscation – I think it’s pretty enough in most cases since original names can’t be restored anymore automatically, only manually by reverse-engineer guessing what names were before obfuscation.
If you have anything to add here or you have any questions – you’re welcome, just leave your comment here! Any comments are welcome at all actually)

And yeah, almost forgot – with the last Easter! ;)

]]>
http://blog.codestage.ru/2013/05/06/decrypting-doswf/feed/ 4
Unity3D threads – measuring performance http://blog.codestage.ru/2013/03/27/unity3d-threads/ http://blog.codestage.ru/2013/03/27/unity3d-threads/#comments Wed, 27 Mar 2013 00:42:53 +0000 focus http://blog.codestage.ru/?p=947 Continue reading ]]> Hey everybody!
Sometimes people ask me about delayed actions or threading in Unity3D and usually I suggest to use coroutines since they are suitable for the most cases I faced with.
But sometimes we need to use true threading and make some calculations faster, A* path finding for example.
So I decided to make a fast-written performance comparison of traditional code execution vs. threaded version. I searched for some simple threads managers and found this really simple Loom class from whydoidoit accidentally.

I did a simple test app for different platforms (I attached archive with apps and sources at the end of this post) and found some results pretty interesting.
All my code is trying to do – is just to make CPU think a little while working with huge array of Vector3D instances (10 000 000 for Desktop platforms and 1 000 000 for mobile platforms):

private void Run()
{
	const float scale = 432.654f;

	for (int j = 0; j < arrayLength; j++)
	{
		Vector3 v = vertices[j];

		v = Vector3.Lerp(v * scale / 123f * v.magnitude, v / scale * 0.0123f * v.magnitude, v.magnitude);

		vertices[j] = v;
	}
}

This is a simple dummy code as you can see.
I added simple Ant model (hello, Away3D examples authors! :) ) with rotation at Update() to the scene in order to see how app can freeze while running this ugly code in main thread.

JTMLjQ0

I did few tests of this code as I mentioned previously, both in sync (straight execution in main thread) and async (running it the separate threads) modes, here are results I’ve got (S – sync, A – async):

PC (Intel Core i7 2600K 4.6Ghz, 4-core + Hyper Threading)

Standalone PC build (Fastest quality, 1024×768 windowed)
S: 920.8 ms
A: 198.2 ms (8 threads, x4.64)

WebPlayer build (Chrome 25.0.1364.172, Unity WebPlayer Release Channel Plugin v. 4.1.1f)
S: 938.1 ms
A: 200.4 ms (8 threads, x4.68)

PC (Intel Core i7 Q740 1.73Ghz, 4-core + Hyper Threading)

Standalone PC build (Fastest quality, 1024×768 windowed)
S: 1732.1 ms
A: 584.4 ms (8 threads, x2.96)

WebPlayer build (Chrome 25.0.1364.172, Unity WebPlayer Release Channel Plugin v. 4.1.1f)
S: 1780.0 ms
A: 555.3 ms (8 threads, x3.21)

PC (Intel Atom N455 1.66GHz 1-Core + Hyper Threading)

Standalone PC build (Fastest quality, 1024×600 windowed)
S: 7835.3 ms
A: 6533.9 ms (2 threads, x1.20)

WebPlayer build (Chrome 25.0.1364.172, Unity WebPlayer Release Channel Plugin v. 4.1.1f)
S: 7701.6 ms
A: 6778.3 ms (2 threads, x1.14)

Mobile

Galaxy Tab 10.1 (1.4GHz OC 2-core CPU, Tegra 2, Android 4.0.4, GT-P7510)
S: 1479.0 ms
A: 831.1 ms (2 threads, x1.78)

iPad 1 (1Ghz 1-core CPU)
S: 5364.0 ms
A: 6865.7 ms (1 thread, x0.78)

Pretty cool, huh? We have significant performance improvements (up to x4.68!) on the CPUs with 2 cores and more and overall performance improvement except the iPad1 test.
All tests in async mode on all tested platforms prevented app from freezing so we could see smoothly (or not, like in case of Atom) rotated mesh while our dummy code were executed in the separate thread(s). Expected, but very pleasantly!

Take a look at the two different generations of the Inter Core i7 CPUs – both have 4 cores + HT, but newer generation (2600K) allows using threads much more efficiently.
Tests on Intel Atom with 1 core + HT CPU were interesting – we run total 3 threads (1 main and 2 child dummy threads) there and we got small speed boost even with 1 core CPU. Looks like HT helped us there, nice!
I also noticed overall FPS dropped significantly on Atom still allowing interacting with app though.

Mobile tests are quite interesting as well.
Galaxy Tab 10.1 showed itself much faster in this tests comparing to the iPad. I guess 1.4GHz OC helped here though =P
iPad1 have 1 core CPU so it can’t handle 2 threads natively – that’s why we see running our code in separate thread is slower here. Actually we make CPU to work with 2 synthetic threads switching from one to another – from main, with our scene and rotating mesh to the child one – with our dummy calculations. Async code execution prevents app from freezing though, in some cases it would be more necessary than higher performance, you know (that’s where the Coroutines are usually can help BTW).

And we can see threading in Unity3D works on mobile devices like a charm, cool!

Let’s take a look at the overall timings comparison:

chart1
Not so huge overall difference… But with async code execution we have freeze-free apps on all platforms with a little performance boost, not so bad!

And to the 2+ cores CPU only selection:
chart2

Whoa! We see great performance leap here for the async code execution scheme. We definitely should use threads in the CPU-intensive algorithms to avoid app freezing and perform better on the 2+ core CPU configurations.

So if your

SystemInfo.processorCount

will return 2 or more – it’s a definitely way to go with async implementation of your CPU-intensive algorithms.

You could notice I didn’t tested threads in the Unity3D exported SWFs. The simple reason for this – Threading is not supported (yet?) by the Flash Exporter. I guess it’s a pretty complicated task since the only way to implement true threading in Flash is Workers usage. But workers approach differs from the Threading in .NET too much from my point so I guess we will see threads in Flash Exporter supported features list not so soon if ever.

Don’t forget additional threads will use multicore mobile devices batteries much more intensively leading to the short battery life – be careful with threads on mobile!
And as DbIMok commented in the Russian blog pos version: keep in mind – true threads can’t work with Unity3D engine objects (there are some exceptions though, like Debug.Log()), but coroutines can because they are utilising the “Green threads” concept – run code in chunks (every “frame”) within main thread.

I think that’s all for now, you could grab archive with sources and compiled app here (~27MB).
This is a LZMA2 compressed 7-zip archive. Use 7-zip 9.x or similar to unpack.

PS: And I’d be glad to hear from you any thoughts on this topic as well as any tests results on your hardware and devices!

]]>
http://blog.codestage.ru/2013/03/27/unity3d-threads/feed/ 6
AIR vs. Unity3D. Who’s faster? (Update 1) http://blog.codestage.ru/2013/03/20/air-vs-unity3d/ http://blog.codestage.ru/2013/03/20/air-vs-unity3d/#comments Wed, 20 Mar 2013 19:16:07 +0000 focus http://blog.codestage.ru/?p=928 Continue reading ]]> Update 1: uploaded some sources (look at the end of article).

Hey there!
Yeah, it’s been a while blahblahblah.. To the point! =)

Sometimes I’ll highlight actual files from the archive, attached at the page bottom.

Sometimes I see Flash developers interested in the Unity3D lately, and I – one of them actually)
I work with Unity for a while already and all I can say – it’s fantastic experience! So cool to learn C# language (I hope other Flash devs make wise decision to code in C# as well), to learn new community and people, to meet a lot of new challenges and to look at 3D world from a new point at all!

Many Flash developers are still uncertain they should try Unity and spend their time learning this brand new world though.. And in some cases it’s built on top of the AIR and Unity3D performance differences obscurity. So I’ll unveil portion of this differences in this article to help those Flash developers make a choice (whatever what they choose)!

All examples I’ll compile with AIR 3.6 and Unity3D 4.1 and I’ll try to keep similar functionality and look of these examples to let them compete.
I’ll test builds on the pretty slow Samsung Galaxy Tab 10.1 and make some tests on the desktop as well.

Intro

Okay, let’s start from comparing empty builds.
To measure FPS in unity3D I’ll use hand-made FPSmeter working with GUIText.
In AIR builds I’ll use different FPSmeters, usually in-built to the frameworks I’ll use.
Well, let’s see to the built apks (I built Captive Runtime in AIR and usual release build in Unity3D):

FPS: I see stable 60 on the mobile device (Galaxy Tab 10.1 resolution – 1280×800).
RAM: I can’t measure total ram used in AIR (including runtime) from the AIR itself using standard APIs AFAIR (let me know if I’m wrong here please); I can use Profiler class in Unity3D for this purposes. Yeah, I could use some external profiler for AIR, but since profilers overhead will be different it will decrease overall accuracy, so I’ll skip RAM measurements at all.
Files size:
AIR – 9223 kb
Unity3D – 7406 kb
If I’ll use “Strip Bytecode” Stripping Level in Unity3D, I’ll get 6946 kb build size. Pretty nice, counting we have Unity3D player there!

Code execution performance

Fine, let’s add TextField to the Stage in AIR and OnGUI label in Unity3D to output there our code execution time.
Let’s start from the arrays creation and filling with random numbers.
I’ll use fixed typed Vector in AIR since it’s a fastest standard array there.
And I’ll compare it with standard typed array in C# – it’s a fastest available there too.

AS3 code:

private const VECTOR_LENGTH:int = 100000;
//...
private function callFewTests():void
{
	var timeBegin:int = getTimer();
	for (var i:int = 0; i < 100; i++)
	{
		makeACake();
	}
	outputTextField.text = String(getTimer() - timeBegin) + " ms";
}

private function makeACake():void
{
	var v:Vector.<int> = new Vector.<int>(VECTOR_LENGTH, true);

	for (var i:int = 0; i < VECTOR_LENGTH; i++)
	{
		v[i] = int(Math.random());
	} 
}

C# code:

 
private const int ARRAY_LENGTH = 100000;
private float totalTime = 0;

void Start ()
{
 	CallFewTests();
}

void OnGUI()
{
 	if (totalTime > 0)
	{
		GUILayout.Label(totalTime.ToString("0."));
	}
}

private void CallFewTests()
{
	float timeBegin = Time.realtimeSinceStartup;

	for (int i = 0; i < 100; i++)
	{
		MakeACake();
	}

	totalTime = (Time.realtimeSinceStartup - timeBegin)*1000;
}

private void MakeACake()
{
	int[] a = new int[ARRAY_LENGTH];

	for (int i = 0; i < ARRAY_LENGTH; i++)
	{
		a[i] = (int)Random.value;
	}
}

As you can see I have two for loops there. First calls method with second 100 times. Second one fills an array with the 100000 random ints. Built-in random generators used in both AIR and Unity3D.
After APK installation I launched test apps few times and got these average results:

AIR – 1965 ms
Unity3D – 1600 ms

We see almost same results here, Unity3D code runs a bit faster.
Let’s try to remove random generation to exclude built-in random generators speed differences from the test. I replaced it with this simple method:

private int GetTotalGeeksCount()
{
	int a = 23;
	int b = 41;
	return a + b;
}

I looked into both AS3 and C# compiled code to ensure compilers didn’t optimize these simple expressions. After I uploaded APKs to the Galaxy Tab, this is a result:

AIR – 837 ms
Unity3D – 224 ms

This time we see a pretty big difference here – Unity3D faster than AIR more than 3 times! I think this difference is important counting we measured very simple code usually presents in every game or application.

Try to compare yourself, maybe you’ll get another results (I’ll be glad to know about them) – look at the files from archive:
Random*, Clean*

Okay, what if we’ll use Flash exporter in Unity3D and look how exported SWF can compete with SWF created traditional way in the desktop Flash Player projector?
Let’s increase iterations count to 1 000 000, export form Unity3D (for Flash Player 11.4) and recompile AIR app. After launching resulting swfs in FP Projector 11.6 I saw this results:

AIR – 573 ms
Unity3D – 2580 ms (!)

BTW I found a nice bug while exporting SWF from Unity – myFloat.ToString(“0″); stops code execution in current method. It’s weird exporter can handle pretty big projects, but fails on 1 simple code line haha.

So we can see this code takes much more time in Unity3D exported SWF compared to the usual SWF.
If we started to compare desktop performance, why not to try usual Unity3D desktop builds? I mean WebPlayer and standalone for PC.
Unity3D WebPlayer vs SWF in FP Projector:

AIR – 573 ms (measured in previous test)
Unity3D – 102 ms

Unity3D is faster more than 5 times. Not bad!
Now let’s try usual Unity3D standalone (PC) builds:

x86 – 103 ms
x64 – 124 ms

Looks like it’s almost same as in WebPlayer, good. One interesting observation – x64 build works a little bit slower than x86 one.

Moving next – let’s remove all array-related code from our tests, leaving only pure for loops and methods calls. Results on Galaxy Tab:

AIR – 4181 ms (http://pastebin.com/yNr3aVyc)
Unity3D – 281 ms (http://pastebin.com/btz405XS)

I tried to compile AIR test using ASC2 compiler with hope to see significant speed increasing, but result was 3991 ms, not so much =(

Well, looking at the tests results I can say AS3 code speed is still an Achilles heel of AIR, like as some years ago. I hope this will change in future though.
Unity3D Calculations*, Simple Code*

2D

Render time! Let’s start from 2D with simple test – 3000 small rotating quads.
I use Starling for AIR test (yes, I know about other fast 2D frameworks for AIR, this one is most popular and supported by Adobe though).
Also I use 16 bit colorDepth and Starling’s built-in FPSmeter.

I made orthographic camera in Unity3D with Solid Color clear flag.
Also I’ll use simple hand-made RGB color shader.
And I disabled Use 32-bit Display Buffer, Use 24-bit Depth Buffer in the Player Settings.

eAhNVDy

Building, uploading to device.. Results, FPS:
AIR – 32
Unity3D – 20

We got pretty interesting, but expectable results. Unity3D uses 3 dimensions to manipulate objects and calculate things, Starling uses and optimized for 2D only calculations. This is a one of the reasons why Starling faster in 2D mode now. Did you know Unity3D team is working on adding special 2D mode? ;)
Quads*

Now let’s use a texture with alpha on this quads, reduce quads count to 1000 and add some movement.
I got a texture form the Bohan Valera’s Starling Benchmark open source app (Hey, Valera! =) ).
And I used RGBA DXT5 texture compression in Unity since my Galaxy built on top of the Tegra 2 and DXT5 is a best one available for Tegra.

cA6t0eU

Building, uploading to device.. Results, FPS:
AIR – 43
Unity3D – 47

Here we see a bit different results comparing to the previous test. I guess Unity3D is faster here because of DXT5 texture compression suitable for Tegra devices only. If I use more universal RGBA32 compression which gives similar to the AIR’s texture quality, I have only 30 FPS. From the other side, I have no not-tegra Android device to try other compression methods. Anyway Google Play supports different builds of the app – with different textures compression methods for example.
Texture*

Overall tests results let me say AIR is faster than Unity in 2D only mode now. I hope brand new Unity’s 2D mode will let Unity3D to compete with AIR’s 2D frameworks more natural way.
BTW we can see here the true power of low-level Stage3D API (all AIR’s GPU-accelerated 2D frameworks are built on top of the Stage3D)! 2D frameworks developers can focus on the only features they need, optimizing performance and making frameworks lighter – very flexible approach.

3D

Enough 2D, let’s dig into the 3D!
Aaand, we’ll start from the simple standard “bunch of cubes” test)
Let’s make small 1000 cubes to avoid fillRate issues and use most simple color shader we have.
I’ll use Away3D (4.1.0 Alpha src from dev branch) in AIR build for the same reason I used Starling previously.

fskxVfR

Building, uploading to device.. Results, FPS:
AIR – 10
Unity3D – 49

This is a total Unity3D win! I double-checked I have release AIR build. Here is a test source code for you to check if I forgot something: http://pastebin.com/iNzPZTnM
Simple Cubes*

Okay, new is time to make test a bit harder. Let’s take a high poly (17k+) 3ds model, add it 10 times, add 1 Directional Light, change shader.
In Unity I used standard not optimized Specular shader. Total triangles on scene: 173840.

gzCy14h

Building, uploading to device.. Results, FPS:
AIR – 27
Unity3D – 51

Expected results here!
Lighting*

PS

What can I say after all this tests? I’d like to say Unity3D combines high performance, flexible and robust IDE, support for wide range of platforms and nice C# programming language. And this is a really powerful combination!
So if you are the Flash (AIR) game developer and you’re looking some alternative migrate to, I’d suggest you to try the Unity3D first!
BTW I used not all possible optimizations while creating these test cases to keep all workflow simple, with default approach since my goal was to try both platforms in similar way, with similar code and with only some common optimizations.
Also it was a long time ago when I used Away3D last time so I could miss something important in my code. Let me know if you’ll find some critic performance issues in my code – I’ll re-write it and update test results then!

I’ll be glad to hear from you something about AIR vs Unity3D performance comparison!

Archive with all APKs I tested:
AIRvsUnity3D.7z (38 MB)
It’s a standard LZMA2 compressed one (use 7-zip 9 or newer to unpack)

Update 1:
Archive with Unity3D sources:
UnityPerformanceTest.7z (750 KB, LZMA2)
It’s a Unity3D 4.1 project. You can find 3 scenes there with 1 test from each article charpter.


All examples were tested on the 1280×800 (landscape) Tegra 2 device (Samsung Galaxy Tab 10.1) running on Android OS 4.0.4. Correct examples execution is not guaranteed on any other devices.

]]>
http://blog.codestage.ru/2013/03/20/air-vs-unity3d/feed/ 16
SWF rebuilding with as3swf code library http://blog.codestage.ru/2012/07/12/as3swf-code-library/ http://blog.codestage.ru/2012/07/12/as3swf-code-library/#comments Thu, 12 Jul 2012 01:48:25 +0000 focus http://blog.codestage.ru/?p=872 Continue reading ]]> Hey!
It’s been too long since we’ve had a good bandit raid topical content here. I’m going to fix it!)

Today we’ll speak about SWF changing using as3swf code library, as you could already guess from this post topic.

Let me introduce this library first.
It was designed to parse, modify, and create SWF files on the fly. You could get all the tags and SWF properties (frameRate, version, etc.) after ByteArray with target SWF parsing. The good thing is that with as3swf you’re free to modify any SWF tags and properties and it is able to save all changes you did! It could even allow you to create a new SWF file from scratch.
as3swf is available for your experiments at github: https://github.com/claus/as3swf

Library is pretty alive and have a good communicative author (Claus Wahlers), so feel free to make Pull requests ;)
BTW, he applied my LZMA compression (more on LZMA – here) support pull request yesterday.
You should wait for the Flash Player 11.4 release to try as3swf with LZMA-compressed SWFs though.

One thing as3swf could not provide is a DoABC Tag ABC parsing.
Author started so library project some time ago, but abandoned it, thus it is no longer supported or actual.

I should agree with Claus though since a great ABC parsing and creating on the fly library as3commons bytecode already exists and have updates periodically: http://as3-commons.googlecode.com/svn/trunk/as3-commons-bytecode/changelog.txt
I’ve used it some time ago and was really happy with it. But this is another case…

I’ll shed a bit of light on my as3swf using purposes: I had a task to replace one SWF tag with completely new data, it was the DefineBinaryData tag to be clearer.

This is how looks SWF parsing code:

var swf:SWF = new SWF(swfByteArray);

swfByteArray is a ByteArray with our SWF.
Really simple one, ah?

So, after SWF parsing I had to replace embedded into the SWF file with this Flex Embed tag:

[Embed(source="./data.dat", mimeType="application/octet-stream")]
private var EmbeddedDataClass:Class;

When some content is being embedded this way, the resulting SWF obtains some special data you should know to replace embedded file.

First of all, a new DefineBinaryData tag appears with it’s unique Symbol ID.
In addition using Embed tag leads to the new AS3 class creation with name = ClassName_VariableName and extending the mx.core.ByteArrayAsset class.
If we’ll imagine we’ve used Embed in the MySuperClass class inside of the ru.codestage package, we’ll have a class with ru.codestage.MySuperClass_EmbeddedDataClass name.
At least, SybmolClass tag containing Symbol IDs linked to their AS3 Classes appears or supplements. BTW, new records also appears in the SybmolClass tag when you’re using class linkage functionality in the Flash Pro.

Knowing all this neat stuff we could easily find and deal with needed DefineBinaryData tag without risk to damage source SWF!

So, how to make it using as3swf:

var newSWFByteArray:ByteArray = new ByteArray();

// this line should be familiar to you already
var swf:SWF = new SWF(swfByteArray);

var symbolClass:TagSymbolClass;
var defineBinaryData:TagDefineBinaryData;

// looping through all the SWF tags ...
var leni:uint = swf.tags.length;
var i:uint;

outerLoop: for (i = 0; i < leni; i++ )
{
	// ... and looking for the SymbolClass tag
	if (swf.tags[i].type == TagSymbolClass.TYPE)
	{
		symbolClass = (swf.tags[i] as TagSymbolClass);

		// when SymbolClass tag is found we could start
		// to loop through all its symbols
		var lenj:uint = symbolClass.symbols.length;
		var j:uint;
		
		for (j = 0; j < lenj; j++ )
		{
			// looking for the symbol record with needed name
			var symbol:SWFSymbol = symbolClass.symbols[j];
			if (symbol.name == "ru.codestage.MySuperClass_EmbeddedDataClass")
			{
				// as we encounter needed symbol record, we could get its ID using symbol.tagId field
				// and get a needed Symbol with the same ID from the SWF using swf.getCharacter() method
				defineBinaryData = (swf.getCharacter(symbol.tagId) as TagDefineBinaryData);
				break outerLoop;
			}
		}
	}
}

// if we got something valuable with swf.getCharacter(),
// we could start to replace its data
if (defineBinaryData)
{
	defineBinaryData.binaryData.clear();
	defineBinaryData.binaryData.writeUTFBytes(_dataString);

	// and save results into ByteArray
	swf.publish(newSWFByteArray);
	trace("Done!");
}
else
{
	trace("[ERROR] No ru.codestage.MySuperClass_EmbeddedDataClass symbol found!");
}

I’m sure this code is pretty simple and easy to understand.
So, as you can see, as3swf is a really powerful (note that I showed just small part of all its functionality), flexible and easy to use code library, use it with fun!)

Recently I’ve used it in my small Site Locking tool I wrote for one day (most of time I’d polished GUI though :D )

If you have any questions, notes, suggestions or anything else to say – you’re welcome, just leave a comment here – I’ll read it, I promise!)

]]>
http://blog.codestage.ru/2012/07/12/as3swf-code-library/feed/ 4
Flash GAMM Moscow 2012 http://blog.codestage.ru/2012/06/24/flash-gamm-moscow/ http://blog.codestage.ru/2012/06/24/flash-gamm-moscow/#comments Sun, 24 Jun 2012 15:08:38 +0000 focus http://blog.codestage.ru/?p=865 Continue reading ]]> Hey guys!

I just posted my FlashGAMM Moscow 2012 report in the Russian blog section:
http://blog.codestage.ru/ru/2012/06/24/flash-gamm-moscow/

Since it’s a commonly Russian event, I did no English translation, you could look at my slides (they have English translation) about Flash Console, TheMiner, XFLTool and slide “engine” sources though.
You even can use Google Translate if you really wish to read my report)

]]>
http://blog.codestage.ru/2012/06/24/flash-gamm-moscow/feed/ 0
Going to FlashGAMM Moscow 2012 http://blog.codestage.ru/2012/05/15/going-to-flashgamm-moscow-2012/ http://blog.codestage.ru/2012/05/15/going-to-flashgamm-moscow-2012/#comments Mon, 14 May 2012 21:23:43 +0000 focus http://blog.codestage.ru/?p=845 Continue reading ]]>

Hey, friends!
I’m preparing to the short trip to Moscow with very short blitz session on FlashGAMM.
I’ll speak about few advanced debugging and optimization tools.
I wrote few simple effects using Nape and Genome2D especially for my presentation, it was much more fun creating this effects then preparing the slides)
Blitz sessions section will start at 12:00 (Moscow time) in the “Saturn” hall.

If you will be at Moscow May 16-19 and wish to meet me – feel free to drop me few lines!

I’ll post my slides along with conference report here in the next few weeks, so you will be able to play with effects and see their sources!

Bye!

]]>
http://blog.codestage.ru/2012/05/15/going-to-flashgamm-moscow-2012/feed/ 0
Flash Player roadmap updated – cool features are coming! http://blog.codestage.ru/2012/03/28/flash-player-roadmap-updated/ http://blog.codestage.ru/2012/03/28/flash-player-roadmap-updated/#comments Wed, 28 Mar 2012 10:57:07 +0000 focus http://blog.codestage.ru/?p=834 Continue reading ]]> Hey again!
Along with releasing Flash Player 11.2 / AIR 11.2 and publishing information about premium futures, Adobe updated their roadmap for the Flash runtimes today and revealed many awesome features coming to us this year!

Just look at this quick copy-paste:

Flash Player “Cyril”
Following the Flash Player 11.2 release, Adobe plans to do another release, code-named “Cyril”, which is targeted for a release in the second quarter of 2012.

Some of the features being planned:

  • Keyboard input support in full-screen mode
  • Improved audio support for working with low-latency audio
  • Ability to progressively stream textures for Stage 3D content
  • LZMA compression support for ByteArray
  • Frame label events
  • Support for compressing BitmapData to JPEG and PNG formats
  • Support for Mac OS X App Store application sandboxing requirements

Awesome, isn’t it?

Flash Player “Dolores”
Adobe is planning an additional Flash Player release in the second half of 2012. Code-named “Dolores”.

Some of the features being planned:

  • ActionScript workers (enables concurrent ActionScript execution on separate threads)
  • Support for advanced profiling
  • Support for more hardware-accelerated video cards (from 2005/2006) in order to expand availability of hardware accelerated content
  • Improved ActionScript performance when targeting Apple iOS
  • Performance index API to inform about performance capabilities of current environment
  • Release outside mouse event API
  • ActionScript 3 APIs to access the fast-memory opcodes (premium feature when used in conjunction with Stage3D APIs)

Even more awesome!
Flash is going to rock this year (again)!

Roadmap link: http://www.adobe.com/devnet/flashplatform/whitepapers/roadmap.html

]]>
http://blog.codestage.ru/2012/03/28/flash-player-roadmap-updated/feed/ 0
Brief comparison of three Stage3D 2D frameworks *Update 1* http://blog.codestage.ru/2012/03/26/comparison-stage3d-2d-frameworks/ http://blog.codestage.ru/2012/03/26/comparison-stage3d-2d-frameworks/#comments Mon, 26 Mar 2012 08:15:42 +0000 focus http://blog.codestage.ru/?p=819 Continue reading ]]> Hey, friends!

I’d like to show you some fast results of benchmarking briefly three most popular Stage3D frameworks for the 2D rendering:
Starling, ND2D, Genome2D.

I got latest available builds (and sources) of those frameworks and written a simple AIR app with some amount of images moving, rotating, scaling, and changing alpha on every frame.
Images were placed across whole stage within several iterations (adding fixed images amount on every frame until we reach fixed maximum).
All images had the same texture – small 25 by 25 box with a bit of alpha channel.
I tested that app on my PC and on two mobile devices – iPad1 with iOS 5.0.1 and GalaxyTab 10.1 with Android 3.1.

So, this is a results I got:

Starling from GitHub Commit:9aa93a8195c47252253fd4d2b671115e19d16b6f, 24.03.2012:

iPad 1:
1350 images at 30 FPS
RAM: 6.4 MB

GalaxyTab 10.1 (OC 1.4GHz):
1350 images at 30 FPS
RAM: 6.2 MB

PC (i7 4.8 GHz, Radeon 6790):
10000 images at 30 FPS
RAM: 19.7 MB
RAM with 1000 images: 9.1 MB

Starling is a really nice open source framework. It mimics classic DisplayList, have a huge community (thanks to Adobe) and very detailed API reference. Thus it’s really easy to learn and contribute.

ND2D from GitHub Commit:453531f7aee46b00a112c6f0d5d8b46d62075287, 05.03.2012:

This framework has two different “modes” for the effective massive sprites rendering – using Sprite2DCloud or Sprite2DBatch as Sprites container. I tested both.

Sprite2DCloud:

iPad 1:
~1150 images at 30 FPS
RAM: 6.4 MB

GalaxyTab 10.1 (OC 1.4GHz):
~1150 images at 30 FPS
RAM: 6.2 MB

PC (i7 4.8 GHz, Radeon 6790):
16000 images at 30 FPS with drop to 16 FPS while adding images (100 images per frame), you’ll be fine adding all images from the start
RAM: 37 MB
RAM with 1000 images: 9.5 MB

Sprite2DBatch:

iPad 1:
~1150 images at 30 FPS
RAM: 6.6 MB

GalaxyTab 10.1 (OC 1.4GHz):
~1150 images at 30 FPS
RAM: 6.1 MB

PC (i7 4.8 GHz, Radeon 6790):
10800 images at 30 FPS
RAM: 23.2 MB
RAM with 1000 images: 9.1 MB

ND2D is another nice open source framework we have to render 2D using Stage3D. It have big community (smaller than Starling though), pretty raw API reference (with most of all methods and properties without any description) and it comparable in terms of performance to Starling.
It also easy to understand and use because it is similar to the native DisplayList we have in Flash and there are many examples and information on forums about different use scenarios.

Genome2D Nightly 0.9.0.1093:

This is a surprising framework. Just look at the benchmark results below!

iPad 1:
1900 images at 30 FPS
RAM: 6.5 MB

GalaxyTab 10.1 (OC 1.4GHz):
3800 images at 30 FPS
RAM: 10 MB

PC (i7 4.8 GHz, Radeon 6790):
~40000 images at 30 FPS
RAM: 68.7 MB
RAM with 1000 images: 9.1 MB

It’s a really hardcore framework! It have awesome performance, but no API reference, small community, and no examples for the latest nightly builds (at this moment, latest nightly build is far away from the latest stable build).
It’s could be pretty tricky to use it for the beginner.

So, what we have now for creating 2D content using Stage3D:
Starling – the sweetest one. In some tests slower than ND2D though.
ND2D – compromise – could be faster than Starling in some cases but looks not so sweet at least because of weak API reference (so far) =)
Genome2D – for the maximum performance in some cases (like mine) and mostly for the hardcore devs with ninjaneering skills) I hope it will became more friendly in future.

I think all three frameworks are comparable on features – all have the particle systems, blending, and other advanced features. And all three are under active development so new features are come continuously.
Also I should mention iPad and GalaxyTab 10.1 overclocked to 1.4 were head-to-head in Starling and ND2D in this benchmark. I guess it could happen because of the different screen resolutions and probably compensating each other HW and SW differences.
So for now if you wish to port some of your not hardcore (in resources consumption) game to the Stage3D with comfort, feel free to choice Starling. If you wish to have as much performance as possible (and if you’re ready to have a great adventure) – try Genome2D. Choose ND2D in the middle case.

Feel free to grab all Android benchmarks (and AIR 3.2 p6 Runtimes for Android) as bonus here:
http://codestage.ru/files/flood/android/benchmark.zip

If you think I could make a mistake in my tests – please, write me – I’ll be glad to know about and fix it!

*Update 1*

Recently I updated starling-imagebatch Starling extension by Philippe to keep it synced with latest Starling changes and perfomed this benchmark using it!

So, results are:

iPad 1:
2000 images at 30 FPS
RAM: 6.4 MB

GalaxyTab 10.1 (OC 1.4GHz):
2000 images at 30 FPS
RAM: 5.1 MB

PC (i7 4.8 GHz, Radeon 6790):
>16000 images at rapid 60 FPS (can’t set more images because of full buffer capacity)
RAM: 14.9 MB
RAM with 1000 images: 8.4 MB

Memory exploding bug

While I worked with the ImageBatch I found one memory exploding bug occasionally.
It’s very weird and I’m not sure where its roots are growing at this moment.

Please, look at this really often called piece of code:

var k:Number = (premultipliedAlpha ? item.alpha : 1) / 255;

and at this 2 lines of code:

var k:Number = premultipliedAlpha ? item.alpha : 1;
k /= 255;

There is not so much difference, yeah?
But first line explodes RAM with speed about 5 MB per second!
And second code block not explode RAM at all and work just fine!

]]>
http://blog.codestage.ru/2012/03/26/comparison-stage3d-2d-frameworks/feed/ 17
TheMiner and FlashDevelop http://blog.codestage.ru/2012/03/22/theminer-and-flashdevelop/ http://blog.codestage.ru/2012/03/22/theminer-and-flashdevelop/#comments Thu, 22 Mar 2012 10:53:10 +0000 focus http://blog.codestage.ru/?p=792 Continue reading ]]> This tutorial assumes you’re familiar with both TheMiner (awesome Flash profiler) and FlashDevelop (best and free Action Script / haXe code writing IDE) and wish to use them in conjunction with each other.

There are two common ways using TheMiner in the FlashDevelop:

- Using TheMiner as SWC, like any other external library.
- Adding TheMiner’s swf to the FlashDevelop profilers list.

Why always not to use only one way? Because both have their pros and cons.
So, let’s try out both ways step-by-step. Please, start the FlashDevelop and create or open the as3 project to proceed further.

TheMiner as external SWC

1. First of all, purchase TheMiner or download a free version for the non-commercial usage.

2. Unpack given archive, go into the “SWCs” folder and select desired SWC with translation you prefer, as example, select the TheMiner_en.swc

If you’re familiar with SWC using in FlashDevelop, skip next two paragraphs of this tutorial and go right to the par. 5.

3. Copy-paste selected swc in the “lib” folder of your project (or in any other location in your project or even PC you prefer to store external libraries).

4. Add pasted SWC to the project’s library using “Add To Library” context menu item.

5. To run TheMiner, you should add its panel to the DisplayList first. Choose the wise place in your project where to add it (it could be a place where you’re set up the stage) and write there a few lines of code.

// first, we should import TheMiner class, so add this line to the imports:
import com.sociodox.theminer.TheMiner;

//after you're free to add TheMiner's panel
//please note if you're using 1.3.10 or earlier,
//you should pass "true" to the constructor
stage.addChild(new TheMiner());

Whole sample working code could be like this:

package
{
	import com.sociodox.theminer.TheMiner;
	import flash.display.Sprite;
	import flash.events.Event;

	/**
	 * ...
	 * @author focus
	 */
	public class Main extends Sprite
	{

		public function Main():void
		{
			if (stage) init();
			else this.addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(e:Event = null):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, init);
			//please note if you're using 1.3.10 or earlier,
			//you should pass "true" to the constructor
			this.addChild(new TheMiner());
		}
	}
}

Hey, that’s all about using TheMiner as SWC! As you can see, it’s pretty simple and easy to set up TheMiner right in your SWF using the SWC approach.
Compile your project, run it in the debug Flash Player (by default in FlashDevelop) and you’ll see TheMiner in action!

So, in what cases should we prefer TheMiner as SWC over TheMiner as FlashDevelop profiler?
- if we wish to be able to run TheMiner anywhere our SWF is run under debug Flash Player or debug AIR, including the mobile devices
- if we wish to have an additional control on when to show TheMiner
- if we wish to be able to interact with TheMiner for more flexible and efficient profiling

TheMiner as FlashDevelop profiler

1. First of all, purchase TheMiner or download a free version for the non-commercial usage.

2. Unpack given archive, go into the “SWFs” folder and select desired SWF with translation you prefer, as example, select the TheMiner_en.swf

3. Place that SWF anywhere on your PC, and remember the path for it. For example, path will be “D:\Programming\Flash\Tools\TheMiner.swf”.

4. Open the “Tools->Program Settings” menu item in the FlashDevelop.

5. Go to the AS3Context plugin settings and look there for the Custom Profilers item.

6. Press the “…” button at the right from the Custom Profilers item and paste path to the TheMiner swf in the opened window as new line and press OK.

(sorry for Russian texts)

7. Close the Settings window and press on the “SWF Profiler” button on the toolbar (or to the “View” menu subitem with the same name).

8. Press and hold the “Active Profiler” button at the opened “Profiler” window left side and select “TheMiner” item in the dropped menu.

9. Press the “Auto-start Profiler” button if it’s red now to make it green and to enable TheMiner auto starting with compiled SWF.

That’s all – now you could compile your project and see TheMiner running!

This way of TheMiner using in the FlashDevelop may seem not so fast to set up as using TheMiner SWC, but you should make all this steps only once! Next time you’ll need to add TheMiner in your project all you need is just to ensure Auto-start profiler is enabled and compile your project!

So, in what cases should we prefer TheMiner as FlashDevelop profiler over TheMiner as SWC?
- if we don’t need TheMiner to be included in our SWF / app after publishing / leaving FlashDevelop
- if we wish to have very easy set up after first time without adding anything to the project code and keep the project clean from additional SWCs

PS: Today new TheMiner version is out with lot of bugfixes and some really nice additions.

]]>
http://blog.codestage.ru/2012/03/22/theminer-and-flashdevelop/feed/ 2
Packed SWF. How to unpack? http://blog.codestage.ru/2012/03/07/packed/ http://blog.codestage.ru/2012/03/07/packed/#comments Wed, 07 Mar 2012 18:22:56 +0000 focus http://blog.codestage.ru/?p=762 Continue reading ]]> Hey, friends!
In this post I’d like to explain you what is a packed SWF, how it looks and show you some methods of dynamic and static unpacking.

So, what is packed SWF?

If you never saw it, please, feel free to download this classic example of packed SWF:
http://codestage.ru/files/flood/security/packed.swf
You can see single SWF showing a text. But you can’t reach a code showing it with a classic approach – through the decompilers.
I should mention you’ll not reach any resources (Bitmaps, Sounds, Fonts, etc) via decompilers if they will be there too, because target SWF is placed inside of SWF you have and usually it is encrypted.
Usually all you can get with decompilers from a such SWF is a decryptor/unpacker code (usually hardly obfuscated), and, probably, target encrypted SWF (if your decompiler is able to show you the DefineBinaryData tag)
This kind of packing could be achieved with simple Flex [Embed] tag.

Dynamic unpacking (dumping)

Dynamic means unpacking while target SWF is run in Flash Player (FP).
As FP can’t play packed SWF as is, it should be unpacked and decrypted into the memory before loading (as example, with Loader.loadBytes()).
More important, it will be in the memory all the time while it’s running to allow FP properly display end execute it.

That’s our chance to get it!
There are two common ways to do it.

1) Dynamic unpacking with tools
Using third-party or even own tools to automatically search SWF in FP process memory. It’s the fastest and easiest method. Doesn’t provide you a feeling you’re a true cracker ;)
There are several tools for it available both free and paid.
One of most advanced is a SWF Revealer, free tool for the ASV licence owners. It could bypass domain checks (which will prevent SWF to unpack and decrypt) in some cases and force SWF to load and decrypt target SWF.
Also you could found some free tools for dumping after googling for it a bit.

2) Dynamic unpacking with hands
Search for it “by hands”, looking for the CWS (compressed SWF) or FWS (uncompressed SWF) header signature which are the start of any SWF file. If you never tried it, you definitely should try! It could be useful to improve your skills with hex a bit and to provide you a feeling yourself a true cracker)
For search you could use any Hex editor supporting RAM editing\viewing.
If you’ll try to search for packed SWF in the sample file I linked before, you should start from searching the FWS signature (uncompressed SWF) – just search for the ‘FWS’ string in the Flash Player’s (or Flash Player plugin\browser with SWF running in it) process because FP decompresses SWF before executing if it was compressed.
If you’ll search in a browser, be careful and close all other tabs with SWFs to decrease amount of the false positives.

Usually, you’ll find not only one signature entry, because FP contains other internal SWFs as well, like SWF showing hint how to exit from the fullscreen mode.
So if you’re not sure, I recommend you to check all found entries.
Well, what to do with found signature you’ll ask? How to validate it, how to know, where is the end of the SWF?
Please, look at this screenshot:

This is a signature for the one of the SWFs found in the FP memory (accidentally it’s a signature of the target packed SWF =) ) by looking for FWS string.
So, what next? Next you should check the length of the found SWF. Length is placed at the 4 bytes starting from 4 byte:

How did I knew that? It’s simple, I just read the “SWF File Format Specification” http://www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf_file_format_spec_v10.pdf (“The SWF header” section)
Since it’s a hexadecimal number written in memory, you should know its bytes are written from right to left. So resulting number is:
00 00 04 DB in hexadecimal and 1243 in decimal.
Let’s measure this 1243 bytes starting from the FWS signature.
Because signature starts at 053DD020, SWF file end should be at 053DD4FB (053DD020 + 4DB):

Please, note that address where FWS is placed in memory is not the same on different OS and hardware.

Now we see our SWF in memory really ends at 053DD4FB and we can select all bytes from 053DD020 up to 053DD4FB and copy-paste them into the new SWF file.
After making this with all suitable FWS entries you’ll, you’ll have target unpacked SWF file in one of the saved SWFs!
Now you should be able to decompile it as usual and look into its sources or resources.

Some protections are trying to resist SWF dumping by generating many fake FWS headers, trashing a memory with them a bit. So you should double check if header has valid length and how it looks at all. Experienced in reversing people (like me :p) could say if header fake or not just looking on it and on several tens of bytes after the header.

Sometimes, packed SWF will not be decrypted and loaded into the memory because of different cases. As example, packer’s loader could check current domain or some kind of the license file before unpacking SWF. In this case you’ll need to patch that checks (as example, with bytecode disassemblers like Yogda or RABCDasm) or provide needed files (probably with crypto keys for decrypting) to make SWF run and unpack in memory.

Static unpacking

Static means we don’t need the SWF to be executed in FP to unpack.
Well, this kind of unpacking usually comes to help when you have no chance with unpacking your SWF dynamically (who knows why you can’t run SWF?)
Static unpacking could be very difficult because of many possible safety precautions of the packer developer. There are many ways of making static unpacking painful and very long.

So, how to start with static unpacking? First of all, you should have access to the two things inside the SWF to make this unpacking possible:
1 – DefineBinaryData tag(s).
2 – Decompiled AS or abc bytecode of packer loader.
And optionally, to the
3 – SymbolClass tag
Use available tools to achieve it (ASV, Adobe SWF Investigator, SWiX, etc).

How to find DefineBinaryData tag in the SWF?
Well, some tools, like ASV will point you to that tag with ease and allow you to save it as binary file.
Also it could be found by hands, with different tag-reading tools, like mentioned before Adobe SWF Investigator.
To get data from DefineBinaryData tag with Adobe SWF Investigator from the sample file I linked above, just open the file, go to the Tag Viewer tab, select DefineBinaryData tag and press Dump To File button.

Sometimes there could be numerous fake DefineBinaryData tags inside, just to make your life harder. To find the desired tag, you should look inside the packer’s loader code and track down where is the embedded SWF is created to be decrypted and loaded.
Usually it looks like this:

var someVar:ByteArray = new SomeClass();

Where SomeClass is type of Class extending the ByteArrayAsset class.

Let’s look at the sample SWF loader code and look for something like this.
Gotcha! here it is:

private var content:Class;
//...
var _local3:ByteArray = new this.content();

So, we should look for the class with name ending on “_content” and extending the ByteArrayAsset class.
We have one match here:

public class MainTimeline_focus_loader_content extends ByteArrayAsset

To get which DefineBinaryData tag is linked with this class, we should look into the SymbolClass tag and search there for a record with found class name “MainTimeline_focus_loader_content”.
And we got it (in Adobe SWF Investigator):

<Symbol idref='1' className='MainTimeline_focus_loader_content' />

Remember idref value. This is a desired DefineBinaryData tag id!
Now go and search the DefineBinaryData tag with id = 1 – that tag will be needed one, so we can just dump it in a file and continue unpacking.
Why I asked you to remember the idref value instead of class name? That’s because in case loader AS will be obfuscated, it could be really hard to work with class name.

Now your success depends on your free time, packer’s loader difficulty and your luck)
If you’ll be a lucky one, that data dumped from the DefineBinaryData tag will be the pure, not encrypted SWF, and unpacking will be finished.
But in most cases data is encrypted and you should reverse engineer the packer’s loader code and make own decryptor.

In our case the loader’s code is extremely easy and not obfuscated, so we can easily found the decryption function:

private function decryptFile(_arg1:ByteArray):void
{
    _arg1.position = 0;
    var _local2:int = -1;
    var _local3:uint = _arg1.length;
    var _local4:uint = uint("55");
    while (_local2++ < _local3)
    {
        _arg1[_local2] = (_arg1[_local2] ^ _local4);
    };
}

All we need to decrypt file from the DefineBinaryData tag is just xor each byte of it by 55.
That’s all. Now you could write decryptor, decrypt SWF and decompile it to see the desired source code. And pray this decrypted swf will be your target swf, not the another one with packed swf inside haha! Sometimes packers uses the Russian Matreshka doll approach to hide target swf and other techniques to make static unpacking harder. Anyway, dynamic unpacking will beat all of them.
Remember – in Flash world, nothing only variables names can be hided from the true professional with high motivation level.

Any questions, ideas, comments? Feel free to leave it below!

]]>
http://blog.codestage.ru/2012/03/07/packed/feed/ 5