def debug_event_loop(self): ''' Overriden debug event handling loop. A transparent mirror here with method_missing() would not do. Our debug event loop is reduced here to a data marshaling loop with the server. If the received type from the server is a tuple then we assume a debug or exception event has occured and pass it to any registered callbacks. The callback is free to call arbitrary PyDbg routines. Upon return of the callback, a special token, **DONE**, is used to flag to the PyDbg server that we are done processing the exception and it is free to move on. ''' self.pickle_send(("debug_event_loop", ())) while 1: received = self.pickle_recv() if not received: continue # if we received a "special" type, which can currently be one of: # - debugger callback event # - user callback event # - raised exception if type(received) == tuple: # callback type. if received[0] == "callback": (msg_type, dbg, context) = received # debugger callback event. if dbg and context: # propogate the convenience variables. self.dbg = dbg self.context = context self.exception_address = dbg.u.Exception.ExceptionRecord.ExceptionAddress self.write_violation = dbg.u.Exception.ExceptionRecord.ExceptionInformation[ 0] self.violation_address = dbg.u.Exception.ExceptionRecord.ExceptionInformation[ 1] exception_code = dbg.u.Exception.ExceptionRecord.ExceptionCode ret = DBG_CONTINUE if exception_code in self.callbacks: print("processing handler for %08x" % exception_code) ret = self.callbacks[exception_code](self) # user callback event. else: if USER_CALLBACK_DEBUG_EVENT in self.callbacks: ret = self.callbacks[USER_CALLBACK_DEBUG_EVENT]( self) # raised exception type. elif received[0] == "exception": (msg_type, exception_string) = received print(exception_string) raise pdx(exception_string) self.pickle_send(("**DONE**", ret))
def debug_event_loop(self): """ Overriden debug event handling loop. A transparent mirror here with method_missing() would not do. Our debug event loop is reduced here to a data marshaling loop with the server. If the received type from the server is a tuple then we assume a debug or exception event has occured and pass it to any registered callbacks. The callback is free to call arbitrary PyDbg routines. Upon return of the callback, a special token, **DONE**, is used to flag to the PyDbg server that we are done processing the exception and it is free to move on. """ self.pickle_send(("debug_event_loop", ())) while 1: received = self.pickle_recv() if not received: continue # if we received a "special" type, which can currently be one of: # - debugger callback event # - user callback event # - raised exception if type(received) == tuple: #### callback type. if received[0] == "callback": (msg_type, dbg, context) = received ## debugger callback event. if dbg and context: # propogate the convenience variables. self.dbg = dbg self.context = context self.exception_address = dbg.u.Exception.ExceptionRecord.ExceptionAddress self.write_violation = dbg.u.Exception.ExceptionRecord.ExceptionInformation[0] self.violation_address = dbg.u.Exception.ExceptionRecord.ExceptionInformation[1] exception_code = dbg.u.Exception.ExceptionRecord.ExceptionCode ret = DBG_CONTINUE if self.callbacks.has_key(exception_code): print "processing handler for %08x" % exception_code ret = self.callbacks[exception_code](self) ## user callback event. else: if self.callbacks.has_key(USER_CALLBACK_DEBUG_EVENT): ret = self.callbacks[USER_CALLBACK_DEBUG_EVENT](self) #### raised exception type. elif received[0] == "exception": (msg_type, exception_string) = received print exception_string raise pdx(exception_string) self.pickle_send(("**DONE**", ret))
def pickle_recv(self): """ This routine is used for marshaling arbitrary data from the PyDbg server. We can send pretty much anything here. For example a tuple containing integers, strings, arbitrary objects and structures. Our "protocol" is a simple length-value protocol where each datagram is prefixed by a 4-byte length of the data to be received. @raise pdx: An exception is raised if the connection was severed. @rtype: Mixed @return: Whatever is received over the socket. """ try: length = long(self.sock.recv(4), 16) received = self.sock.recv(length) except: raise pdx("connection severed") return cPickle.loads(received)
def pickle_recv(self): ''' This routine is used for marshaling arbitrary data from the PyDbg server. We can send pretty much anything here. For example a tuple containing integers, strings, arbitrary objects and structures. Our "protocol" is a simple length-value protocol where each datagram is prefixed by a 4-byte length of the data to be received. @raise pdx: An exception is raised if the connection was severed. @rtype: Mixed @return: Whatever is received over the socket. ''' try: length = long(self.sock.recv(4), 16) received = self.sock.recv(length) except: raise pdx("connection severed") return cPickle.loads(received)
def pickle_send(self, data): """ This routine is used for marshaling arbitrary data to the PyDbg server. We can send pretty much anything here. For example a tuple containing integers, strings, arbitrary objects and structures. Our "protocol" is a simple length-value protocol where each datagram is prefixed by a 4-byte length of the data to be received. @type data: Mixed @param data: Data to marshal and transmit. Data can *pretty much* contain anything you throw at it. @raise pdx: An exception is raised if the connection was severed. """ data = cPickle.dumps(data) try: self.sock.send("%04x" % len(data)) self.sock.send(data) except: raise pdx("connection severed")
def pickle_send(self, data): ''' This routine is used for marshaling arbitrary data to the PyDbg server. We can send pretty much anything here. For example a tuple containing integers, strings, arbitrary objects and structures. Our "protocol" is a simple length-value protocol where each datagram is prefixed by a 4-byte length of the data to be received. @type data: Mixed @param data: Data to marshal and transmit. Data can *pretty much* contain anything you throw at it. @raise pdx: An exception is raised if the connection was severed. ''' data = cPickle.dumps(data) try: self.sock.send("%04x" % len(data)) self.sock.send(data) except: raise pdx("connection severed")
def __init__(self, host, port): """ Set the default client attributes. The target host and port are required. @type host: String @param host: Host address of PyDBG server (dotted quad IP address or hostname) @type port: Integer @param port: Port that the PyDBG server is listening on. @raise pdx: An exception is raised if a connection to the PyDbg server can not be established. """ self.host = host self.port = port self.pydbg = pydbg() self.callbacks = {} try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((host, port)) except: raise pdx("connection severed")
def __init__(self, host, port): ''' Set the default client attributes. The target host and port are required. @type host: String @param host: Host address of PyDBG server (dotted quad IP address or hostname) @type port: Integer @param port: Port that the PyDBG server is listening on. @raise pdx: An exception is raised if a connection to the PyDbg server can not be established. ''' self.host = host self.port = port self.pydbg = pydbg() self.callbacks = {} try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((host, port)) except: raise pdx("connection severed")