def analyze_crash(cmd): """ This is called with the command line (including the filename) which caused the crash before. It is a late analysis routine which sorts the crashes. """ global file_info global victim_filename global crash_filename # TODO: This may not always be the case victim_filename, crash_filename = cmd print "=== [*] Analyzing %s" % crash_filename file_binary = fileops.get_base64_contents(crash_filename) if file_binary: file_info = (crash_filename, file_binary) # Instance a Debug object, passing it the event handler callback. debug = Debug(crash_event_handler, bKillOnExit = True) try: # Start a new process for debugging. debug.execv(cmd) # Wait for the debugee to finish. debug.loop() # Stop the debugger. finally: debug.stop()
def main( argv ): # Parse the command line arguments options = parse_cmdline(argv) # Create the event handler object eventHandler = Tracer() eventHandler.options = options # Create the debug object debug = Debug(eventHandler, bHostileCode = options.hostile) try: # Attach to the targets for pid in options.attach: debug.attach(pid) for argv in options.console: debug.execv(argv, bConsole = True, bFollow = options.follow) for argv in options.windowed: debug.execv(argv, bConsole = False, bFollow = options.follow) # Make sure the debugees die if the debugger dies unexpectedly debug.system.set_kill_on_exit_mode(True) # Run the debug loop debug.loop() # Stop the debugger finally: if not options.autodetach: debug.kill_all(bIgnoreExceptions = True) debug.stop()
def intercept_wsmprovhost(pid,eventHandler): debug = Debug(eventHandler,bKillOnExit=True) try: debug.attach(int(pid)) debug.loop() except Exception,e: print "Error: ",str(e)
def simple_debugger(address_file, program_file, arg_check): process = None debug = Debug(HitTracerEventHandler(address_file, program_file, arg_check)) try: # Lookup currently running processes debug.system.scan_processes() for (process, name) in debug.system.find_processes_by_filename(program_file): print "[*] Found %d: %s" % (process.get_pid(), name) # Attach to it debug.attach(process.get_pid()) if process == None: print "[*] Fatal. Process not found. Is it running?" sys.exit(1) # Wait for all debugees to finish debug.loop() # Cleanup actions finally: debug.stop()
def simple_debugger( argv ): # Instance a Debug object, passing it the event handler callback. debug = Debug( my_event_handler, bKillOnExit = True ) try: # Start a new process for debugging. debug.execv( argv ) # Wait for the debugee to finish. debug.loop() # Stop the debugger. finally: debug.stop()
def main( ): set_logger() args = parse_args() pid = get_pid(args) logging.debug( "about to connect to pid %(pid)s" % locals() ) dbg = None try: dbg = Debug( event_handler.RPCEventHandler(), bKillOnExit = False) dbg.attach(pid) dbg.loop() finally: if dbg != None: logging.debug ("About to detach from pid %(pid)s" % locals() ) dbg.detach(pid) logging.info("Finished")
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # This line is needed in Python 2.5 to use the "with" statement. from __future__ import with_statement from winappdbg import Debug import sys # Instance a Debug object, set the kill on exit property to True. debug = Debug( bKillOnExit = True ) # The user can stop debugging with Control-C. try: print "Hit Control-C to stop debugging..." # Start a new process for debugging. debug.execv( sys.argv[ 1 : ] ) # Wait for the debugee to finish. debug.loop() # If the user presses Control-C... except KeyboardInterrupt: print "Interrupted by user." # Stop debugging. This kills all debugged processes. debug.stop()
def createDebugger(self, command): debug = Debug(self.debuggerEventHandler, bKillOnExit=True) argv = command.split() debug.execv(argv) debug.loop()
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import sys from winappdbg import Debug import sys # Get the process ID from the command line. pid = int( sys.argv[1] ) # Instance a Debug object. debug = Debug() try: # Attach to a running process. debug.attach( pid ) # Wait for the debugee to finish. debug.loop() # Stop the debugger. finally: debug.stop()
class WinAppDbgTarget(ServerTarget): def __init__(self, name, process_path, process_args=[], sql_crash_db='sqlite:///crashes.sqlite', logger=None): ''' :param name: name of the object :param process_path: path to the target executable :param process_args: arguments to pass to the process :param attach: try to attach if process path :param sql_crash_db: sql alchemy connection string to crash db (default:sqlite:///crashes.sqlite) :param logger: logger for this object (default: None) ''' super(WinAppDbgTarget, self).__init__(name, logger) assert (process_path) assert (os.path.exists(process_path)) self._process_path = process_path self._process_name = os.path.basename(process_path) self._process_args = process_args self._process = None self._sql_crash_db = sql_crash_db self._crash_event_complete = threading.Event() self._server_is_up = threading.Event() self._crash_event_complete.set() self._debug = Debug(lambda x: _my_event_handler(self, x), bKillOnExit=True) def _debug_server(self): ''' debugger thread ''' try: self._process = None # Start a new process for debugging. argv = [self._process_path] + self._process_args self.logger.debug('debugger starting server: %s' % argv) try: self._process = self._debug.execv(argv, bFollow=True) except WindowsError: self.logger.error('debug_server received exception', traceback.fmt_exc()) self._pid = self._process.get_pid() self.logger.info('process started. pid=%d' % self._pid) # Wait for the debugee to finish. self._server_is_up.set() self._debug.loop() except: self.logger.error('Got an exception in _debug_server') self.logger.error(traceback.format_exc()) # Stop the debugger. finally: self._debug.stop() self._process = None self._pid = -1 self._crash_event_complete.set() def _start_server_thread(self): ''' start the server thread ''' self._server_is_up.clear() self.server_thread = FuncThread(self._debug_server) self.server_thread.start() self.logger.info('waiting for server to be up') self._server_is_up.wait() self.logger.info('server should be up') def _kill_all_processes(self): ''' kill all processes with the same name :return: True if all matching processes were killed properly, False otherwise ''' res = True # Lookup the currently running processes. self._debug.system.scan_processes() # For all processes that match the requested filename... for (process, name) in self._debug.system.find_processes_by_filename( self._process_name): process_pid = process.get_pid() self.logger.info('found process %s (%d) - trying to kill it' % (name, process_pid)) try: process.kill() self.logger.info('successfully killed %s (%d)' % (name, process_pid)) except: self.logger.error('failed to kill %s (%d) [%s]' % (name, process_pid, traceback.format_exc())) res = False return res def teardown(self): self._stop_process() self._process = None super(WinAppDbgTarget, self).teardown() def pre_test(self, test_number): # we need kill all process before fuzzing super(WinAppDbgTarget, self).pre_test(test_number) self._stop_process() def post_test(self, test_num): self.logger.debug('in') time.sleep(1) self.logger.debug('after sleep') res = self._crash_event_complete.wait() self.logger.debug('after wait') if not res: self.report.failed('incomplete crash detected') super(WinAppDbgTarget, self).post_test(test_num) self.logger.debug('out') def _send_to_target(self, data): ''' this is the key off windbgtarget :param data: data is the file path ''' self.logger.info('send called') ''' starting ''' self._process_args = [data] # this may need implement self._start_server_thread() def _stop_process(self): ''' Stop the process (if running) ''' return self._kill_all_processes() def _stop_process_old(self): ''' :return: True if process was killed, False otherwise ''' if self._is_victim_alive(): self._process.kill() time.sleep(0.5) if self._is_victim_alive(): self._process.kill() time.sleep(0.5) if self._is_victim_alive(): raise Exception('Failed to kill client process') self._debug.stop() return True else: self._debug.stop() return False def _restart(self): ''' restart the process ''' self._stop_process() self.server_thread.join(1) time.sleep(3) self._server_is_up.clear() self._start_server_thread() def _is_victim_alive(self): ''' check if process running ''' if self._process: self.logger.debug('process pid: %d' % self._pid) is_alive = self._process.is_alive() is_debugee_started = self._debug.is_debugee_started(self._pid) self.logger.debug('is_alive = %s' % is_alive) self.logger.debug('is_debugee_started = %s' % is_debugee_started) return (is_alive and is_debugee_started) else: self.logger.debug('_process is None') return False
class WinAppDbgController(BaseController): ''' WinAppDbgController controls a server process by starting it on setup making sure it stays up. It uses winappdbg to attach to the target processes. ''' def __init__(self, name, process_path, process_args=[], sql_crash_db='sqlite:///crashes.sqlite', logger=None): ''' :param name: name of the object :param process_path: path to the target executable :param process_args: arguments to pass to the process :param attach: try to attach if process path :param sql_crash_db: sql alchemy connection string to crash db (default:sqlite:///crashes.sqlite) :param logger: logger for this object (default: None) ''' super(WinAppDbgController, self).__init__(name, logger) assert(process_path) assert(os.path.exists(process_path)) self._process_path = process_path self._process_name = os.path.basename(process_path) self._process_args = process_args self._process = None self._sql_crash_db = sql_crash_db self._crash_event_complete = threading.Event() self._server_is_up = threading.Event() self._crash_event_complete.set() self._debug = Debug(lambda x: _my_event_handler(self, x), bKillOnExit=True) def _debug_server(self): ''' debugger thread ''' try: self._process = None # Start a new process for debugging. argv = [self._process_path] + self._process_args self.logger.debug('debugger starting server: %s' % argv) try: self._process = self._debug.execv(argv, bFollow=True) except WindowsError: self.logger.error('debug_server received exception', traceback.fmt_exc()) self._pid = self._process.get_pid() self.logger.info('process started. pid=%d' % self._pid) # Wait for the debugee to finish. self._server_is_up.set() self._debug.loop() except: self.logger.error('Got an exception in _debug_server') self.logger.error(traceback.format_exc()) # Stop the debugger. finally: self._debug.stop() self._process = None self._pid = -1 self._crash_event_complete.set() def _start_server_thread(self): ''' start the server thread ''' self._server_is_up.clear() self.server_thread = FuncThread(self._debug_server) self.server_thread.start() self.logger.info('waiting for server to be up') self._server_is_up.wait() self.logger.info('server should be up') def _kill_all_processes(self): ''' kill all processes with the same name :return: True if all matching processes were killed properly, False otherwise ''' res = True # Lookup the currently running processes. self._debug.system.scan_processes() # For all processes that match the requested filename... for (process, name) in self._debug.system.find_processes_by_filename(self._process_name): process_pid = process.get_pid() self.logger.info('found process %s (%d) - trying to kill it' % (name, process_pid)) try: process.kill() self.logger.info('successfully killed %s (%d)' % (name, process_pid)) except: self.logger.error('failed to kill %s (%d) [%s]' % (name, process_pid, traceback.format_exc())) res = False return res def setup(self): ''' Called at the beginning of a fuzzing session. Will start the server up. ''' self._stop_process() self._start_server_thread() def teardown(self): self._stop_process() self._process = None super(WinAppDbgController, self).teardown() def pre_test(self, test_number): super(WinAppDbgController, self).pre_test(test_number) if not self._is_victim_alive(): self.logger.error('victim is dead, restarting...') # self.report.failed('server is down during pre_test - failure it probably from previous test (%d)' % (test_number-1)) self._restart() self._crash_event_complete.set() else: self.logger.debug('victim is alive (pid=%d)' % self._pid) def post_test(self): self.logger.debug('in') time.sleep(1) self.logger.debug('after sleep') res = self._crash_event_complete.wait() self.logger.debug('after wait') if not res: self.report.failed('incomplete crash detected') super(WinAppDbgController, self).post_test() self.logger.debug('out') def _stop_process(self): ''' Stop the process (if running) ''' return self._kill_all_processes() def _stop_process_old(self): ''' :return: True if process was killed, False otherwise ''' if self._is_victim_alive(): self._process.kill() time.sleep(0.5) if self._is_victim_alive(): self._process.kill() time.sleep(0.5) if self._is_victim_alive(): raise Exception('Failed to kill client process') self._debug.stop() return True else: self._debug.stop() return False def _restart(self): ''' restart the process ''' self._stop_process() self.server_thread.join(1) time.sleep(3) self._server_is_up.clear() self._start_server_thread() def _is_victim_alive(self): ''' check if process running ''' if self._process: self.logger.debug('process pid: %d' % self._pid) is_alive = self._process.is_alive() is_debugee_started = self._debug.is_debugee_started(self._pid) self.logger.debug('is_alive = %s' % is_alive) self.logger.debug('is_debugee_started = %s' % is_debugee_started) return (is_alive and is_debugee_started) else: self.logger.debug('_process is None') return False