Skip to main content

SWF/ABC toolkit for parsing, analyzing, and manipulating Flash files and AVM2 bytecode

Project description

flashkit

Parse, analyze, and manipulate Adobe Flash SWF files and AVM2 bytecode.

Install

pip install pyflashkit

Or from source:

git clone https://github.com/bitalizer/pyflashkit.git
cd pyflashkit
pip install -e .

Quick start

from flashkit.workspace import Workspace

ws = Workspace()
ws.load_swf("application.swf")

# Find all classes extending Sprite
for cls in ws.find_classes(extends="Sprite"):
    print(f"{cls.qualified_name}{len(cls.fields)} fields, {len(cls.methods)} methods")

# Inspect a specific class
player = ws.get_class("PlayerManager")
print(player.super_name)    # "EventDispatcher"
print(player.interfaces)    # ["IDisposable", "ITickable"]
print(player.fields[0].name, player.fields[0].type_name)  # "mHealth", "Number"

# Search strings used in bytecode
for s in ws.search_strings("config"):
    print(s)

CLI

flashkit info

$ flashkit info application.swf
File: application.swf
  Format:     SWF
  SWF version: 40
  Tags:       142
  ABC blocks: 1
  Classes:    823
  Methods:    14210
  Strings:    35482
  Packages:   47

flashkit classes

flashkit classes app.swf                # all classes
flashkit classes app.swf -s Manager     # search by name
flashkit classes app.swf -p com.game    # filter by package
flashkit classes app.swf -e Sprite      # filter by superclass
flashkit classes app.swf -i             # interfaces only
flashkit classes app.swf -v             # verbose output

flashkit class

$ flashkit class application.swf PlayerManager
PlayerManager
  Package: com.game
  Extends: EventDispatcher
  Implements: IDisposable, ITickable

  Instance Fields (3)
    mHealth: Number
    mName: String
    mLevel: int

  Instance Methods (5)
    init(): void
    get name(): String
    set name(value: String): void
    takeDamage(amount: Number): void
    serialize(): ByteArray

flashkit strings

flashkit strings app.swf                # list all
flashkit strings app.swf -s config      # search
flashkit strings app.swf -s config -v   # with usage locations
flashkit strings app.swf -s "\\d+" -r   # regex
flashkit strings app.swf -c             # classify (URLs, debug)

flashkit tags

flashkit tags app.swf

flashkit disasm

flashkit disasm app.swf --class PlayerManager
flashkit disasm app.swf --method-index 42

flashkit tree

flashkit tree app.swf BaseEntity              # show descendants
flashkit tree app.swf PlayerManager -a        # show ancestors

flashkit callers / flashkit callees

flashkit callers app.swf toString
flashkit callees app.swf PlayerManager.init

flashkit refs

flashkit refs app.swf Point

flashkit fields

flashkit fields app.swf PlayerManager              # field access summary (R/W counts)
flashkit fields app.swf PlayerManager -c            # constructor assignments in order
flashkit fields app.swf PlayerManager -f mHealth    # who reads/writes a specific field
flashkit fields app.swf PlayerManager -m takeDamage # what fields a method accesses

flashkit packages / flashkit extract / flashkit build

flashkit packages app.swf                     # list packages
flashkit extract app.swf -o ./output          # extract ABC blocks
flashkit build app.swf -o rebuilt.swf         # rebuild (compressed)
flashkit build app.swf -o out.swf -d          # rebuild (decompressed)

Library

Load and query

from flashkit.workspace import Workspace

ws = Workspace()
ws.load_swf("application.swf")
ws.load_swz("module.swz")

print(ws.summary())

cls = ws.get_class("MyClass")
print(cls.name, cls.super_name, cls.interfaces)
print(cls.fields)   # list of FieldInfo
print(cls.methods)  # list of MethodInfoResolved

ws.find_classes(extends="Sprite")
ws.find_classes(package="com.example", is_interface=True)

Search and analysis

All analysis is accessed directly through the Workspace — no separate imports needed.

# Inheritance
ws.get_subclasses("BaseEntity")
ws.get_descendants("BaseEntity")       # transitive
ws.get_ancestors("PlayerManager")
ws.get_implementors("ISerializable")

# Call graph
ws.callers("toString")
ws.callees("PlayerManager.init")

# References
ws.references_to("Point")
ws.references_from("PlayerManager")
ws.find_instantiators("Point")
ws.find_type_users("ByteArray")

# Strings
ws.search_strings("config")
ws.classes_using_string("http://example.com")
ws.strings_in_class("PlayerManager")

# Field access
ws.field_writers("PlayerManager", "mHealth")
ws.field_readers("PlayerManager", "mHealth")
ws.fields_written_by("PlayerManager", "takeDamage")
ws.fields_read_by("PlayerManager", "takeDamage")
ws.constructor_assignments("PlayerManager")
ws.field_access_summary("PlayerManager")

# Structural
ws.find_classes_with_field_type("ByteArray")
ws.find_methods(return_type="String", name="get")
ws.find_fields(type_name="int")
Parse SWF and ABC directly
from flashkit.swf import parse_swf, TAG_DO_ABC2
from flashkit.abc import parse_abc, serialize_abc

header, tags, version, length = parse_swf(swf_bytes)

for tag in tags:
    if tag.tag_type == TAG_DO_ABC2:
        null_idx = tag.payload.index(0, 4)
        abc = parse_abc(tag.payload[null_idx + 1:])
        print(f"{len(abc.instances)} classes, {len(abc.methods)} methods")

        # Round-trip fidelity: serialize(parse(data)) == data
        assert serialize_abc(abc) == tag.payload[null_idx + 1:]
Build SWF programmatically
from flashkit.abc import AbcBuilder, serialize_abc
from flashkit.swf import SwfBuilder

b = AbcBuilder()
b.simple_class("Player", package="com.game",
               fields=[("hp", "int"), ("name", "String")])
b.script()
abc_bytes = serialize_abc(b.build())

swf = SwfBuilder(version=40, width=800, height=600, fps=30)
swf.add_abc("GameCode", abc_bytes)
swf_bytes = swf.build(compress=True)
Disassemble method bodies
from flashkit.abc import decode_instructions

for body in abc.method_bodies:
    for instr in decode_instructions(body.code):
        print(f"0x{instr.offset:04X}  {instr.mnemonic}  {instr.operands}")

Project structure

flashkit/
  cli/           CLI (one module per command)
  swf/           SWF container (parse, build, tags)
  abc/           AVM2 bytecode (parse, write, disasm, builder)
  info/          Resolved class model (ClassInfo, FieldInfo, MethodInfo)
  workspace/     File loading and class index
  analysis/      Inheritance, call graph, references, strings, field access

References

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyflashkit-1.2.0.tar.gz (98.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyflashkit-1.2.0-py3-none-any.whl (89.6 kB view details)

Uploaded Python 3

File details

Details for the file pyflashkit-1.2.0.tar.gz.

File metadata

  • Download URL: pyflashkit-1.2.0.tar.gz
  • Upload date:
  • Size: 98.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyflashkit-1.2.0.tar.gz
Algorithm Hash digest
SHA256 c1cc555ae3055b7b73d030f259e6037ff6f34ea4f83a90d0c76759838acb827d
MD5 d32cb5deec17e6a4c8753feaadeba55c
BLAKE2b-256 d00a1c4e3f354dbc386878ea83555c7864a53f8babfaabde579d53aed327920b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyflashkit-1.2.0.tar.gz:

Publisher: release.yml on bitalizer/pyflashkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyflashkit-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: pyflashkit-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 89.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyflashkit-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8a1f6a37fe842e90e7f2ce405c925a42485c0cd7d5fd0e371a142e824131bd6e
MD5 14bb27f7cdd2654a2d78d7e9134a4536
BLAKE2b-256 4a2b4befe55a663bdb5bbcf0d6710d94fc5a1fa4ac2dd918f4ab5037937b061b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyflashkit-1.2.0-py3-none-any.whl:

Publisher: release.yml on bitalizer/pyflashkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page