Skip to content
Zwetan Kjukov edited this page Oct 29, 2017 · 8 revisions

All about projectors or static binaries.

Introduction

A projector allow you to build your ActionScript 3.0 source code into a portable one-file binary and deploy it by just copying it to the target machine.

The binary only dependency is libc (or msvcrt) and doesn't require Redtamarin to be installed on the machine.

Redtamarin projectors support the following architectures

  • Windows 32-bit (win32)
  • Windows 64-bit (win64)
  • Mac OS X 32-bit (darwin-i386)
  • Mac OS X 64-bit (darwin-amd64)
  • Linux 32-bit (i386)
  • Linux 64-bit (amd64)

Other names for "projector"

  • static binary
  • fat binary
  • one-file binary
  • standalone executable
  • independent executable
  • no-dependencies executable
  • self-running executable
  • self-contained executable

So, what is a projector really?
It is simply a runtime that embed pre-compiled code and run it by default.

In our case the runtime can be any redshell executable
and pre-compiled code can be any ABC or SWF files using the Redtamarin API.

FAQ

Q: Do I have to compile the AS3 code?
A: yes, if you want to run AS3 without compiling the code
see shell scripts
A: no, since redtamarin v0.4.2 you can build projectors with plain text .as files

Q: Can I embed multiple AS files?
A: no, you will have to merge the .as files into one file

Q: Can I embed only one ABC file?
A: yes

Q: Can I embed multiple ABC files?
A: yes, by combining them in one SWF file

Q: Can I embed multiple SWF files?
A: no

Q: Can I embed a Flash produced SWF file?
A: not with the redshell projectors,
yes with the Flash Standalone projectors
A: yes since redtamarin v0.4.2 with the Program.start( "MainClassName" ) method
and yes with the Flash Standalone projectors

Q: Do I need Visual Studio or GCC installed?
A: no

History

The term Projector comes from Flash, in fact you could often see it referred as a "Flash Projector".

It started with a feature in Adobe Flash Professional which allowed to export a SWF as an executable, later Adobe provided a Standalone Flash Player with the option to "Create Projector...".

Later, numerous softwares emerged to save swf as exe, see SWF2EXE software.

For a time, Adobe considered removing the feature

The Export Projectors feature was deprecated in Flash Professional CC June 2013 release,
and has been re-enabled in Flash Professional CC June 2014 release even if the feature was still there in the Standalone Flash Player runtime.

While the feature was disabled, a "Export as Projector" extension for Flash Pro CC was created.

See

How it Works with Flash

From the Flash Professional Help / Exporting Projector files here how Adobe describe it

About Projectors Projectors are Flash files that contain both the published SWF and Flash Player.
Projectors can play like a normal application, without the need for a web browser,
the Flash Player plugin, Adobe AIR, or any other platform runtimes.

Flash Pro CC allows you to publish Projectors for Windows and MAC operating systems.
When exported, a Projector file is generated as .exe for Windows and .app for MAC.

You have in general 2 ways to produce a projector (officially)

Flash Professional CC

  • select "Commands"
  • then "Export as Projector"

Standalone Flash Player

  • open a SWF file
  • select "File"
  • then "Create Projector..."

Manually with Mac OS X

  • copy Standalone Flash Player.app
  • option click the .app
  • select "Show Package Contents"
  • in the path Contents/Resources/
  • drop a swf file named "movie.swf"

From that point opening "Standalone Flash Player.app" will automatically play this "movie.swf".

Yes, you can rename the .app to anything you want and also change the icon.

The one thing missing in all that is the support for Linux projectors, even if it is technically possible to take a Linux Standalone Flash Player and create a projector.

How it Works with Redtamarin

The simpler approach was to use the -exe option provided in the ActionScript Compiler (ASC).

If you created an .abc file this way
$ java -jar asc.jar -AS3 -import builtin.abc -import shell_toplevel.abc program.as

then you could simply create a projector that way
$ java -jar asc.jar -AS3 -import builtin.abc -import shell_toplevel.abc -exe redshell program.as

Here the option "documentation"
-exe <avmplus path> = emit an EXE file (projector)

But there are a couple of issues with this way of doing.

With ASC you can only create a projector when you're compiling .as sources to build one .abc, if you already have an .abc file or need to produce a projector from a .swf file it will not work.

Compiler Support

In the Adobe Flex SDK, then the Apache Flex SDK, you have the ActionScript Compiler that we refer as ASC.

This one always had an option to produce a projector
-exe <avmplus path> = emit an EXE file (projector)

You can see how it is implemented in Java by reading
/src/macromedia/asc/embedding/Compiler.java
see the createProjector() function.

It's nice it's there, but technically we don't need it to be supported by the compilers.

In fact, the only support we need is inside the runtime, if the runtime support projectors then we can build our own "projector compiler".

Redtamarin Runtime Support

If you compile Redtamarin with the AVMSHELL_PROJECTOR_SUPPORT flag, the runtime will be able to access 2 functions: executeProjector() and isValidProjectorFile().

It works like that

  • while the redshell starts up
  • it will search for a "magic number" in the executable file
  • if this magic number is found
    • then the redshell knows it is a projector
    • and then knows where to read a "content length"
    • so the redshell can extract the file embedded

here the structure of a projector
| executable bytes | abc bytes | projector header |

The "projector header" is a fixed length of 8 bytes
4 bytes of "magic number, and 4 bytes of "content length"

  | projector header |
        |
        |_ magic number   = 0x56 0x34 0x12 0xFA
        |_ content length = LEN | LEN<<8 |  LEN<<16 | LEN<<24

0x56 0x34 0x12 0xFA ?
is the dword 0xFA123456 in Little Endian (least significant byte first)

In ActionScript 3.0 it would be

    //projector signature
    var header:ByteArray = new ByteArray(); //always 8 bytes
        header.writeByte( 0x56 );
        header.writeByte( 0x34 );
        header.writeByte( 0x12 );
        header.writeByte( 0xFA );
        header.writeByte(  file_len      & 0xFF );
        header.writeByte( (file_len>>8)  & 0xFF );
        header.writeByte( (file_len>>16) & 0xFF);
        header.writeByte( (file_len>>24) & 0xFF );

How do we get the "content length" ?

  • read the last 8 bytes
  • check the first 4 bytes
    equals the "magic number" 0x56 0x34 0x12 0xFA
  • the following 4 bytes
    is the "content length"

How do we extract the content from a projector ?

  • read the last 8 bytes
  • check the first 4 bytes
    equals the "magic number" 0x56 0x34 0x12 0xFA
  • from the following 4 bytes
    get the "content length"
  • from the end of the executable minus 8 bytes,
    read the content length to obtain a file

In a projector, the embedded file can either be a SWF or an ABC file,
there to validate the file we then check another "magic number"
which can be either 0x53 0x57 0x46 (SWF) or 0x53 0x57 0x43 (SWC) for a SWF file
or something like v = 46<<16|16 (another kind, more complicated) for an ABC file.

As long as the redshell can detect those "magic numbers" then it can support projectors.

see

Redtamarin Runtime Support Advanced

Because we own the source code of the runtime we can also change the way a projector is detected.

In the 0.4.2 release we changed the length of the projector header.

Now we use 12 bytes instead of 8 bytes.

TODO (more explanations)

and link to difference example of AS3 source code to detect different magic numbers

see

Tooling

redbean

TODO

Misc.

Other languages use more or less the same principle, here a non-exhaustive list compared to our own redtamarin projectors.

Language Tool Open Source Comment
PHP php2exe yes support only Windows, need Visual Studio installed
PHP bamcompile yes support only Windows, may need extra DLL
Python py2exe yes support only Windows
Python exxo yes support only Linux 64-bit (x86_64)
Python pyinstaller yes
Ruby ocra yes support only Windows, may need extra DLL
Ruby RubyScript2Exe yes support only Windows and Linux, Mac OS X is experimental

Note: our focus is only on command-line executable, but other tools provide GUI projectors.

Clone this wiki locally