Beginner’s guide to SWF internals

! Warning: this post hasn't been updated in over three years and so may contain out of date information.

I have recently pushed the initial version of a new framework – the AS3Introspection library – up to github. AS3Introspection can decode a SWF and generate a representation – by default as XML – of its code contents. Whilst writing an introduction to AS3Introspection, it occurred to me that for someone to understand how it works, they would need at least a basic understanding of the internals of a SWF. I have therefore written this article to hopefully provide that basic understanding.

The contents of a SWF is simple in principle and complex in practice. In order to keep SWFs as small as possible back in the dark old days of 56K or slower modems, the developers at Macromedia, and in turn Adobe, have used some clever but complex techniques to pack data into as few bytes as possible. For example, a basic data type within a SWF is the Rectangle record. This structure uses five bits to define the size – in bits – of each of the four coordinate values of the rectangle. So if those first five bits were 00111, (which is 7 in decimal) then the Xmin value would be spread across the last 3 bits of that first byte and the first four bits of the next byte!

Luckily for us mere mortals, we don’t need to worry about these details in order to explore the internals of a SWF. Other folk have written frameworks like the AS3Commons library, which decode these complicated structures for us and present them as simpler AS3 data types. So to delve into the internals of a SWF, one need only have knowledge of the simpler principles, which is what I’ll try to describe here.

As shown in the diagram below, the basic structure of a SWF consists of a header and a series of blocks of data known as tags.

SWF Internal structure showing header and tags

The header contains information such as the target flash player version, the size of the file, whether the tags are compressed or not etc. We can safely ignore this information here, so I’ll mention the header no further.

The tags form the bulk of the contents of the SWF. There are a great many types of tag for things such as images, sounds, the time line and the like. There is one particular tag though that is of interest to anyone wanting to know about the code within a SWF. That tag is the DoABC tag and it contains the AS3 code contained within a SWF. Adobe introduced the DoABC tag with Flash Player 9. Prior to that, code was contained within DoAction tags. This latter tag is effectively now deprecated and can be ignored. Incidentally, if you are curious as to why the DoABC tag is named thus, “ABC” stands for ActionScript Byte Code. So in crude terms, we can view a SWF as containing some boring stuff that we do not care about and a series of DoABC tags, which we do care about.

So what is in a DoABC tag? In most cases, there is a simple one to one mapping between an ActionScript .as file and a .abc “file” contained within the DoABC tag. The reason for saying in most cases is because:

  1. The AS3 specification imposes restrictions on the contents of .as file
  2. The specification of the DoABC tag doesn’t have these same restrictions, and
  3. Adobe themselves ignore those restrictions for SWFs within some SWCs within the SDK

I’ll mention more about those special case SWCs in another post on AS3Introspection, for they cause problems with AS3Commons and so, in turn, cause AS3Introspection problems too. For now though, it’s best to concentrate on the more common one to one mapping, so the rest of this article will focus on those AS3-compliant DoABC tags therefore.

To understand the contents of a DoABC tag, it’s necessary to introduce another term: trait. Traits correspond to the following list of things within AS3:

  • functions/ methods
  • classes
  • interfaces
  • constants
  • variables
  • namespaces
  • getters
  • setters

A DoABC tag will contain some optional metadata and a list of traits. Exactly one of those traits will be either a public or internal definition of one of the above “things”. All other traits will be private. This is shown in the diagram below:

Contents of a DoABC tag showing the traits

Now this might sound a bit odd because you are probably used to the idea that an .as file contains a class with many public members. The explanation is that the class is the public (or internal) trait and its contents are nested within its trait details. The following is an extreme, but completely valid, example of an .as file that illustrates the point:

There are a two aspects to the contents of this file that may be unfamiliar to you. First, there is a lost of content that is defined outside the package. Second, the package only defines a variable; not a class or interface. An .as file must contain exactly one package definition and within that, exactly one trait. There is no requirement to put a class or interface inside that package definition as you’ll know if you have ever defined a namespace. It is possible – though really undesirable – to create global variables and functions via this method. The variable z in the above example is one such global variable. As well as the package definition, an .as file is free to contain any number of traits outside of the package definition. The consequence of being outside of the package is that all such traits are marked private and are only accessible to other traits within the .as file. So the DoABC tag for the above file would look like the following:

Details of DoABC equivalent of the previous code

So in conclusion, a SWF file can be viewed as containing a bunch of DoABC tags, each of which can contain a bunch of traits. This is pretty much how AS3Introspection presents the contents of a SWF. It’s a simplification of course, but ought to be enough to allow a person to make sense of AS3Introspection. If this article has prompted you to want to know more though, then Adobe’s official documentation is the place to turn:

  1. SWF File Format Specification Version 10
  2. ActionScript Virtual Machine 2 (AVM2) Overview