RABCDAsm
Robust ABC (ActionScript Bytecode) [Dis-]Assembler
Install / Use
/learn @CyberShadow/RABCDAsmREADME
Robust ABC (ActionScript Bytecode) [Dis-]Assembler
RABCDAsm is a collection of utilities including an ActionScript 3 assembler/disassembler, and a few tools to manipulate SWF files. These are:
rabcdasm- ABC disassemblerrabcasm- ABC assemblerabcexport- extracts ABC from SWF filesabcreplace- replaces ABC in SWF filesswfdecompress- decompresses zlib-compressed SWF filesswf7zcompress- (re-)compress the contents of a SWF using 7-Zipswflzmacompress- compress the contents of a SWF using LZMAswfbinexport/swfbinreplace- extract/replace contents of binary data tags from SWF files
abcexport and abcreplace are reimplementations of similar utilities from
my swfutilsex Java package, however these work faster as they do not parse
the SWF files as deeply.
swfdecompress is ancillary and is only useful for debugging and studying of
the SWF file format, and not required for ABC manipulation. It is functionally
equivalent to flasm's -x option. If you frequently work on compressed
SWF files, you may want to decompress them to speed processing up.
swf7zcompress is an utility to further reduce the size of SWF files. It uses
7-Zip to compress the data better than the standard zlib library would. It
requires that the 7z command-line program be installed and in PATH.
swflzmacompress compresses SWF files using the LZMA algorithm, support
for which was introduced in Flash 11. It will only work with SWF files with
version 13 or higher.
swfbinexport and swfbinreplace aid in the manipulation of
DefineBinaryData tags in SWF files (some files may contain nested SWF files
stored in these tags).
Motivation and goals
This package was created due to lack of similar software out there. Particularly, I needed an utility which would allow me to edit ActionScript 3 bytecode with the following properties:
- Speed. Less waiting means more productivity.
rabcasmcan assemble large projects (>200000 LOC) in under a second on modern machines. - Comfortably-editable output. Each class is decompiled to its own file,
with files arranged in subdirectories representing the package hierarchy.
Class files are
#included from the main file. - Most importantly - robustness! If the Adobe AVM can load and run the file, then it must be editable - no matter if the file is obfuscated or otherwise mutilated to prevent reverse-engineering. RABCDAsm achieves this by using a textual representation closer to the ABC file format, rather than to what an ActionScript compiler would generate.
Compiling from source
RABCDAsm is written in the D programming language, version 2.
Assuming you have git and a D2 compiler, such as dmd or gdc installed, compiling should be as straight-forward as:
git clone git://github.com/CyberShadow/RABCDAsm.git
cd RABCDAsm
dmd -run build_rabcdasm.d
Substitute dmd with gdmd if you're using gdc. You can use the DC and
DCFLAGS environment variables to override the detected compiler and default
compilation flags (-O -inline).
To be able to manipulate SWF files packed with LZMA compression, you'll need to have the liblzma library and development files installed on your system.
Note: DMD 2.066 is required for long path support on Windows since RABCDAsm 1.16.
Pre-compiled binaries
You can find pre-compiled Windows binaries on my website. However, please don't expect them to be up-to-date with the latest source versions.
Usage
To begin hacking on a SWF file:
abcexport file.swf
This will create file-0.abc ... file-N.abc (often just file-0.abc). Each
file corresponds to an ABC block inside the SWF file.
To disassemble one of the .abc files:
rabcdasm file-0.abc
This will create a file-0 directory, which will contain file-0.main.asasm
(the main program file) and files for ActionScript scripts, classes, and
orphan and script-level methods.
To assemble the .asasm files back, and update the SWF file:
rabcasm file-0/file-0.main.asasm
abcreplace file.swf 0 file-0/file-0.main.abc
The second abcreplace argument represents the index of the ABC block in the
SWF file, and corresponds to the number in the filename created by abcexport.
swfbinexport and swfbinreplace are used in the same manner as abcexport
and abcreplace.
Syntax
The syntax of the disassembly was designed to be very simple and allow fast
and easy parsing. It is a close representation of the .abc file format, and
thus it is somewhat verbose. All constant pool elements (signed/unsigned
integers, doubles, strings, namespaces, namespace sets, multinames) are always
expanded inline, for ease of editing. Similarly, classes, instances, methods
and method bodies are also defined inline, in the context of their "parent"
object. By-index references of classes and methods (used in the newclass,
newfunction and callstatic instructions) are represented via
automatically-generated unique "reference strings", declared as refid fields.
If you haven't yet, I strongly recommend that you look through Adobe's ActionScript Virtual Machine 2 (AVM2) Overview. You will most likely need to consult it for the instruction reference anyway (although you can also use this handy list as well). You will find it difficult to understand the disassembly without good understanding of concepts such as namespaces and multinames.
Overview
In order to guarantee unambiguity and data preservation, all strings read from the input file - including identifiers (variable/function/class names) - are represented as string literals. Thus, the syntax does not have any "reserved words" or such - an unrecognized word is treated as an error, not as an identifier.
Whitespace (outside string literals, of course) is completely ignored, except
where required to separate words. Comments are Intel-assembler-style: a single
; demarks a comment until the next end-of-line. Control directives (such as
#include) are allowed anywhere where whitespace is allowed.
The syntax is comprised of hierarchical blocks. Each block contains a number
of fields - starting with a keyword specifying the field type. A block is
terminated with the end keyword. Some fields contain a limited number of
parameters, and others are, or contain blocks.
Hierarchy
The topmost block in the hierarchy is the program block. This must be the
first block in the file (thus, program must be the first word in the file as
well). The program block contains script fields, and class / method
fields for "orphan" classes and methods (not owned by other objects in the
hierarchy). Orphan methods are usually anonymous functions. The file version
is also specified in the program block, using the minorversion and
majorversion fields (both unsigned integers).
script blocks have one mandatory sinit field (the script initialization
method) and trait fields.
A "trait" can be one of several kinds. The kind is specified right after the
trait keyword, followed by the trait name (a multiname). Following the name
are the trait fields, varying by trait kind:
slot/const:slotid(unsigned integer),type(multiname),valueclass:slotid,class(the actual class block)function:slotid,method(the actual method block)method/getter/setter:dispid(unsigned integer),method
Additionally, all traits may have flag fields, describing the trait's
attributes (FINAL / OVERRIDE / METADATA), and metadata blocks.
metadata blocks (which are ignored by the AVM) consist of a name string, and
a series of item fields - each item having a key and value string.
class blocks have mandatory instance and cinit fields, defining the
class instance and the class initializer method respectively. They may also
have trait fields and a refid field (the refid field is not part of the
file format - it's an unique string to allow referencing the class, see above).
instance blocks - always declared inline of their class block - must
contain one iinit field (the instance initializer method), and may contain
one extends field (multiname), implements fields (multinames), flag
fields (SEALED / FINAL / INTERFACE / PROTECTEDNS), one protectedns
field (namespace), and trait fields.
method blocks may contain one name field (multiname), a refid field,
param fields (multinames - this represents the parameter types), one
returns field (multiname), flag fields (NEED_ARGUMENTS /
NEED_ACTIVATION / NEED_REST / HAS_OPTIONAL / SET_DXNS /
HAS_PARAM_NAMES), optional fields (values), paramname fields (strings),
and a body field (method body).
body blocks - always declared inline of their method block - must contain
the maxstack, localcount, initscopedepth and maxscopedepth fields
(unsigned integers), and a code field. It may also contain try and trait
fields.
code
Related Skills
node-connect
341.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
341.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.5kCommit, push, and open a PR
