def export_single_shape(self, shape_tag, swf): from swf.movie import SWF # find a typical use of this shape example_place_objects = [x for x in swf.all_tags_of_type(TagPlaceObject) if x.hasCharacter and x.characterId == shape_tag.characterId] if len(example_place_objects): place_object = example_place_objects[0] characters = swf.build_dictionary() ids_to_export = place_object.get_dependencies() ids_exported = set() tags_to_export = [] # this had better form a dag! while len(ids_to_export): id = ids_to_export.pop() if id in ids_exported or id not in characters: continue tag = characters[id] ids_to_export.update(tag.get_dependencies()) tags_to_export.append(tag) ids_exported.add(id) tags_to_export.reverse() tags_to_export.append(place_object) else: place_object = TagPlaceObject() place_object.hasCharacter = True place_object.characterId = shape_tag.characterId tags_to_export = [ shape_tag, place_object ] stunt_swf = SWF() stunt_swf.tags = tags_to_export return super(SingleShapeSVGExporter, self).export(stunt_swf)
def execute(self, input_data): # Spin up SWF class swf = SWF() # Get the raw_bytes raw_bytes = input_data['sample']['raw_bytes'] # Parse it swf.parse(StringIO(raw_bytes)) # Header info head = swf.header output = {'version':head.version,'file_length':head.file_length,'frame_count':head.frame_count, 'frame_rate':head.frame_rate,'frame_size':head.frame_size.__str__(),'compressed':head.compressed} # Loop through all the tags output['tags'] = [tag.__str__() for tag in swf.tags] # Add the meta data to the output output.update(input_data['meta']) return output ''' # Map all tag names to indexes tag_map = {tag.name:index for tag,index in enumerate(swf.tags)} # FileAttribute Info file_attr_tag = swf.tags[tag_map] ''' '''
def export(self, swf, shape, **export_opts): """ Exports the specified shape of the SWF to SVG. @param swf The SWF. @param shape Which shape to export, either by characterId(int) or as a Tag object. """ # If `shape` is given as int, find corresponding shape tag. if isinstance(shape, Tag): shape_tag = shape else: shapes = [ x for x in swf.all_tags_of_type((TagDefineShape, TagDefineSprite)) if x.characterId == shape ] if len(shapes): shape_tag = shapes[0] else: raise Exception("Shape %s not found" % shape) from swf.movie import SWF # find a typical use of this shape example_place_objects = [ x for x in swf.all_tags_of_type(TagPlaceObject) if x.hasCharacter and x.characterId == shape_tag.characterId ] if len(example_place_objects): place_object = example_place_objects[0] characters = swf.build_dictionary() ids_to_export = place_object.get_dependencies() ids_exported = set() tags_to_export = [] # this had better form a dag! while len(ids_to_export): id = ids_to_export.pop() if id in ids_exported or id not in characters: continue tag = characters[id] ids_to_export.update(tag.get_dependencies()) tags_to_export.append(tag) ids_exported.add(id) tags_to_export.reverse() tags_to_export.append(place_object) else: place_object = TagPlaceObject() place_object.hasCharacter = True place_object.characterId = shape_tag.characterId tags_to_export = [shape_tag, place_object] stunt_swf = SWF() stunt_swf.tags = tags_to_export return super(SingleShapeSVGExporterMixin, self).export(stunt_swf, **export_opts)
def doit(inf, outf): swf = SWF(inf) # swf-in-an-swf data = getimagedata(swf) swf2 = SWF(StringIO(data)) exporter = SVGExporter() svg = swf2.export(exporter) outf.write(svg.read())
def export(self, swf, shape, **export_opts): """ Exports the specified shape of the SWF to SVG. @param swf The SWF. @param shape Which shape to export, either by characterId(int) or as a Tag object. """ # If `shape` is given as int, find corresponding shape tag. if isinstance(shape, Tag): shape_tag = shape else: shapes = [x for x in swf.all_tags_of_type((TagDefineShape, TagDefineSprite)) if x.characterId == shape] if len(shapes): shape_tag = shapes[0] else: raise Exception("Shape %s not found" % shape) from swf.movie import SWF # find a typical use of this shape example_place_objects = [x for x in swf.all_tags_of_type(TagPlaceObject) if x.hasCharacter and x.characterId == shape_tag.characterId] if len(example_place_objects): place_object = example_place_objects[0] characters = swf.build_dictionary() ids_to_export = place_object.get_dependencies() ids_exported = set() tags_to_export = [] # this had better form a dag! while len(ids_to_export): id = ids_to_export.pop() if id in ids_exported or id not in characters: continue tag = characters[id] ids_to_export.update(tag.get_dependencies()) tags_to_export.append(tag) ids_exported.add(id) tags_to_export.reverse() tags_to_export.append(place_object) else: place_object = TagPlaceObject() place_object.hasCharacter = True place_object.characterId = shape_tag.characterId tags_to_export = [ shape_tag, place_object ] stunt_swf = SWF() stunt_swf.tags = tags_to_export return super(SingleShapeSVGExporterMixin, self).export(stunt_swf, **export_opts)
def fetch_current_version(): request = urlopen( 'http://l3cdn.riotgames.com/releases/live/projects/lol_air_client/releases/releaselisting' ) versions = request.read().split('\n') url = 'http://l3cdn.riotgames.com/releases/live/projects/lol_air_client/releases/{0}/files/lib/ClientLibCommon.dat' for index in range(1, len(versions)): version = versions[index].replace('\b', '').replace('\r', '') try: request = urlopen(url.format(version)) open('ClientLibCommon.dat', 'wb').write(request.read()) break except HTTPError: continue f = open('ClientLibCommon.dat', 'rb') swf = SWF(f) for tag in swf.tags: if tag.TYPE == 82 and 'Version' in tag.abcName: start = 'CURRENT_VERSION' end = 'String' data = tag.bytes version = data[data.index(start) + len(start):data.index(end)] return version[2:len(version) - 1]
def test_header(): f = open('./test/data/test.swf', 'rb') swf = SWF(f) assert swf.header.frame_count == 1
def analyze(self, afile): '''Analyze SWF files and extract metadata about the file into the FileAnalysis object. Args: afile (FileAnalysis): The file to be analyzed. Returns: None ''' if afile.mime_type in self.analyzed_mimes: # Parse the metadata for the swf file and add all swf metadata # attributes to the FileAnalysis object. try: fp = open(afile.path, 'rb') swf = SWF(fp) process_metadata = True except IOError: afile.errors = afile.errors + [ 'swf plugin: unsupported filetype' ] afile.plugin_output[self.__NAME__] = 'None' process_metadata = False if process_metadata: tag_list = list() for tag in swf.tags: if tag.name == 'FileAttributes': setattr(afile, 'useDirectBlit', tag.useDirectBlit) setattr(afile, 'useGPU', tag.useGPU) setattr(afile, 'hasMetadata', tag.hasMetadata) setattr(afile, 'actionscript3', tag.actionscript3) setattr(afile, 'useNetwork', tag.useNetwork) elif tag.name == 'Metadata': # Iterate through xml tags and pass to regex search to easily pull out value. xml_tags = [ 'format', 'title', 'description', 'publisher', 'creator', 'language', 'date' ] for xt in xml_tags: search = re.search( r'<dc:' + xt + '>(.*)</dc:' + xt + '>', tag.xmlString, re.M | re.I) if search: setattr(afile, xt, search.group(1)) if xt == 'title': afile.plugin_output[ self.__NAME__] = search.group(1) elif tag.name == 'TagScriptLimits': setattr(afile, 'MaxRecursionDepth', tag.maxRecursionDepth) setattr(afile, 'ScriptTimeout', tag.scriptTimeoutSeconds) elif tag.name == 'TagExportAssets': setattr(afile, 'Exports', tag.exports)
def read(self, filename): assert os.path.exists(filename) self._swf = None with open(filename, 'rb') as f: self._swf = SWF(f) return self._swf
def test_export(): f = open('./test/data/test.swf', 'rb') swf = SWF(f) svg_exporter = SVGExporter() svg = svg_exporter.export(swf) assert b'<svg xmlns' in svg.read()
def __main__(): parser = argparse.ArgumentParser(description='Dump actionscript stuff.') parser.add_argument('-s', '--script_names', action='append', metavar='script', help='script name to dump') parser.add_argument('files', metavar='file', nargs='+', help='file to parse') args = parser.parse_args() if not args.files: print "Must provide a filename..." return for file_ in args.files: print "Opening file: %s" % file_ try: f = open(file_, 'rb') except Exception as e: print str(e) continue try: swiff = SWF(f) except Exception as e: print "pyswf failure: %s" % str(e) f.close() continue f.close() parser = None for tag in swiff.tags: if tag.name in ["DoABC", "DoABC2"]: parser = ABCParser.ABCParser(tag.bytes) parser.parse() #out = open("abc.as", 'wb') #out.write(tag.bytes) #out.close() break # XXX: There can be more than one DoABC tag... # XXX: Sometimes pyswf fails to parse things... :( if parser: dump_scripts(parser) dump_classes(parser) dump_methods(parser) dump_bodies(parser) dump_instances(parser) else: print "Problem finding DoABC..."
def execute(self, input_data): # Spin up SWF class swf = SWF() # Get the raw_bytes raw_bytes = input_data['sample']['raw_bytes'] # Parse it swf.parse(StringIO(raw_bytes)) # Header info head = swf.header output = { 'version': head.version, 'file_length': head.file_length, 'frame_count': head.frame_count, 'frame_rate': head.frame_rate, 'frame_size': head.frame_size.__str__(), 'compressed': head.compressed } # Loop through all the tags output['tags'] = [tag.__str__() for tag in swf.tags] # Add the meta data to the output output.update(input_data['meta']) return output ''' # Map all tag names to indexes tag_map = {tag.name:index for tag,index in enumerate(swf.tags)} # FileAttribute Info file_attr_tag = swf.tags[tag_map] ''' '''
def __init__(self, file, depthNames={}): self.depthNames = depthNames # load and parse the SWF logging.info("<SWF> Starting parse...") self.swf = SWF(open(file, 'rb')) self.alias = file.split('.')[0].split('/')[-1] self.frameRate = self.swf.header.frame_rate self.frameCount = self.swf.header.frame_count # Debug logging.debug(self.swf) # Document ELements self.shapes = [] self.sprites = [] self.frames = [] self.depths = {} for _ in range(self.frameCount): SWFDocument.Frame.addFrame(self) # Parse self.parse()
ip2.rstrip() # internalIp = ip2.split('lo:')[1].replace(' ', '') # print internalIp except: print 'We could not find internal ip of your app or your system,' \ 'problem maybe ocurred because this is working by linux system and you are using windows system' from swf.movie import SWF from swf.export import SVGExporter # create a file object file = open('C:/Users/Hamed/IGC/Desktop/trash/1.swf', 'rb') # load and parse the SWF swf = SWF(file) # print SWF(file) # create the SVG exporter svg_exporter = SVGExporter() # export! svg = swf.export(svg_exporter) # save the SVG open('C:/Users/Hamed/IGC/Desktop/trash/1.svg', 'wb').write(svg.read()) import gfx doc = gfx.open("swf", "C:/Users/Hamed/IGC/Desktop/trash/1.swf")
def swfParse(strSWFFile): for file in strSWFFile: hFile = open(file) swf = SWF(hFile) print swf.parse() hFile.close()
def __main__(): parser = argparse.ArgumentParser(description='Dump actionscript stuff.') parser.add_argument('-s', '--class_names', action='append', metavar='class', help='class name to dump') parser.add_argument('-f', '--full', action='store_true', help='full graph including methods and inits') parser.add_argument('-m', '--metadata', action='store_true', help='enable SWF metadata tags') parser.add_argument('-b', '--binaries', action='store_true', help='enable SWF binary tags') parser.add_argument('files', metavar='file', nargs='+', help='file to parse') args = parser.parse_args() if not args.files: print "[!] Must provide a filename..." return nodes = [] edges = [] binaries = {} metadata = {} bodies = {} classes = {} instances = {} for file_ in args.files: print "[+] Opening file: %s" % file_ try: f = open(file_, 'rb') except Exception as e: print "[!] %s" % str(e) continue try: swiff = SWF(f) except Exception as e: print "[!] pyswf failure: %s" % str(e) f.close() continue f.close() parser = None indexes = [] # Metadata and binary tags are stored until we have nodes returned # for ABC elements. This ensures that we don't create nodes for these # tags without also having something else meaningful. metadata_tags = [] binary_tags = [] for tag in swiff.tags: #print "Tag: %s" % tag.name if tag.name == "Metadata" and args.metadata: metadata_tags.append(tag) if tag.name == "TagDefineBinaryData" and args.binaries: binary_tags.append(tag) elif tag.name in ["DoABC", "DoABCDefine"]: if hasattr(tag, 'abcName'): print " [-] ABCName: %s" % tag.abcName parser = ABCParser.ABCParser(tag.bytes) try: parser.parse() except ABCdException as e: print "[!] Parsing error: %s" % str(e) continue indexes += dump_graph(parser, nodes, edges, args, bodies=bodies, classes=classes, instances=instances) if indexes: new_id = len(nodes) nodes.append({ 'id': new_id, 'label': os.path.basename(file_), 'color': 'purple', 'default_color': 'purple', 'level': 0 }) # Create edge between this new node and all returned indexes for index in indexes: edges.append({'from': new_id, 'to': index}) for tag in metadata_tags: # Create a node for metadata blobs. md_hash = hashlib.md5(tag.xmlString).hexdigest() if md_hash in metadata: mid_id = metadata[md_hash] else: md_id = len(nodes) metadata[md_hash] = md_id nodes.append({ 'id': md_id, 'label': md_hash, 'details': tag.xmlString, 'color': 'blue', 'default_color': 'blue', 'level': 1 }) edges.append({'from': new_id, 'to': md_id}) print " [-] Metadata: %s" % md_hash for tag in binary_tags: # Add a node for binary data blobs. bin_hash = hashlib.md5(tag.data).hexdigest() if bin_hash in binaries: bin_id = binaries[bin_hash] else: bin_id = len(nodes) binaries[bin_hash] = bin_id # Include hexdump of first 512 bytes... nodes.append({ 'id': bin_id, 'label': bin_hash, 'details': "Length: %s" % len(tag.data), 'color': 'pink', 'default_color': 'pink', 'dump': hexdump(tag.data[:512]), 'level': 1 }) edges.append({'from': new_id, 'to': bin_id}) print " [-] Binary: %s" % bin_hash else: print "[!] No nodes created..." print "[-] Nodes: %s" % len(nodes) f = open("nodes.json", 'w') f.write(json.dumps(nodes)) f.close() print "[-] Edges: %s" % len(edges) f = open("edges.json", 'w') f.write(json.dumps(edges)) f.close()
#!/usr/bin/env python """ Read coachmap.swf and export all coaches to dist/coaches/*.{svg,js}. """ from swf.movie import SWF from swf.export import SVGExporter, SingleShapeSVGExporterMixin, FrameSVGExporterMixin, NamesSVGExporterMixin from swf.tag import TagPlaceObject, TagDefineShape, TagDefineSprite, TagFrameLabel from subprocess import call import json print "Parsing..." swf = SWF(open('coachmap.swf')) # NB: the order of these mixins matter. class CoachExporter(SingleShapeSVGExporterMixin, FrameSVGExporterMixin, NamesSVGExporterMixin, SVGExporter): pass exporter = CoachExporter() # 1) Find the PlaceObject tag "floorplan". placeobject = [x for x in swf.all_tags_of_type(TagPlaceObject) if x.instanceName == 'floorplan'][0] # 2) Find corresponding DefineSprite. sprite = [x for x in swf.all_tags_of_type((TagDefineShape, TagDefineSprite)) if x.characterId == placeobject.characterId][0] # 3) Remove background (id=362) to get a tight viewbox for each coach type. sprite.tags = [t for t in sprite.tags if not hasattr(t, 'characterId') or t.characterId != 362] # 4) Remove filter from placeobject so there's something to see.
def get_data(swf): """ swf must be a SWF object """ if not isinstance(swf, SWF): print "[!] The passed parameter is not an SWF object" return None data = get_buf(swf.data) if swf.header.compressed: print "[+] Compressed SWF" # we skip the first 8-bytes from SWF header data = data[8:] return data if len(sys.argv) < 2: print "Usage: %s <filename>" % __file__ sys.exit(0) swf_filename = sys.argv[1] raw_data = read_file(swf_filename) swf_file = SWF(StringIO(raw_data)) data = get_data(swf_file) ustream = zlib.decompress(data) filename = os.path.basename(swf_filename) + ".decompressed" print "[+] Writing new SWF file: %s ..." % filename rebuild_swf_file(filename, ustream) print "[+] Done."
parser.add_argument( "--frame", type=int, help="Export frame FRAME (0-based index) instead of frame 0", required=False) parser.add_argument( "--names", action='store_true', help='For each element, extract SWF instanceName to class="n-<name>"', required=False) options = parser.parse_args() argparse.swf_file = options.swf # load and parse the SWF swf = SWF(options.swf) export_opts = {} export_mixins = [] # process the optional arguments if options.shape is not None: export_mixins.append(SingleShapeSVGExporterMixin) export_opts['shape'] = options.shape if options.frame is not None: export_mixins.append(FrameSVGExporterMixin) export_opts['frame'] = options.frame if options.names:
print ip2.rstrip() # internalIp = ip2.split('lo:')[1].replace(' ', '') # print internalIp except: print 'We could not find internal ip of your app or your system,' \ 'problem maybe ocurred because this is working by linux system and you are using windows system' from swf.movie import SWF from swf.export import SVGExporter # create a file object file = open('C:/Users/Hamed/IGC/Desktop/trash/1.swf', 'rb') # load and parse the SWF swf = SWF(file) # print SWF(file) # create the SVG exporter svg_exporter = SVGExporter() # export! svg = swf.export(svg_exporter) # save the SVG open('C:/Users/Hamed/IGC/Desktop/trash/1.svg', 'wb').write(svg.read()) import gfx doc = gfx.open("swf", "C:/Users/Hamed/IGC/Desktop/trash/1.swf") for pagenr in range(1, doc.pages + 1): page = doc.getPage(pagenr)
import argparse from swf.movie import SWF from swf.export import SVGExporter parser = argparse.ArgumentParser(description="Convert an SWF file into an SVG") parser.add_argument("--swf", type=argparse.FileType('rb'), help="Location of SWG file to convert", required=True) parser.add_argument("--svg", type=argparse.FileType('wb'), help="Location of converted SVG file", required=True) options = parser.parse_args() argparse.swf_file = options.swf # load and parse the SWF swf = SWF(options.swf) # create the SVG exporter svg_exporter = SVGExporter() # export! svg = swf.export(svg_exporter) # save the SVG options.svg.write(svg.read())
#!/usr/bin/env python """ Read coachmap.swf and export all coaches to dist/coaches/*.{svg,js}. """ from swf.movie import SWF from swf.export import SVGExporter, SingleShapeSVGExporterMixin, FrameSVGExporterMixin, NamesSVGExporterMixin from swf.tag import TagPlaceObject, TagDefineShape, TagDefineSprite, TagFrameLabel from subprocess import call import json print "Parsing..." swf = SWF(open('coachmap.swf')) # NB: the order of these mixins matter. class CoachExporter(SingleShapeSVGExporterMixin, FrameSVGExporterMixin, NamesSVGExporterMixin, SVGExporter): pass exporter = CoachExporter() # 1) Find the PlaceObject tag "floorplan". placeobject = [ x for x in swf.all_tags_of_type(TagPlaceObject) if x.instanceName == 'floorplan' ][0] # 2) Find corresponding DefineSprite. sprite = [
def execute(self, request): self.request = request request.result = Result() self.result = self.request.result file_path = self.request.download() fh = open(file_path, 'rb') try: self.swf = SWF(fh) if self.swf is None: raise except: self.log.exception("Unable to parse srl %s:" % self.request.srl) fh.close() raise self.tag_summary = defaultdict(list) self.symbols = {} self.binary_data = {} self.exported_assets = [] self.big_buffers = set() self.has_product_info = False self.anti_decompilation = False self.recent_compile = False self.disasm_path = None header_subsection = ResultSection(score=0, title_text="SWF Header") header_subsection.add_line("Version: %d" % self.swf.header.version) header_subsection.add_line("FileLength: %d" % self.swf.header.file_length) header_subsection.add_line("FrameSize: %s" % self.swf.header.frame_size.__str__()) header_subsection.add_line("FrameRate: %d" % self.swf.header.frame_rate) header_subsection.add_line("FrameCount: %d" % self.swf.header.frame_count) self.result.add_section(header_subsection) # Parse Tags tag_types = [] for tag in self.swf.tags: self.tag_analyzers.get(SWF_TAGS.get(tag.type), self._dummy)(tag) tag_types.append(str(tag.type)) tag_list = ','.join(tag_types) tags_ssdeep = ssdeep.hash(tag_list) _, hash_one, hash_two = tags_ssdeep.split(':') self.result.add_tag(tag_type=TAG_TYPE.SWF_TAGS_SSDEEP, value=hash_one, weight=TAG_WEIGHT.NULL) self.result.add_tag(tag_type=TAG_TYPE.SWF_TAGS_SSDEEP, value=hash_two, weight=TAG_WEIGHT.NULL) # Script Overview if len(self.symbols.keys()) > 0: root_symbol = 'unspecified' if 0 in self.symbols: root_symbol = self.symbols[0] self.symbols.pop(0) symbol_subsection = ResultSection(score=SCORE.NULL, title_text="Symbol Summary") symbol_subsection.add_line('Main Timeline: %s' % root_symbol) if len(self.symbols.keys()) > 0: symbol_subsection.add_line('Other Symbols:') for tag_id, name in self.symbols.iteritems(): symbol_subsection.add_line('\tTagId: %s\tName: %s' % (tag_id, name)) self.result.add_section(symbol_subsection) if len(self.binary_data.keys()) > 0: self.result.report_heuristic(Swiffer.AL_Swiffer_003) binary_subsection = ResultSection( score=SCORE.NULL, title_text="Attached Binary Data") for tag_id, tag_data in self.binary_data.iteritems(): tag_name = self.symbols.get(tag_id, 'unspecified') binary_subsection.add_line('\tTagId: %s\tName: %s\tSize: %d' % (tag_id, tag_name, len(tag_data))) try: binary_filename = hashlib.sha256( tag_data).hexdigest() + '.attached_binary' binary_path = os.path.join(self.working_directory, binary_filename) with open(binary_path, 'w') as fh: fh.write(tag_data) self.request.add_extracted( binary_path, "SWF Embedded Binary Data %d" % tag_id, tag_name) except: self.log.exception( "Error submitting embedded binary data for swf:") self.result.add_section(binary_subsection) tags_subsection = ResultSection(score=SCORE.INFO, title_text="Tags of Interest") for tag in sorted(self.tag_summary.keys()): tags_subsection.add_line(tag) summaries = self.tag_summary[tag] for summary in summaries: summary_line = '\t' + '\t'.join(summary) tags_subsection.add_line(summary_line) tags_subsection.add_line('') if len(tags_subsection.body) > 0: self.result.add_section(tags_subsection) if len(self.big_buffers) > 0: self.result.report_heuristic(Swiffer.AL_Swiffer_001) bbs = ResultSection(score=SCORE.HIGH, title_text="Large String Buffers") for buf in self.big_buffers: bbs.add_line("Found a %d byte string." % len(buf)) buf_filename = "" try: buf_filename = hashlib.sha256( buf).hexdigest() + '.stringbuf' buf_path = os.path.join(self.working_directory, buf_filename) with open(buf_path, 'w') as fh: fh.write(buf) self.request.add_extracted(buf_path, "AVM2 Large String Buffer.") except: self.log.exception( "Error submitting AVM2 String Buffer %s" % buf_filename) self.result.add_section(bbs) if not self.has_product_info: self.log.debug("Missing product info.") no_info = ResultSection(score=SCORE.INFO, title_text="Missing Product Information") no_info.add_line( "This SWF doesn't specify information about the product that created it." ) self.result.add_section(no_info) if self.anti_decompilation: self.result.report_heuristic(Swiffer.AL_Swiffer_004) self.log.debug("Anti-disassembly techniques may be present.") no_dis = ResultSection(score=SCORE.LOW, title_text="Incomplete Disassembly") no_dis.add_line( "This SWF may contain intentional corruption or obfuscation to prevent disassembly." ) self.result.add_section(no_dis) if self.recent_compile: recent_compile = ResultSection(score=SCORE.LOW, title_text="Recent Compilation") recent_compile.add_line( "This SWF was compiled within the last 24 hours.") self.result.add_section(recent_compile) self.result.report_heuristic(Swiffer.AL_Swiffer_002) fh.close()
#!/usr/bin/env python #!/usr/bin/python #!python from swf.actions import ActionGetURL from swf.movie import SWF from swf.tag import TagDefineButton2 import sys import argparse parser = argparse.ArgumentParser(description="Read and output the URLs linked to in a SWF file.") parser.add_argument("--swf", type=argparse.FileType('rb'), help="Location of SWF file to parse", required=True) options = parser.parse_args() # Load and parse the SWF. swf = SWF(options.swf) # Print all of the URLs that are targeted via ActionGetURL actions on Button2 tags. for button in swf.all_tags_of_type(TagDefineButton2): for buttonAction in button.buttonActions: for action in buttonAction.actions: if isinstance(action, ActionGetURL): print action.urlString