Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- '''A very crude Flash Debugger in Python, usable with BlackBerry PlayBook simulator.'''
- # Copyright 2010 Peter Hansen (http://peterhansen.ca)
- # Released under the Simplified BSD License: http://www.opensource.org/licenses/bsd-license.php
- from __future__ import print_function
- import sys
- import struct
- from socket import *
- from threading import Thread
- __version__ = '0.2'
- MSG_NAME = {
- 0x00: 'menu state', #dd ?, dd ?
- 0x01: 'property', #dd addr, dw propertyIndex, sz value
- 0x02: 'exit', #
- 0x03: 'create anonymous object', #dd addr
- 0x04: 'remove object', #dd addr
- 0x05: 'trace', #sz msg
- 0x06: 'target error', #sz error
- 0x07: 'recursion depth error', #
- 0x08: 'with error', #
- 0x09: 'proto limit error', #
- 0x0A: 'set field', #dd addr, sz name, amf value
- 0x0B: 'delete field', #dd addr, sz name
- 0x0C: 'movie attribute', #sz name, sz value
- 0x0D: 'place object', #dd addr, sz name
- 0x0E: 'SWD file entry', #dd fileID, dd unknownIndex, sz name, sz sourceCode, dd swfIndex
- 0x0F: 'ask breakpoints', #
- 0x10: 'breakpoint hit', #dw fileID, dw line, dd addr, sz funcName
- 0x11: 'break', #
- 0x12: 'set local vars', #dd addr address of an object containing the named local variables of the current scope
- 0x13: 'breakpoints', #dd count, (dw fileID, dw line)[count]
- 0x14: 'num swd file entries', #dd num, dd swfIndex
- 0x15: 'remove SWD file entry', #dd fileID
- 0x16: 'remove breakpoint', #dd count, (dw fileID, dw line)[count]
- 0x17: 'not synced', #Sent if the debug ID in the .swf does not match the SWD ID in the .swd
- 0x18: 'URL open error', #sz error
- 0x19: 'process tag', #
- 0x1A: 'version', #dd majorVersion, db 4
- 0x1B: 'breakpoint hit ex', #dw fileID, dw line, dd callDepth, (dw fileID, dw line, dd thisAddr, sz callstackentry)[callDepth]
- 0x1C: 'set field 2', #addr, sz name, amf value
- 0x1D: 'squelch', #dd enabled
- 0x1E: 'get field', #dd addr, sz name, amf value, (sz memberName, amf memberValue)*
- 0x1F: 'function frame', #dd callDepth, #if(callDepth > -1) dd numRegs, reg registers[numRegs] #endif, dd addr, amf value, (sz childName, amf childValue)* contains two meta children that serve as start markers: one named "$arguments" and one named "$scopechain"
- 0x20: 'debugger option', #sz name, sz value
- 0x21: 'watch', #dw success, dw oldFlags, dw oldTag, dw flags, dw tag, dw addr, sz name
- 0x22: 'SWF image', #.swf file contents
- 0x23: 'SWD image', #.swd file contents
- 0x24: 'exception', #dd 0, sz exception
- 0x25: 'stack underflow', #dd 0
- 0x26: 'divide by 0', #dd 0
- 0x27: 'script stuck', #
- 0x28: 'suspend reason', #dw reason, dw swfIndex, dd offset, dd prevLineOffset, dd nextLineOffset
- 0x29: 'actions', #dw swfIndex, dw reserved, dd offset, dd size, db data[size] deprecated/not implemented, will be empty
- 0x2A: 'SWF info', #dw swfcount, (dd swfIndex, dd addr, #if(addr) db debugComing, db vmVersion, dw reserved, dd swfSize, dd swdSize, dd numSWDs, dd numLines, dd numBreakpoints, dd port, sz path, sz url, sz host, dd swdfilecount, (dd swdLocalIndex, dd swdFileID)[swdfilecount] #endif)[swfcount] addr == 0 means swf was unloaded
- 0x2B: 'constant pool', #dw swfIndex, dd count, (dd id, sz name, amf value)[count]
- 0x2C: 'console error', #sz error
- 0x2D: 'function info', #dd fileID, dd count, (dd offset, dd firstLine, dd lastLine, sz name)[count]
- 0x2E: '?', #
- 0x2F: '?', #
- 0x30: '?', #
- 0x31: '?', #
- 0x32: '?', #
- 0x33: '?', #
- 0x34: '?', #
- 0x35: '?', #
- 0x36: '?', #
- 0x37: 'watch 2' #dw success, dw oldFlags, dw oldTag, dw flags, dw tag, dd addr, sz name
- }
- COMMANDS = {
- 0x00: 'zoom in', #
- 0x01: 'zoom out', #
- 0x02: 'zoom 100%', #
- 0x03: 'home', #
- 0x04: 'set quality', #sz quality="LOW"/"MEDIUM"/"HIGH"/"AUTOLOW"/"AUTOMEDIUM"/"AUTOHIGH"/"BEST"
- 0x05: 'play', #
- 0x06: 'loop', #
- 0x07: 'rewind', #
- 0x08: 'forward', #
- 0x09: 'back', #
- 0x0A: 'print', #
- 0x0B: 'set field', #dd addr, sz name, sz type="string"/"number"/"boolean"/"null", sz value For "number", value can be "Infinity", "-Infinity" or "NaN"
- 0x0C: 'set property', #dd addr, dw propIndex, sz type="string"/"number"/"boolean"/"null", sz value For "number", value can be "Infinity", "-Infinity" or "NaN"
- 0x0D: 'end debugging session', #
- 0x0E: 'request properties', #dd addr
- 0x0F: 'continue', #
- 0x10: 'suspend', #
- 0x11: 'set breakpoint', #dd ignored, dw fileID, dw line
- 0x12: 'clear breakpoint', #dd ignored, dw fileID, dw line
- 0x13: 'clear all breakpoints', #
- 0x14: 'step over', #
- 0x15: 'step into', #
- 0x16: 'step out', #
- 0x17: 'processed tag', #
- 0x18: 'set squelch', #dd squelchOn
- 0x19: 'get field', #dd addr, sz name [, dd flags] flags: 1=fire getter, 2=also get children, 4=? (always set)
- 0x1A: 'get function frame', #dd calldepth
- 0x1B: 'get debugger option', #sz name
- 0x1C: 'set debugger option', #sz name, sz value
- 0x1D: 'add watch', #dw addr, sz name, dw flags, dw tag
- 0x1E: 'remove watch', #dw addr, sz name
- 0x1F: 'step continue', #
- 0x20: 'get SWF file content', #dw swfIndex
- 0x21: 'get SWD file content', #dw swfIndex
- 0x22: 'get field which invokes getter', #dd addr, sz name [, dd flags] flags: 1=fire getter, 2=also get children, 4=? (always set)
- 0x23: 'get suspend reason', #
- 0x24: 'get actions', #dd swfIndex, dw reserved, dd offset, dd size deprecated/not implemented, sends back an empty "actions" reply
- 0x25: 'set actions', #dd swfIndex, dw reserved, dd offset, dd size, db data[size] deprecated/not implemented, sends back an empty "actions" reply
- 0x26: 'get SWF info', #dw swfIndex, dw 0
- 0x27: 'get constant pool', #dw swfIndex
- 0x28: 'get function info', #dd swdID, dd lineNum lineNum =< 0: all functions
- 0x29: '?', #
- 0x2A: '?', #
- 0x2B: '?', #
- 0x2C: '?', #
- 0x2D: '?', #
- 0x2E: '?', #
- 0x2F: '?', #
- 0x30: '?', #
- 0x31: 'add watch 2', #dd addr, sz name, dw flags, dw tag flags: 1=read, 2=write, 3=both. tag: for identification, choose one
- 0x32: 'remove watch 2', #dd addr, sz name
- 0x33: '?', #
- 0x34: '?',
- }
- def main():
- s = socket(AF_INET, SOCK_STREAM)
- #~ s.settimeout(500)
- s.bind(('', 7935))
- s.listen(5)
- clientnum = 0
- while 1:
- #~ print('listening on 7935')
- sock, client = s.accept()
- clientnum += 1
- print('-' * 40)
- print('connection %s from %s' % (clientnum, client))
- cthread = Thread(target=run_client, args=(clientnum, sock))
- cthread.daemon = True
- cthread.start()
- def run_client(clientnum, sock, _print=print):
- def print(*args):
- _print('[%s]' % clientnum, *args)
- while 1:
- data = sock.recv(8)
- if not data:
- break
- length, id = struct.unpack('LL', data)
- msgtype = MSG_NAME.get(id, 'unknown')
- if length:
- if length < 1000000:
- data = sock.recv(length)
- else:
- print('length too large at %s (from %r)' % (length, data))
- break # ignore and quite
- else:
- data = ''
- if id == 0x02: # exit
- print('%s: %s' % (msgtype, 'program terminated'))
- break
- elif id in (0x03, 0x12):
- continue # create anonymous object (noisy)
- elif id == 0x05: # trace
- print('%s: %s' % (msgtype, data.rstrip('\x00')))
- elif id == 0x0e: # SWD file entry
- fileid, unknown = struct.unpack('LL', data[:8])
- try:
- name, source, rest = data[8:].split('\0', 2)
- assert len(rest) == 4
- assert source == ''
- index, = struct.unpack('L', rest)
- assert index == 0
- if fileid == 1:
- print('%s: %s' % (msgtype, (fileid, name, index)))
- print('(following SWD file entries skipped)')
- else:
- continue
- except StandardError, ex:
- print('error', ex)
- print('fileid %r, unknown %r, data %r' % (fileid, unknown, data))
- elif id == 0x19: # process tag
- cmd = struct.pack('LL', 0, 0x17) # "processed tag"
- sock.send(cmd)
- elif id == 0x24: # exception
- text, dump = data[4:].split('\0', 1)
- print('%s: %s' % (msgtype, text))
- print('\t(and %s extra bytes)' % len(dump))
- elif id not in (0x00, 0x0A, 0x0B, 0x1C):
- print('%s: %r' % (msgtype, data))
- if 'global$init' in data:
- cmd = struct.pack('LL', 0, 0x0F)
- sock.send(cmd)
- print('client disconnected')
- print('-' * 40)
- '''
- After global$init:
- slight pause then
- target $20: disable_script_stuck_dialog true
- host $1c: disable_script_stuck on
- target $20: disable_script_stuck true
- host $1c: break_on_fault on
- target $20: break_on_fault true
- host $1c: enumerate_override on
- target $20: enumerate_override true
- host $1c: notify_on_failure on
- target $20: notify_on_failure true
- host $1c: invoke_setters on
- target $20: invoke_setters true
- host $1c: swf_load_messages on
- target $20: swf_load_messages true
- host $1c: getter_timeout 1500
- target $20: getter_timeout 1500
- host $1c: setter_timeout 1500
- target $20: setter_timeout 1500
- host $18 (set squelch): 01 00 00 00
- target $1d (squelch): 01 00 00 00
- host $26 (get SWF info):
- target responds
- host $0f (continue):
- target $11 (break): some data
- target $19 (process tag):
- host $17 (processed tag):
- continues forever...
- '''
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment