Convert *some* Flash 8 Movies to Flash9 Movies at runtime
I don’t know how long I’ve been frustrated with the AVM1Movie Class — finally I’ve gotten around to trying to get around the class by modifying the byte header order … I have been able to successfully switch any Flash8 Movie that doesn’t have actionscript in it, just pure frame data … This might not be a huge help for too many of you, but it’s nice for people (like me) that still use uncompressed swfs.
How it works: Change byte 23 to a value of 8. That’s it. I didn’t have to change the 4th byte (which is the version 8 or 9 byte). I have no idea why, but hey, it works, and that’s all that matters. Code is below: (here’s an example swf as well (right click save as))
The output: [object MovieClip] lovely.
package {
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.ByteArray;
public class ByteHeader extends Sprite {
public function ByteHeader():void {
var convertMovie:Boolean = true;
var request:URLRequest = new URLRequest(’flash8_movie.swf’)
if (convertMovie) {
var urlloader:URLLoader = new URLLoader();
urlloader.dataFormat = URLLoaderDataFormat.BINARY;
urlloader.addEventListener(Event.COMPLETE, _convertF8Movie);
urlloader.load(request);
} else {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoaderComplete);
loader.load(request);
addChild(loader);
}
}
private function _convertF8Movie(event:Event):void {
var urlloader:URLLoader = event.currentTarget as URLLoader;
var f8bytes:ByteArray = urlloader.data;
// set version — not necessary
// f8bytes[3] = 9;
// no idea what this byte does, but it’s important
f8bytes[22] = 8;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoaderComplete);
loader.loadBytes(f8bytes);
addChild(loader);
}
private function _onLoaderComplete(event:Event):void {
var info:LoaderInfo = event.target as LoaderInfo;
trace(info.content);
}
}
}


Hmm, I couldn’t get that to work, if I change the f8bytes[22] = 8; then I cannot receive Event.COMPLETE from the loader
Comment on November 22, 2006 @ 2:10 am
send me your source, and i’ll take a look at it.
Comment on November 28, 2006 @ 1:54 pm
nice trick ;)
Comment on November 30, 2006 @ 1:18 pm
The more appropriate way to put f8bytes[22] = 8, would be, f8bytes[8 /* "FWS" + x08 or x09 + 4 bytes filesize */ + x + 6 /* 2 bytes framerate multiplied by 255 + 2 bytes frame count + 2 bytes for background frame tag marker */].
x is the size of the window rectangle, which is variable. For example, an 1×1px window is encoded as 30 0A 00 A0 (four bytes), while 200×200px is encoded as 00 1F 40 00 07 D0 00 (seven bytes). I don’t have the time to tell how to tell how many bytes any window rectangle size is encoded as right now, but you can find it in swftools 0.7’s lib\rfxswf.c on row 477 and further (swf_SetRect).
Modifying the 23:rd byte did not work for me, as my SWF was 1×1px.
Regards
Mikael Möre
Comment on December 17, 2006 @ 11:37 am
thanks mikael. I didn’t realize swftools already could compile as3 swfs.
rock.
Comment on December 18, 2006 @ 12:31 pm
Thanks for discovering and reporting this Daniel! I researched it a little bit using the SWF format documentation and a hex editor. This specific “magic” byte corresponds to the UseNetwork field of the new FileAttributes tag which is now required in SWF 8. According to the docs, this field can have either 1 or 0 as value, which denotes, respectively, network or local file access permissions. Interestingly, when compiling to SWF 9 with the Flash 9 beta, this field instead assumes the values 9 or 8 depending on the access permissions.
So, it appears what your method is doing is to set the Access permissions to local using an as yet undocumented change in the FileAttribute tag in SWF9.
Comment on March 12, 2007 @ 5:14 pm
Correction:
Its not the UseNetwork field itself that is significant, its the “Reserved” field just immediately preceding it, and more specifically the leftmost bit of this 3-bit field should be set to 1 for this hack to work. Apparently, this is always the case in files compiled to SWF9, and never in older SWF’s (the SWF8 documentation requires it to be set to 0…).
My guess is a new security feature was added which now takes the place of the previously reserved field, and as far as i can tell it acts as a switch determining whether parent swf’s are allowed to access the inner content of the current SWF.
Comment on March 12, 2007 @ 5:39 pm
Can somebody point out what to do, from all this comments and can’t really figure out which byte location to change according to my swf - i have an output from swftools, pdf2swf, and changing byte 23 to 08 doesnt work :|
Comment on April 18, 2007 @ 7:44 am
hey Gregor, it’s not byte 23 exactly. ithe length of the header is variable due to the dimensions of the swf (look up nbits). You’ll have to parse the header and find out the rect size of the swf, then find the relevant bits to change. If i get some time I’ll post some code that i started that does some of this look-up.
Comment on April 18, 2007 @ 8:49 am
Ok thanks, the problem is: i can find how the window size is encoded like Mikael suggested but still from all this discussion i can’t understand how to parse the header and find the right location, are there bits to change or bytes? And Mikaels formula to find the location is more then confusing :| What are nbits? What is FWS?
Comment on April 18, 2007 @ 9:10 am
Hey, ok with the help of Daniel and information at sites:
http://sswf.sourceforge.net/SWFalexref.html
http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm
i managed to decipher the header.
Now i can calculate where the flash header ends and i can get the first tag. But if i generate a Flash8 the first tag is not FILEATTRIBUTES as it should be.
Anyway, can somebody tell specifically what bite to change? Some bite in the FILEATTRIBUTE tag? This apparently won’t be enough: http://www.mail-archive.com/swftools-common@nongnu.org/msg00900.html
Comment on April 18, 2007 @ 2:01 pm
[...] リンク先サンプルの書き換えは、ステージサイズ依存になっているので、汎用コードじゃないけど、もうちょっとみんなが調べれば確実な方法が判明しそう。 danielhai.com : Convert *some* Flash 8 Movies to Flash9 Movies at runtime [...]
Pingback on May 7, 2008 @ 6:58 am
Hi Daniel, this is great! Thanks! It seems that this needs to load the entire file before displaying the swf. Is it possible to use the progressive download to begin playing before it is completely loaded? I don’t see in your code where the swf is made visible.
Comment on February 18, 2009 @ 12:52 pm