Пример #1
0
    def __init__(self,
                 connection_string,
                 set_initial_bp=True,
                 event_callbacks_sink=None,
                 output_callbacks_sink=None,
                 dbg_eng_dll_path=None,
                 symbols_path=None):
        PyDbgEng.__init__(self, event_callbacks_sink, output_callbacks_sink,
                          dbg_eng_dll_path, symbols_path)

        self.force_quit_flag = False
        self.is_deleted = False

        # sanity check before setting initial bp
        if (event_callbacks_sink != None
                and isinstance(event_callbacks_sink, IDebugEventCallbacksSink)
                and set_initial_bp):
            if (not (event_callbacks_sink.GetInterestMask()
                     & DbgEng.DEBUG_EVENT_EXCEPTION)):
                raise DebuggerException(
                    "requested initial break, but 'exception' method is not implemented."
                )
            self.dbg_eng_log(
                "KernelAttacher.__init__: setting engine options with initial break"
            )
            self.idebug_control.SetEngineOptions(
                DbgEng.DEBUG_ENGOPT_INITIAL_BREAK)

        # attach to kernel
        self.dbg_eng_log(
            "KernelAttacher.__init__: about to attach to kernel with connection string %s"
            % connection_string)
        self.idebug_client.AttachKernel(
            ConnectOptions=connection_string,
            Flags=DbgEng.DEBUG_ATTACH_KERNEL_CONNECTION)
Пример #2
0
    def add(self, dbg, address, num_args, entry_hook=None, exit_hook=None):

        if (entry_hook == None and exit_hook == None):
            raise DebuggerException("no entry or exit hooks")

        # create a new hook instance and activate it.
        h = hook(address, num_args, entry_hook, exit_hook)
        h.hook(dbg)

        self.hooks.append(h)
Пример #3
0
    def read_virtual_memory(self, address, length):
        read_buf = create_string_buffer(length)
        bytes_read = c_ulong(0)

        self.idebug_data_spaces.ReadVirtual(address, read_buf, length,
                                            byref(bytes_read))

        if (bytes_read.value != length):
            raise DebuggerException(
                "read_virtual_memory(): ReadVirtual() failed")

        return read_buf.raw
Пример #4
0
    def create_idebug_client(dbgeng_dll):
        # DebugCreate() prototype
        debug_create_prototype = WINFUNCTYPE(
            HRESULT, POINTER(IID), POINTER(POINTER(DbgEng.IDebugClient)))
        debug_create_func = debug_create_prototype(("DebugCreate", dbgeng_dll))

        # call DebugCreate()
        idebug_client = POINTER(DbgEng.IDebugClient)()
        idebug_client_ptr = POINTER(POINTER(
            DbgEng.IDebugClient))(idebug_client)
        hr = debug_create_func(DbgEng.IDebugClient._iid_, idebug_client_ptr)
        if (hr != S_OK):
            raise DebuggerException("DebugCreate() failed with %x" % hr)

        # return debug_client of type POINTER(DbgEng.IDebugClient)
        return idebug_client
Пример #5
0
    def event_loop_with_user_callback(self, user_callback,
                                      user_callback_pool_interval_ms):
        if (user_callback_pool_interval_ms <= 0):
            raise DebuggerException(
                "UserModeSession.event_loop_with_user_callback(): invalid user_callback_pool_interval_ms"
            )

        while (True):
            if (self.wait_for_event(user_callback_pool_interval_ms) == False):
                self.dbg_eng_log(
                    "UserModeSession.event_loop_with_user_callback: wait_for_event() done. breaking loop."
                )
                break

            # call user callback
            if (user_callback(self) == True):
                # user requested to quit event loop
                self.dbg_eng_log(
                    "UserModeSession.event_loop_with_user_callback: user callback returned true. breaking loop."
                )
                break
Пример #6
0
    def event_loop_with_quit_event(self, quit_event):
        '''
        in kernel debugging session IDebugControl.WaitForEvent() must be called with an 'infinite' timeout value.
        this is why we have to create thread that checks the given given quit event. once set it will force a debugger
        break.
        '''

        if (self.is_deleted):
            raise DebuggerException("called when object is deleted")

        # sanity check on quit_event
        #if (not isinstance(quit_event, threading._Event)):
        #   raise DebuggerException("invalid type for quit event")

        # is already set?
        if (quit_event.is_set()):
            # no job for us
            return

        # create abort event
        abort_quit_waiter_event = Event()

        # start quit thread
        quit_waiter = KernelAttacher.QuitEventWaiter(
            quit_event=quit_event,
            abort_event=abort_quit_waiter_event,
            top=self)

        # event loop
        self.__event_loop_with_forced_break_check(quit_event)

        # stop quit waiter thread
        self.dbg_eng_log(
            "KernelAttacher.event_loop: waiting for quit_waiter to end")
        abort_quit_waiter_event.set()
        quit_waiter.join()

        # dont wait for garbage collection, and force delete on self
        self.__del__()
Пример #7
0
    def get_dbg_eng_dir_from_registry():
        import win32api, win32con
        try:
            hkey = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER,
                                       "Software\\Microsoft\\DebuggingTools")
        except:

            # Lets try a few common places before failing.
            pgPaths = [
                "c:\\",
                os.environ["SystemDrive"] + "\\",
                os.environ["ProgramFiles"],
            ]
            if "ProgramW6432" in os.environ:
                pgPaths.append(os.environ["ProgramW6432"])
            if "ProgramFiles(x86)" in os.environ:
                pgPaths.append(os.environ["ProgramFiles(x86)"])

            dbgPaths = [
                "Debuggers",
                "Debugger",
                "Debugging Tools for Windows",
                "Debugging Tools for Windows (x64)",
                "Debugging Tools for Windows (x86)",
            ]

            for p in pgPaths:
                for d in dbgPaths:
                    testPath = os.path.join(p, d)

                    if os.path.exists(testPath):
                        return testPath

            raise DebuggerException(
                "Failed to locate Microsoft Debugging Tools in the registry. Please make sure its installed"
            )
        val, type = win32api.RegQueryValueEx(hkey, "WinDbg")
        return val
Пример #8
0
 def get_current_tid(self):
     raise DebuggerException(
         "PyDbgEng.get_current_tid() must be implemented")
Пример #9
0
 def get_handle_data(self, handle):
     raise DebuggerException(
         "PyDbgEng.get_handle_data() must be implemented")
Пример #10
0
 def event_loop_with_quit_event(self, quit_event):
     print "%%% About to throw exception: event_loop_with_quit_event %%%"
     raise DebuggerException(
         "PyDbgEng.event_loop_with_quit_event() must be implemented")
Пример #11
0
 def event_loop_with_user_callback(self, user_callback,
                                   user_callback_pool_interval_ms):
     raise DebuggerException(
         "PyDbgEng.event_loop_with_user_callback() must be implemented")
Пример #12
0
    def __init__(self,
                 event_callbacks_sink=None,
                 output_callbacks_sink=None,
                 dbg_eng_dll_path=None,
                 symbols_path=None):
        import sys
        self.dbg_eng_log = lambda msg: None  # sys.stdout.write("DBGENG_LOG> " + msg + "\n")
        #self.dbg_eng_log = lambda msg: sys.stdout.write("> " + msg + "\n")

        if (dbg_eng_dll_path == None):
            finder = DbgEngDllFinder()
            dbg_eng_dll_path = finder.get_dbg_eng_dir_from_registry()

        self.dbg_eng_log("PyDbgEng.__init__: got dbg_eng_dll_path %s" %
                         dbg_eng_dll_path)

        # load dbgeng dlls
        self.dbg_eng_log("PyDbgEng.__init__: loading dbgeng dlls")
        self.dbghelp_dll = windll.LoadLibrary(dbg_eng_dll_path +
                                              "\\dbghelp.dll")
        self.dbgeng_dll = windll.LoadLibrary(dbg_eng_dll_path + "\\dbgeng.dll")

        # create main interfaces
        self.dbg_eng_log("PyDbgEng.__init__: creating interfaces")
        creator = IDebugClientCreator()

        try:
            self.idebug_client = creator.create_idebug_client(self.dbgeng_dll)
        except:
            # Try registering it
            import os, sys
            os.system("%s %s -regserver" %
                      (sys.executable, self.findDbgEngEvent()))
            self.idebug_client = creator.create_idebug_client(self.dbgeng_dll)
            pass

        self.idebug_control = self.idebug_client.QueryInterface(
            interface=DbgEng.IDebugControl)
        self.idebug_data_spaces = self.idebug_client.QueryInterface(
            interface=DbgEng.IDebugDataSpaces3)
        self.idebug_registers = self.idebug_client.QueryInterface(
            interface=DbgEng.IDebugRegisters)
        self.idebug_symbols = self.idebug_client.QueryInterface(
            interface=DbgEng.IDebugSymbols)
        self.idebug_system_objects = self.idebug_client.QueryInterface(
            interface=DbgEng.IDebugSystemObjects)

        if (symbols_path != None):
            self.idebug_symbols.SetSymbolPath(symbols_path)

    # create event sink
        if (event_callbacks_sink != None):
            # sanity check on sink
            if (not isinstance(event_callbacks_sink,
                               IDebugEventCallbacksSink)):
                raise DebuggerException(
                    "Invalid sink object (event_callbacks_sink)")

            self.event_callbacks_sink = event_callbacks_sink
            self.dbg_eng_log(
                "PyDbgEng.__init__: registering event callbacks proxy")

            # Updated code to work with latest comtypes and remove native code needs
            # Eddington 5/3/2008
            PyDbgEng.fuzzyWuzzy = self  # HACK!

            from DbgEngEvent import DbgEngEventCallbacks
            event_proxy = DbgEngEventCallbacks()
            event_proxy.IUnknown_AddRef(event_proxy)

            self.new_event_callbacks = event_proxy
            self.old_event_callbacks = self.idebug_client.GetEventCallbacks()
            self.idebug_client.SetEventCallbacks(Callbacks=event_proxy)

    # create output sink
        if (output_callbacks_sink != None):
            # sanity check on sink
            if (not isinstance(output_callbacks_sink,
                               IDebugOutputCallbacksSink)):
                raise DebuggerException(
                    "Invalid sink object (output_callbacks_sink)")
            self.dbg_eng_log(
                "PyDbgEng.__init__: registering output callbacks proxy")

            # Updated code to work with latest comtypes and remove native code needs
            # Eddington 5/3/2008
            PyDbgEng.fuzzyWuzzy = self  # HACK!

            from DbgEngEvent import DbgEngEventCallbacks
            output_proxy = DbgEngEventCallbacks()
            output_proxy.IUnknown_AddRef(output_proxy)

            self.new_output_callbacks = output_proxy
            self.output_callbacks_sink = output_callbacks_sink
            self.old_event_callbacks = self.idebug_client.GetEventCallbacks()
            self.idebug_client.SetOutputCallbacks(Callbacks=output_proxy)
Пример #13
0
 def GetInterestMask(self):
     raise DebuggerException(
         "IDebugEventCallbacksSink.GetInterestMask() must be implemented")