We have been doing some enhancements about how we show information about SymbolClass tags in ASV (and UAE). Usually, I don’t post about technical matters like this because the info might be used by either competitors or SWF obfuscator vendors. We decided this one is sufficiently harmless, so here we go…A SWF file can contain more than one SymbolClass tag in one or more frames. For the sake of simplicity, in this post I will discuss a single SymbolClass tag in a single frame SWF. Also please assume sample symbol tags are ones that can be placed on stage (like a DefineSprite tag – a Movie Clip-, not a DefineBinaryData tag) unless stated otherwise.
As the SWF Specs state, for AS3 SWFs, SymbolClass tag creates associations between symbols in the SWF file and ActionScript 3.0 classes.
Specs further state that if the character ID entry in the SymbolClass tag is zero, then the class is associated with the main timeline of the SWF. So that’s how good ol’ document class is defined.
Apart from the ‘export’ purposes mentioned in the specs, the association means:
- When you place a symbol, which has an associated class, on stage, in Flash Pro by dragging it from the library (or using a PlaceObject tag in a SWF), its associated class instance is created and run. For example, this is how the class instance that contains frame scripts of a Movie Clip is run.
- When you create a new instance of a class, which has an associated symbol, you can place the symbol on stage using addChild() or as in case of BinaryData symbol (DefineBinaryData tag), a class that subclasses ByteArray must be associated with the symbol and the byte array will be automatically populated with the data after the class is instantiated.
The tag simply contains a list of symbol (character) IDs and associated class names.
Here is how ASV currently displays the information:
The Good: Normal Case
Normally, the entries in SymbolClass tag list, both character IDs and class names, are unique, and so the association is true both ways: When a symbol is associated with a class (Symbol -> Class), the class is also associated with the symbol (Class -> Symbol), and vice versa.
If the character ID is 0, then the class is the document class (Class -> Main Timeline) [In this case, also Main Timeline/Document is associated with the class but that association is used automatically when main timeline is run/displayed along with the associated document class, in the first frame of a SWF file].
In a simpler world, if you only consider normal usage, for any random entry in the list, you could simply say: ‘If symbol ID is 0, class is doc class, else symbol is associated with class, and class is associated with symbol’.
The Expected: Consequences
What if, after a symbol is associated with a class, a later entry in the list has the same symbol ID to be associated with another class? First one is valid only. A symbol can only be associated with a single class (Symbol -> Class).
What if, after a class is associated with a symbol, a later entry in the list has the same class name to be associated with another symbol? First one is valid only. A class can only be associated with a single symbol (Class -> Symbol).
So a symbol associated with a class does not necessarily mean the same class is associated with the symbol. On top of this, many symbols can be associated with the same class and many classes can be associated with the same symbol.
This is much easier to see with a sample. Assume a SymbolClass tag which has 4 entries:
Entry 1 = Symbol1 : Class1
Symbol1 will be associated with Class1 (Symbol1 -> Class1).
Class1 will be associated with Symbol1 (Class1- > Symbol1)
Entry 2= Symbol1 : Class2
Symbol1 will NOT be associated with Class2, because it is already associated with another class.
Class2 will be associated with Symbol1 (Class2 -> Symbol1)
Entry 3= Symbol2 : Class1
Symbol2 will be associated with Class1 (Symbol2 -> Class1).
Class1 will NOT be associated with Symbol2, because it is already associated with another symbol.
Entry 4= Symbol2 : Class2
Symbol2 will NOT be associated with Class2, because it is already associated with another class.
Class2 will NOT be associated with Symbol2, because it is already associated with another symbol.
This entry has no effect.
Now we have,
- Class1 and Class2 -> Symbol1 (Many classes associated with a symbol).
- Symbol1 and Symbol2 -> Class1 (Many symbols associated with a class).
- Class1->Symbol1 but Symbol1 -> Class2 (Class associated with a symbol, but symbol isn’t).
- Symbol2 -> Class1 but Class1 -> Symbol1 (Symbol associated with a class, but class isn’t).
- An entry that associates Symbol2 with Class2, but has no effect.
Things are not that complicated when you are looking from one side.
From within AS3, some classes have associated symbols. Though rare, the symbol need not be exclusive to the class.
From SWF side, some symbols have associated classes. Though rare, the class need not be exclusive to the symbol.
Actually, it is a lot more simple when you think it like this: To find the associated symbol or class, if you have the symbol ID, search for it and return the first found class. If you have the class name, search for it, return the first found symbol.
Current internal version of ASV places arrow icons to specify the associations:
The Bad: Missing Parts
What if the tag for the symbol ID specified in an entry is missing in the SWF? This is clearly an error. The symbol will not be associated with the specified class, and certainly the class will not be associated with the missing symbol.
What if the class isn’t defined? Same as above. The class will not be associated with the specified symbol, and certainly the symbol will not be associated with the missing class.
In these cases, a later valid entry for the non-missing symbol ID, or, class name, will create the associations as normal.
We can conclude that if an entry has an error, the entry is ignored.
But we still have the document class entry to consider…
The Unexpected: Symbol X
What if there is no entry for the document class? This is acceptable. The SWF file will run with no doc class.
Normally character IDs start from 1 and there won’t be a symbol with the character ID zero. But what if there is? The class for the symbol ID 0 entry will be associated with the Symbol 0, not the document.
Now this is interesting.
It turns out 0 is not really a magic number, it is just the convenient number for the (normally) non-existing symbol ID. Tests reveal that, until the document class is assigned in the first frame, a missing symbol ID entry will assign the document class (and should not be considered as in-error).
So even determining the document class of a flash file can be tricky. A class assigned to missing character 28 can be the document class, while the class specified in the entry with character ID 0 is associated with a symbol, and the document class can be associated to Symbol 42 at the same time…