ShockwaveFlash.Avm1
1.4.0
See the version list below for details.
dotnet add package ShockwaveFlash.Avm1 --version 1.4.0
NuGet\Install-Package ShockwaveFlash.Avm1 -Version 1.4.0
<PackageReference Include="ShockwaveFlash.Avm1" Version="1.4.0" />
<PackageVersion Include="ShockwaveFlash.Avm1" Version="1.4.0" />
<PackageReference Include="ShockwaveFlash.Avm1" />
paket add ShockwaveFlash.Avm1 --version 1.4.0
#r "nuget: ShockwaveFlash.Avm1, 1.4.0"
#:package ShockwaveFlash.Avm1@1.4.0
#addin nuget:?package=ShockwaveFlash.Avm1&version=1.4.0
#tool nuget:?package=ShockwaveFlash.Avm1&version=1.4.0
ShockwaveFlash.Avm1
AVM1 (ActionScript 1/2 bytecode) support for ShockwaveFlash. Disassemble DoAction bytecode to a mutable, strongly-typed action tree and assemble it back losslessly; dump it as p-code or best-effort AS2; and evaluate linear data scripts to a typed value tree you can edit and write back.
Install
dotnet add package ShockwaveFlash.Avm1
Disassemble to p-code or AS2
using ShockwaveFlash;
using ShockwaveFlash.Avm1.Text;
using ShockwaveFlash.Tags.Action;
var swf = ShockwaveFlashFile.Disassemble(File.ReadAllBytes("movie.swf"));
var version = swf.Header.Version;
var tag = swf.Tags.OfType<DoActionTag>().First();
string pcode = Avm1Disassembler.Disassemble(tag.Data, version, Avm1DisassemblyKind.Pcode);
string as2 = Avm1Disassembler.Disassemble(tag.Data, version, Avm1DisassemblyKind.As2);
P-code is a faithful, complete listing — every opcode with its operands, constant-pool references resolved, and function/with/try bodies decoded and indented:
ConstantPool "VERSION", "DU", "Object", "n", "m", ...
Push "VERSION"
Push 1258
SetVariable
Push "DU"
Push 0
Push "Object"
NewObject
SetVariable
AS2 is a best-effort reconstruction over the linear subset (push literals, get/set variable and member, object/array literals, operators, new/calls, function bodies). It is not a full decompiler: control flow and registers holding complex expressions fall back to their p-code line.
VERSION = 1258;
DU = new Object();
DU[1] = {n: "Donjon Bouftou", m: new Object()};
DU[1].m[2073] = {x: 0, y: 0, z: 0, n: "Salle 1", i: 900};
Evaluate a data table
Linear data scripts (localization / config tables, common in older games) are replayed to their global variables, with version-accurate value coercion:
using ShockwaveFlash.Avm1.Types;
var version = swf.Header.Version;
var tag = swf.Tags.OfType<DoActionTag>().First();
Avm1Object globals = tag.Evaluate(version);
string name = globals["EM"].AsObject["1"].AsObject["n"].AsString;
Edit & write back
Avm1Object / Avm1Array are editable in place, and primitives convert implicitly:
var globals = tag.Evaluate(version);
var emotes = globals["EM"].AsObject;
emotes["1"].AsObject["n"] = "New name"; // change
emotes["24"] = new Avm1Object { Members = { ["n"] = "New emote", ["s"] = "new" } }; // add
var output = swf.ReplaceTag(tag, tag.WithGlobals(globals, version)).Assemble();
File.WriteAllBytes("emotes.swf", output.ToArray());
Raw actions
For surgical edits that preserve everything else, go through the mutable action tree instead of the value tree. Every action is a mutable class with settable properties; function/with/try bodies are owned, so editing one action never corrupts another:
var actions = tag.DecodeActions(version); // IReadOnlyList<Action>
// ... inspect or mutate actions in place ...
var newTag = tag.WithActions(actions, version); // re-encoded; byte-identical when unchanged
Action.DecodeCollection(bytes, version) decodes leniently by default — unknown opcodes are kept as ActionUnknown, an unknown push type stops that push, and a length mismatch is tolerated. Pass strict: true to promote all of these to a typed SwfFormatException (and to reject malformed SWF6+ UTF-8 strings).
What it is — and isn't
- Faithful disassembler + assembler. The documented opcode set (SWF 1–7) round-trips byte-for-byte; the action tree is mutable, and unknown tags/opcodes are preserved.
- Version-accurate evaluator.
Avm1Machineruns the pure (branch-free) operators — arithmetic, bitwise, comparison, logic, string, type and stack ops, plus a register file — over value coercion ported faithfully from Flash (number formatting included). - Linear only. The evaluator is a data-script interpreter: no control flow, no function calls, no host/display objects. Opcodes outside that subset are recorded in
UnsupportedOpcodes(or throwAvm1UnsupportedActionExceptionwhenstrict). The AS2 listing is best-effort, not a decompiler. - AVM2 (
DoABC) is out of scope — its bytecode is kept raw by the core package.
Part of the ShockwaveFlash project · MIT © Aerafal
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- SharpCompress (>= 0.39.0)
- ShockwaveFlash (>= 1.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.