Packed SWF. How to unpack?

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 may find some other tools for dumping on the web using google.

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!

Found a typo? Please, highlight it and press Shift + Enter or click here to inform me!

Share Button

Comments

Packed SWF. How to unpack? — 26 Comments

  1. hi,

    i hope you can see my post. i have been readed all of you article about swf security. and now, i have a question about alchemy : is there any way to analyse algorithm which is compiled by flashcc or alchemy, or is it possible to export abc codes which is compiled by flashcc or alchemy to swc to use? i search this question by google, but found nothing. could you talk abount it? thank you!

    • Hey, sorry for a such late reply.
      Yes, it’s possible to decompile and analyse flascc \ alchemy opcodes with different tools. Not all tools support them though.

      • thx, is there any article or tools can analyse flascc \ alchemy opcodes? i try to decompile flashcc with action script viewer, but the result scripts are unreadable.

        • No, didn’t saw such article. Are you using latest ASV version. Latest version works great for me and decompiles flascc opcodes correctly.

  2. Hey ,
    I know this post is very old but I found SWF file that cannot be unpacked ๐Ÿ™
    Hopefully I’d like to get some advices how to unpack this swf file: haxball.com/haxball13.swf
    Have a nice day.

      • Hey , Thanks for the comment.
        I opened the SWF in hex editor.
        then I looked at the length of the file in the SWF header: 4D8A4
        but I saw that the file length is actually 4D170 ,
        so I cant copy the first 4D8A4 bytes to new SWF file because there is no 4D8A4 bytes only 4D170

          • there is crypted swf file inside the main SWF file I sent in the first message,
            If I just copy all the bytes from the first SWF into new SWF I just get the original first SWF and not the crypted SWF file that is inside the main SWF file as in the dynamic unpacking..

          • I see your problem now. You just find the original swf loaded in memory and dump it, which obviously results in the same swf.
            Instead, you should try looking in FP memory encrypted swf which is loaded by the original swf.
            To do this, just dump every swf with size ~ of the original swf size.

            You should be able to find swf with size 06 DB D5 after all which is swf you’re looking for.
            Also please note, original (loader) swf has some specific code you need to re-implement in your own loader or in dumped swf (something about array prototype).
            Otherwise dumped swf may just not work.

  3. Pingback: Free SWF Decompilers | 8tut.com

    • This is just a SWF compressor \ decompressor (CWS< ->FWS, no LZMA support), isn’t it? Can’t read those Japanese symbols, sorry ;-P

  4. what need to do after this? “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.” ?

        • Hey, Muhd!
          You actually should look at the DefineBinaryData tag contents you dumped. It could be clean swf (starts from CWS, FWS, ZWS) or something encrypted. In second case look for the decryptor in the SWF you got DefineBinaryData contents from.

          • can u tell me more? XD im not understand what u say ๐Ÿ˜› newbie

          • Well, I’m not sure what can I explain here in more details ๐Ÿ™
            Please, try to use Google Translate to translate article to your native language. And use google itself to search for additional info on SWF format and AVM specs.

          • Hi! BinaryData may contain different valid data, like FLEX skins for example. In your SWF there are JSON configs stored as BitmapData tags. They are used in wom.model.domain.JsonPopulatedDomainInfo class. Nothing extra special here.

  5. Thank your for this good explanation.
    How can I fake the swf header information and pack the file again?
    I don’t want metainfo tags like: created with adobe CS5.

  6. Dynamically dump swf from memory not easy too. Sometimes they create multiply (10000 or more) fake swfs (size some Kb) in memory.

    • Thanks for your comment! There are many free and shareware tools created to dump swfs from memory, including SWF Reader, it’s definitely nice and useful tool for SWF inspection and editing!

Feel free to print your thoughts on topic below

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

*