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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27c71521fe4f6c7f030c3ad7f44dfcd8c5de79e759fb2aa5178132f26000fe45
|
|
| MD5 |
b750b18d8b27b590f6ee621592d05cde
|
|
| BLAKE2b-256 |
7bc008c6b0f300802439496a8d443585ad9c0fd9735edcd5fbea7f1e76296088
|
Provenance
The following attestation bundles were made for pyflashkit-1.1.0.tar.gz:
Publisher:
release.yml on bitalizer/pyflashkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflashkit-1.1.0.tar.gz -
Subject digest:
27c71521fe4f6c7f030c3ad7f44dfcd8c5de79e759fb2aa5178132f26000fe45 - Sigstore transparency entry: 1268935578
- Sigstore integration time:
-
Permalink:
bitalizer/pyflashkit@29def9c6f8c1d570d5d5a0e6c9e87e9ce8885f16 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/bitalizer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@29def9c6f8c1d570d5d5a0e6c9e87e9ce8885f16 -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93dc938befc942b25d367d05cee8407f7319ff7161e78457b8c6c8e095e7bce8
|
|
| MD5 |
4cda1f1176f03902de594e39dcf8fe82
|
|
| BLAKE2b-256 |
0521c268b75693d21c80e0a9ed3202eea88aae41800fc34c02e14f0564c36b01
|
Provenance
The following attestation bundles were made for pyflashkit-1.1.0-py3-none-any.whl:
Publisher:
release.yml on bitalizer/pyflashkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflashkit-1.1.0-py3-none-any.whl -
Subject digest:
93dc938befc942b25d367d05cee8407f7319ff7161e78457b8c6c8e095e7bce8 - Sigstore transparency entry: 1268935765
- Sigstore integration time:
-
Permalink:
bitalizer/pyflashkit@29def9c6f8c1d570d5d5a0e6c9e87e9ce8885f16 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/bitalizer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@29def9c6f8c1d570d5d5a0e6c9e87e9ce8885f16 -
Trigger Event:
push
-
Statement type: