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.1.0.tar.gz (87.2 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.1.0-py3-none-any.whl (79.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pyflashkit-1.1.0.tar.gz
Algorithm Hash digest
SHA256 27c71521fe4f6c7f030c3ad7f44dfcd8c5de79e759fb2aa5178132f26000fe45
MD5 b750b18d8b27b590f6ee621592d05cde
BLAKE2b-256 7bc008c6b0f300802439496a8d443585ad9c0fd9735edcd5fbea7f1e76296088

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyflashkit-1.1.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.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyflashkit-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 79.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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93dc938befc942b25d367d05cee8407f7319ff7161e78457b8c6c8e095e7bce8
MD5 4cda1f1176f03902de594e39dcf8fe82
BLAKE2b-256 0521c268b75693d21c80e0a9ed3202eea88aae41800fc34c02e14f0564c36b01

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyflashkit-1.1.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