peter9477

pyfdb v0.2

Mar 20th, 2011
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.74 KB | None | 0 0
  1.  
  2. '''A very crude Flash Debugger in Python, usable with BlackBerry PlayBook simulator.'''
  3.  
  4. # Copyright 2010 Peter Hansen (http://peterhansen.ca)
  5. # Released under the Simplified BSD License: http://www.opensource.org/licenses/bsd-license.php
  6.  
  7. from __future__ import print_function
  8. import sys
  9. import struct
  10. from socket import *
  11. from threading import Thread
  12.  
  13. __version__ = '0.2'
  14.  
  15. MSG_NAME = {
  16.     0x00: 'menu state', #dd ?, dd ?
  17.     0x01: 'property', #dd addr, dw propertyIndex, sz value
  18.     0x02: 'exit', #
  19.     0x03: 'create anonymous object', #dd addr
  20.     0x04: 'remove object', #dd addr
  21.     0x05: 'trace', #sz msg
  22.     0x06: 'target error', #sz error
  23.     0x07: 'recursion depth error', #
  24.     0x08: 'with error', #
  25.     0x09: 'proto limit error', #
  26.     0x0A: 'set field', #dd addr, sz name, amf value
  27.     0x0B: 'delete field', #dd addr, sz name
  28.     0x0C: 'movie attribute', #sz name, sz value
  29.     0x0D: 'place object', #dd addr, sz name
  30.     0x0E: 'SWD file entry', #dd fileID, dd unknownIndex, sz name, sz sourceCode, dd swfIndex
  31.     0x0F: 'ask breakpoints', #
  32.     0x10: 'breakpoint hit', #dw fileID, dw line, dd addr, sz funcName
  33.     0x11: 'break', #
  34.     0x12: 'set local vars', #dd addr address of an object containing the named local variables of the current scope
  35.     0x13: 'breakpoints', #dd count, (dw fileID, dw line)[count]
  36.     0x14: 'num swd file entries', #dd num, dd swfIndex
  37.     0x15: 'remove SWD file entry', #dd fileID
  38.     0x16: 'remove breakpoint', #dd count, (dw fileID, dw line)[count]
  39.     0x17: 'not synced', #Sent if the debug ID in the .swf does not match the SWD ID in the .swd
  40.     0x18: 'URL open error', #sz error
  41.     0x19: 'process tag', #
  42.     0x1A: 'version', #dd majorVersion, db 4
  43.     0x1B: 'breakpoint hit ex', #dw fileID, dw line, dd callDepth, (dw fileID, dw line, dd thisAddr, sz callstackentry)[callDepth]
  44.     0x1C: 'set field 2', #addr, sz name, amf value
  45.     0x1D: 'squelch', #dd enabled
  46.     0x1E: 'get field', #dd addr, sz name, amf value, (sz memberName, amf memberValue)*
  47.     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"
  48.     0x20: 'debugger option', #sz name, sz value
  49.     0x21: 'watch', #dw success, dw oldFlags, dw oldTag, dw flags, dw tag, dw addr, sz name
  50.     0x22: 'SWF image', #.swf file contents
  51.     0x23: 'SWD image', #.swd file contents
  52.     0x24: 'exception', #dd 0, sz exception
  53.     0x25: 'stack underflow', #dd 0
  54.     0x26: 'divide by 0', #dd 0
  55.     0x27: 'script stuck', #
  56.     0x28: 'suspend reason', #dw reason, dw swfIndex, dd offset, dd prevLineOffset, dd nextLineOffset
  57.     0x29: 'actions', #dw swfIndex, dw reserved, dd offset, dd size, db data[size] deprecated/not implemented, will be empty
  58.     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
  59.     0x2B: 'constant pool', #dw swfIndex, dd count, (dd id, sz name, amf value)[count]
  60.     0x2C: 'console error', #sz error
  61.     0x2D: 'function info', #dd fileID, dd count, (dd offset, dd firstLine, dd lastLine, sz name)[count]
  62.     0x2E: '?', #
  63.     0x2F: '?', #
  64.     0x30: '?', #
  65.     0x31: '?', #
  66.     0x32: '?', #
  67.     0x33: '?', #
  68.     0x34: '?', #
  69.     0x35: '?', #
  70.     0x36: '?', #
  71.     0x37: 'watch 2' #dw success, dw oldFlags, dw oldTag, dw flags, dw tag, dd addr, sz name
  72.     }
  73.  
  74. COMMANDS = {
  75.     0x00: 'zoom in', #
  76.     0x01: 'zoom out', #
  77.     0x02: 'zoom 100%', #
  78.     0x03: 'home', #
  79.     0x04: 'set quality', #sz quality="LOW"/"MEDIUM"/"HIGH"/"AUTOLOW"/"AUTOMEDIUM"/"AUTOHIGH"/"BEST"
  80.     0x05: 'play', #
  81.     0x06: 'loop', #
  82.     0x07: 'rewind', #
  83.     0x08: 'forward', #
  84.     0x09: 'back', #
  85.     0x0A: 'print', #
  86.     0x0B: 'set field', #dd addr, sz name, sz type="string"/"number"/"boolean"/"null", sz value For "number", value can be "Infinity", "-Infinity" or "NaN"
  87.     0x0C: 'set property', #dd addr, dw propIndex, sz type="string"/"number"/"boolean"/"null", sz value For "number", value can be "Infinity", "-Infinity" or "NaN"
  88.     0x0D: 'end debugging session', #
  89.     0x0E: 'request properties', #dd addr
  90.     0x0F: 'continue', #
  91.     0x10: 'suspend', #
  92.     0x11: 'set breakpoint', #dd ignored, dw fileID, dw line
  93.     0x12: 'clear breakpoint', #dd ignored, dw fileID, dw line
  94.     0x13: 'clear all breakpoints', #
  95.     0x14: 'step over', #
  96.     0x15: 'step into', #
  97.     0x16: 'step out', #
  98.     0x17: 'processed tag', #
  99.     0x18: 'set squelch', #dd squelchOn
  100.     0x19: 'get field', #dd addr, sz name [, dd flags] flags: 1=fire getter, 2=also get children, 4=? (always set)
  101.     0x1A: 'get function frame', #dd calldepth
  102.     0x1B: 'get debugger option', #sz name
  103.     0x1C: 'set debugger option', #sz name, sz value
  104.     0x1D: 'add watch', #dw addr, sz name, dw flags, dw tag
  105.     0x1E: 'remove watch', #dw addr, sz name
  106.     0x1F: 'step continue', #
  107.     0x20: 'get SWF file content', #dw swfIndex
  108.     0x21: 'get SWD file content', #dw swfIndex
  109.     0x22: 'get field which invokes getter', #dd addr, sz name [, dd flags] flags: 1=fire getter, 2=also get children, 4=? (always set)
  110.     0x23: 'get suspend reason', #
  111.     0x24: 'get actions', #dd swfIndex, dw reserved, dd offset, dd size deprecated/not implemented, sends back an empty "actions" reply
  112.     0x25: 'set actions', #dd swfIndex, dw reserved, dd offset, dd size, db data[size] deprecated/not implemented, sends back an empty "actions" reply
  113.     0x26: 'get SWF info', #dw swfIndex, dw 0
  114.     0x27: 'get constant pool', #dw swfIndex
  115.     0x28: 'get function info', #dd swdID, dd lineNum lineNum =< 0: all functions
  116.     0x29: '?', #
  117.     0x2A: '?', #
  118.     0x2B: '?', #
  119.     0x2C: '?', #
  120.     0x2D: '?', #
  121.     0x2E: '?', #
  122.     0x2F: '?', #
  123.     0x30: '?', #
  124.     0x31: 'add watch 2', #dd addr, sz name, dw flags, dw tag flags: 1=read, 2=write, 3=both. tag: for identification, choose one
  125.     0x32: 'remove watch 2', #dd addr, sz name
  126.     0x33: '?', #
  127.     0x34: '?',
  128.     }
  129.  
  130.  
  131. def main():
  132.     s = socket(AF_INET, SOCK_STREAM)
  133.     #~ s.settimeout(500)
  134.     s.bind(('', 7935))
  135.     s.listen(5)
  136.     clientnum = 0
  137.     while 1:
  138.         #~ print('listening on 7935')
  139.         sock, client = s.accept()
  140.         clientnum += 1
  141.         print('-' * 40)
  142.         print('connection %s from %s' % (clientnum, client))
  143.         cthread = Thread(target=run_client, args=(clientnum, sock))
  144.         cthread.daemon = True
  145.         cthread.start()
  146.  
  147.  
  148. def run_client(clientnum, sock, _print=print):
  149.     def print(*args):
  150.         _print('[%s]' % clientnum, *args)
  151.  
  152.     while 1:
  153.         data = sock.recv(8)
  154.         if not data:
  155.             break
  156.         length, id = struct.unpack('LL', data)
  157.         msgtype = MSG_NAME.get(id, 'unknown')
  158.         if length:
  159.             if length < 1000000:
  160.                 data = sock.recv(length)
  161.             else:
  162.                 print('length too large at %s (from %r)' % (length, data))
  163.                 break   # ignore and quite
  164.         else:
  165.             data = ''
  166.  
  167.         if id == 0x02:    # exit
  168.             print('%s: %s' % (msgtype, 'program terminated'))
  169.             break
  170.         elif id in (0x03, 0x12):
  171.             continue    # create anonymous object (noisy)
  172.         elif id == 0x05:    # trace
  173.             print('%s: %s' % (msgtype, data.rstrip('\x00')))
  174.         elif id == 0x0e:    # SWD file entry
  175.             fileid, unknown = struct.unpack('LL', data[:8])
  176.             try:
  177.                 name, source, rest = data[8:].split('\0', 2)
  178.                 assert len(rest) == 4
  179.                 assert source == ''
  180.                 index, = struct.unpack('L', rest)
  181.                 assert index == 0
  182.                 if fileid == 1:
  183.                     print('%s: %s' % (msgtype, (fileid, name, index)))
  184.                     print('(following SWD file entries skipped)')
  185.                 else:
  186.                     continue
  187.             except StandardError, ex:
  188.                 print('error', ex)
  189.                 print('fileid %r, unknown %r, data %r' % (fileid, unknown, data))
  190.  
  191.         elif id == 0x19:    # process tag
  192.             cmd = struct.pack('LL', 0, 0x17)    # "processed tag"
  193.             sock.send(cmd)
  194.         elif id == 0x24:    # exception
  195.             text, dump = data[4:].split('\0', 1)
  196.             print('%s: %s' % (msgtype, text))
  197.             print('\t(and %s extra bytes)' % len(dump))
  198.         elif id not in (0x00, 0x0A, 0x0B, 0x1C):
  199.             print('%s: %r' % (msgtype, data))
  200.  
  201.         if 'global$init' in data:
  202.             cmd = struct.pack('LL', 0, 0x0F)
  203.             sock.send(cmd)
  204.  
  205.     print('client disconnected')
  206.     print('-' * 40)
  207.  
  208. '''
  209. After global$init:
  210. slight pause then
  211. target  $20: disable_script_stuck_dialog true
  212. host    $1c: disable_script_stuck on
  213. target  $20: disable_script_stuck true
  214. host    $1c: break_on_fault on
  215. target  $20: break_on_fault true
  216. host    $1c: enumerate_override on
  217. target  $20: enumerate_override true
  218. host    $1c: notify_on_failure on
  219. target  $20: notify_on_failure true
  220. host    $1c: invoke_setters on
  221. target  $20: invoke_setters true
  222. host    $1c: swf_load_messages on
  223. target  $20: swf_load_messages true
  224. host    $1c: getter_timeout 1500
  225. target  $20: getter_timeout 1500
  226. host    $1c: setter_timeout 1500
  227. target  $20: setter_timeout 1500
  228. host    $18 (set squelch): 01 00 00 00
  229. target  $1d (squelch): 01 00 00 00
  230.  
  231. host    $26 (get SWF info):
  232. target responds
  233.  
  234. host    $0f (continue):
  235. target  $11 (break): some data
  236.  
  237. target  $19 (process tag):
  238. host    $17 (processed tag):
  239. continues forever...
  240. '''
  241.  
  242. if __name__ == '__main__':
  243.     main()
Advertisement
Add Comment
Please, Sign In to add comment