This page describes tools being used to help construct a SWF9 disassembler. This involves tools to analyze the instruction set of the new Flash 9 virtual machine (AVS2).
A disassembler is being written in C++ by Asger Alstrup. The tools below help to extract the binary output of the Flex compiler and compare two code fragments differentially.
A partial list of opcodes we have discovered is listed here SWF9 opcodes, however most of the new information is going straight into the disassembler program code.
The following small utility written in Java will uncompress a swf file and extract a given instance of a tag. It takes input from stdin and writes to stdout
This utility extracts a tag with a given code from a swf file. If there is more than one tag with the desired code, the second command line arg says which tag to extract.
This script (runs in Cygwin on a Windows box) will take a source file which contains two Javascript programs, for which you want to examine the binary differences in the compiled output.
Let us say you wanted to compare the compiled output of these two programs:
package { var foo:Number = 0; } ================ package { var foo:Number = 1; }
You would place the two programs in a file with that separator shown, and the workflow script “doit”, below, will take that and compile the two programs separately, extract the SWF9 code block(s) from the compiled swf files, and produce a binary diff of the output.
The output looks like SWF9 Diff
This script assumes that the ExamDiff application is installed as show, and that the Flex compiler is installed in the indicated path as well. The “unzip” and “etag” java utilities listed above are also required to be in the current working directory.
#!/usr/bin/bash ./splitfile $@ flex="/Program Files/Macromedia/Flex Builder 2 Alpha 1/Flex Framework 2 Alpha 1" java -Xms96m -Xmx384m -Dsun.io.useCanonCaches=false -jar "${flex}/lib/mxmlc.jar" -flexlib "${flex}/frameworks/" a.as java -Xms96m -Xmx384m -Dsun.io.useCanonCaches=false -jar "${flex}/lib/mxmlc.jar" -flexlib "${flex}/frameworks/" b.as #PREFIX=`echo "$@" | sed -e "s/\(.*\)[.]as/\1/g"` #SWF=${PREFIX}.swf java -cp . unzip < a.swf > tags java -cp . etag < tags 52 0 > a.tag52 java -cp . etag < tags 4c 0 > a.tag4c java -cp . unzip < b.swf > tags java -cp . etag < tags 52 0 > b.tag52 java -cp . etag < tags 4c 0 > b.tag4c # Compare files "/cygdrive/c/Program Files/ExamDiff Pro/ExamDiff" a.tag52 b.tag52 /o:cmp.html /html echo "<table border=1 width=\"100%\"> <tr><td width=\"50%\"> " > out.html echo "<pre>" >> out.html echo " <b>a.as:</b>" >> out.html cat a.as | sed 's/</\&lt;/g;s/>/\&gt;/g;s/&/&amp;/g;' - >> out.html echo "</pre> </td><td width=\"50%\"> <pre><b>b.as:</b>" >> out.html cat b.as | sed 's/</\&lt;/g;s/>/\&gt;/g;s/&/&amp;/g;' - >> out.html echo "</pre> </td> </tr> </table>" >> out.html tail +7 cmp.html >> out.html echo "result in out.html"
The steps are:
First, a small PERL program splits a source file into two halves, at the boundary “================”.
splitfile
#!/usr/bin/perl open(F1, ">a.as"); open(F2, ">b.as"); $a = 0; while (<>) { if ($_ =~ "================") { $a = 1; } elsif ($a eq 0) { print F1 $_; } else { print F2 $_; } }
Once the source file has been split, the two halves are compiled separately with Flex’s Javascript compiler.
The output swf files are then passed through the unzip decompressor and then the first instance of tag 0×52 is extracted. This seems to be the tag which contains the AVM2 instructions, at least for small source files. Larger MXML files compile into what looks like two 0×52 tags, with one being a small preamble, and the bulk of the app in the second tag. There are also tag 0×45 and 0x4C which seem to contain some declarations or AVM2 file format codes.
Let’s collect the info discovered here: SWF9 opcodes
You can also use a slightly modified version of HexDump.java found at http://david.tribble.com/src/java/tribble/util/HexDump.java with this doit.sh script:
#!/usr/bin/bash ./splitfile $@ flex="/Program Files/Macromedia/Flex Builder 2 Alpha 1/Flex Framework 2 Alpha 1" java -Xms96m -Xmx384m -Dsun.io.useCanonCaches=false -jar "${flex}/lib/mxmlc.jar" -flexlib "${flex}/frameworks/" a.as java -Xms96m -Xmx384m -Dsun.io.useCanonCaches=false -jar "${flex}/lib/mxmlc.jar" -flexlib "${flex}/frameworks/" b.as #PREFIX=`echo "$@" | sed -e "s/\(.*\)[.]as/\1/g"` #SWF=${PREFIX}.swf java -cp . unzip < a.swf > tags java -cp . etag < tags 52 0 > a.tag52 java -cp . etag < tags 4c 0 > a.tag4c java -cp . unzip < b.swf > tags java -cp . etag < tags 52 0 > b.tag52 java -cp . etag < tags 4c 0 > b.tag4c # Dump hex as ascii java -cp . HexDump a.tag52 > a.tag52hex java -cp . HexDump b.tag52 > b.tag52hex # Compare files diff -y a.tag52hex b.tag52hex > out.txt