SWF rebuilding with as3swf code library

Hey!
It’s been too long since we’ve had a good bandit raid topical content here. I’m going to fix it!)

Today we’ll speak about SWF changing using as3swf code library, as you could already guess from this post topic.

Let me introduce this library first.
It was designed to parse, modify, and create SWF files on the fly. You could get all the tags and SWF properties (frameRate, version, etc.) after ByteArray with target SWF parsing. The good thing is that with as3swf you’re free to modify any SWF tags and properties and it is able to save all changes you did! It could even allow you to create a new SWF file from scratch.
as3swf is available for your experiments at github: https://github.com/claus/as3swf

Library is pretty alive and have a good communicative author (Claus Wahlers), so feel free to make Pull requests 😉
BTW, he applied my LZMA compression (more on LZMA – here) support pull request yesterday.
You should wait for the Flash Player 11.4 release to try as3swf with LZMA-compressed SWFs though.

One thing as3swf could not provide is a DoABC Tag ABC parsing.
Author started so library project some time ago, but abandoned it, thus it is no longer supported or actual.

I should agree with Claus though since a great ABC parsing and creating on the fly library as3commons bytecode already exists and have updates periodically: http://as3-commons.googlecode.com/svn/trunk/as3-commons-bytecode/changelog.txt
I’ve used it some time ago and was really happy with it. But this is another case…

I’ll shed a bit of light on my as3swf using purposes: I had a task to replace one SWF tag with completely new data, it was the DefineBinaryData tag to be clearer.

This is how looks SWF parsing code:

var swf:SWF = new SWF(swfByteArray);

swfByteArray is a ByteArray with our SWF.
Really simple one, ah?

So, after SWF parsing I had to replace embedded into the SWF file with this Flex Embed tag:

[Embed(source="./data.dat", mimeType="application/octet-stream")]
private var EmbeddedDataClass:Class;

When some content is being embedded this way, the resulting SWF obtains some special data you should know to replace embedded file.

First of all, a new DefineBinaryData tag appears with it’s unique Symbol ID.
In addition using Embed tag leads to the new AS3 class creation with name = ClassName_VariableName and extending the mx.core.ByteArrayAsset class.
If we’ll imagine we’ve used Embed in the MySuperClass class inside of the ru.codestage package, we’ll have a class with ru.codestage.MySuperClass_EmbeddedDataClass name.
At least, SybmolClass tag containing Symbol IDs linked to their AS3 Classes appears or supplements. BTW, new records also appears in the SybmolClass tag when you’re using class linkage functionality in the Flash Pro.

Knowing all this neat stuff we could easily find and deal with needed DefineBinaryData tag without risk to damage source SWF!

So, how to make it using as3swf:

var newSWFByteArray:ByteArray = new ByteArray();

// this line should be familiar to you already
var swf:SWF = new SWF(swfByteArray);

var symbolClass:TagSymbolClass;
var defineBinaryData:TagDefineBinaryData;

// looping through all the SWF tags ...
var leni:uint = swf.tags.length;
var i:uint;

outerLoop: for (i = 0; i < leni; i++ )
{
	// ... and looking for the SymbolClass tag
	if (swf.tags[i].type == TagSymbolClass.TYPE)
	{
		symbolClass = (swf.tags[i] as TagSymbolClass);

		// when SymbolClass tag is found we could start
		// to loop through all its symbols
		var lenj:uint = symbolClass.symbols.length;
		var j:uint;
		
		for (j = 0; j < lenj; j++ )
		{
			// looking for the symbol record with needed name
			var symbol:SWFSymbol = symbolClass.symbols[j];
			if (symbol.name == "ru.codestage.MySuperClass_EmbeddedDataClass")
			{
				// as we encounter needed symbol record, we could get its ID using symbol.tagId field
				// and get a needed Symbol with the same ID from the SWF using swf.getCharacter() method
				defineBinaryData = (swf.getCharacter(symbol.tagId) as TagDefineBinaryData);
				break outerLoop;
			}
		}
	}
}

// if we got something valuable with swf.getCharacter(),
// we could start to replace its data
if (defineBinaryData)
{
	defineBinaryData.binaryData.clear();
	defineBinaryData.binaryData.writeUTFBytes(_dataString);

	// and save results into ByteArray
	swf.publish(newSWFByteArray);
	trace("Done!");
}
else
{
	trace("[ERROR] No ru.codestage.MySuperClass_EmbeddedDataClass symbol found!");
}

I’m sure this code is pretty simple and easy to understand.
So, as you can see, as3swf is a really powerful (note that I showed just small part of all its functionality), flexible and easy to use code library, use it with fun!)

Recently I’ve used it in my small Site Locking tool I wrote for one day (most of time I’d polished GUI though :D)

If you have any questions, notes, suggestions or anything else to say – you’re welcome, just leave a comment here – I’ll read it, I promise!)

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

Share Button

Comments

SWF rebuilding with as3swf code library — 4 Comments

  1. Pingback: SWF Dateien in Echtzeit compilieren - Flashforum

  2. For the purpose of comparison, or just for fun, you can also take a look at this library I’ve been building slowly over the years: https://github.com/Krilnon/abc-abstraction

    It tries to handle the creation/editing/saving of both SWF and ABC, although I’ve focused more on ABC. I think the as3commons bytecode library is much more popular than mine, so basically nobody has comment on it. =P

  3. Pingback: CODE STAGE « eaflash