Tag Archive for 'lzma'

LZMA compression in Apparat RC5

Matryoshka avec moustache

I have released Apparat RC5 at GoogleCode. It contains a really cool feature which is called LZMA compression.

Reducer has advanced a lot during the last couple of weeks. It is now also a strong SWF compression tool even if you do not have any PNG files it can compress. You may ask: “What is that Matryoshka doing there? And why the hell the top hat?” The top hat: I do not know. The Matryoshka: I can explain.

The Flash Player does not understand LZMA. SWF files are compressed using good old DEFLATE. So what happens? Apparat extracts your original SWF. It compresses it again using the LZMA algorithm. The compressed SWF is injected into another SWF that contains an LZMA decoder. Size, background color, frame rate, etc. get adjusted. Finally you get a new SWF that contains your old SWF and a decoder to extract it at runtime. The overhead of the decoder is currently at around 5kb and I hope I can get it even smaller.

When you open that SWF with the Flash Player it will extract your original file and load it. Another nice feature is that I created different versions of the runtime decoder. One is using a classic preloader which is great if your SWF is a little bit bigger. And hey: it is a preloader for free so you do not have to deal with the [Frame] hassle. But here is the catch. We at audiotool.com always write our SWF files in the same style and I can just hope you do the same or use the great InitInjector by Valentin Simonov.

Your main SWF class or the so called DocumentClass must make sure that a stage is available before accessing it. This is really easy:

public function Main() {
  addEventListener(Event.ADDED_TO_STAGE, init)
  if(null != stage) init()
}

private function init(event: Event = null): void {
  removeEventListener(Event.ADDED_TO_STAGE, init)
  // your original constructor code goes here ...
}

Stick to that rule or InitInjector can automate it for you. Otherwise you will get a runtime exception that the stage is null. So this is one new feature. The other one is actually pretty standard. If you compile and link against a SWC file all classes will come in their own ABC file. Each ABC file has a constant pool. So if you link against 1000 classes you get 1000 constant pools. Reducer can merge all those files into a single one with some minor exceptions. It can also sort the constant pool so that constants which are used frequently consume less bytes when accessed. The funk-as3 test runner which links against FlexUnit and the Flex framework is only loosing 3.01% of its weight with the old Reducer. The new version reduces it by 17.81% already thanks to the ABC merging. Combine that with some LZMA love and we get 35.34%.

Besides you can call the LZMA compression as often as you want for some basic obfuscation. The LZMA compression alone is already a (weak) obfuscation of your bytecode.

Last but not least: Good news everyone! Scala 2.8 arrived so this is the last time you will have to update it for a while.

You can download the latest Apparat version at GoogleCode. Scala 2.8.0 is required.