Example #1
0
    def exec_sync(func, *args, **kwargs):
        """
            Wrap around the execute_sync API to perform a call on the function
            ``func`` in the main thread. If a function is not marked as
            THREAD_SAFE in the headers, then it can only be called from the
            main thread of IDA.

            .. todo:: unit test
    
            :param func: The function to call.
            :type func: Python Callable
            :param args: Arguments to ``func``
            :param kwargs: Keyworded arguments to ``func``
            :param MFF_FLAG: Flag describing the operation on the database.
                Default ``MFF_READ``. Can be ``MFF_FAST``, ``MFF_READ``,
                ``MFF_WRITE`` or ``MFF_NOWAIT`` (from ida_kernwin).
            :type MFF_FLAG: int
            :return: The return of ``func``
        """
    
        MFF_FLAG = kwargs.get("MFF_FLAG", ida_kernwin.MFF_READ)
    
        ret = {"ret": None}
        def handle():
            ret["ret"] = func(*args, **kwargs)
            return 1
    
        ida_kernwin.execute_sync(handle, MFF_FLAG)
        return ret["ret"]
Example #2
0
    def prepare_debug(self):
        def get_processes_list():
            self.pis = ida_idd.procinfo_vec_t()
            ida_dbg.get_processes(self.pis)
            return 1

        c = 0
        found_pid = False
        while not found_pid:
            c = (c + 1) % 5
            self.sinOut.emit("finding process: [%s]" % self.filename +
                             ('.' * c).ljust(5, " "))

            ida_kernwin.execute_sync(MainCallable(get_processes_list), \
             ida_kernwin.MFF_FAST)

            for proc in self.pis:
                proc_name = proc.name.split(" ")[1]
                idx = proc_name.rfind("/")

                if idx != -1:
                    proc_name = proc_name[idx + 1:]

                if self.filename == proc_name:
                    self.target_pid = proc.pid
                    found_pid = True
                    break

            if not found_pid:
                self.sleep(1)
Example #3
0
    def req_DelNodesInfos(self, *nodes):
        w = self.w

        def f():
            self.log("Deleting nodes infos..")
            w.DelNodesInfos(*nodes)

        ida_kernwin.execute_sync(f, ida_kernwin.MFF_FAST)
Example #4
0
    def req_SetNodeInfo(self, node, info, flags):
        w = self.w

        def f():
            self.log("Setting node info..")
            w.SetNodeInfo(node, info, flags)

        ida_kernwin.execute_sync(f, ida_kernwin.MFF_FAST)
Example #5
0
    def req_SetCurrentRendererType(self, switch_to):
        w = self.w

        def f():
            self.log("Switching to %s" % switch_to)
            w.SetCurrentRendererType(switch_to)

        ida_kernwin.execute_sync(f, ida_kernwin.MFF_FAST)
Example #6
0
        def enqueue(*args, **kwargs):
            def partial_callback():
                # Store return value inside main thread, return a positive value
                self.__ret = callback(*args, **kwargs)
                return 1

            # enqueue partial_callback to be executed by IDA's main thread is needed
            ida_kernwin.execute_sync(partial_callback, self.reqf)

            # retreive return value and set sync variable to None for safety
            ret, self.__ret = self.__ret, None
            return ret
Example #7
0
    def load(self, force=False):
        """
        Actually does :code:`ida_loaders.load_plugin(paths)`, and updates IDAUSR variable.
        """
        if not force and self.path in os.environ.get('IDAUSR', ''):
            # Already loaded, just update sys.path for python imports
            sys.path.append(self.path)
            return

        env = str(_idausr_add(os.getenv('IDAUSR'), self.path))
        # XXX: find a more efficient way to ensure dependencies
        errors = []
        for dependency in self.metadata().get('dependencies', {}).keys():
            dep = LocalPackage.by_name(dependency)
            if not dep:
                errors.append('Dependency not found: %r' % dependency)
                continue
            dep.load()

        if errors:
            for error in errors:
                log.error(error)
            return

        def handler():
            assert isinstance(threading.current_thread(),
                              threading._MainThread)
            # Load plugins immediately
            # processors / loaders will be loaded on demand
            sys.path.append(self.path)

            # Update IDAUSR variable
            invalidate_idausr()
            putenv('IDAUSR', env)

            # Immediately load compatible plugins
            self._find_loadable_modules('plugins', ida_loader.load_plugin)

            # Find loadable processor modules, and if exists, invalidate cached process list (proccache).
            invalidates = []
            self._find_loadable_modules('procs', invalidates.append)

            if invalidates:
                invalidate_proccache()

        ida_kernwin.execute_sync(handler, ida_kernwin.MFF_FAST)
Example #8
0
    def load(self, force=False):
        """
        Actually does :code:`ida_loaders.load_plugin(paths)`, and updates IDAUSR variable.
        """
        if not force and self.path in ida_diskio.get_ida_subdirs(''):
            # Already loaded, just update sys.path for python imports
            if self.path not in sys.path:
                sys.path.append(self.path)
            return

        # XXX: find a more efficient way to ensure dependencies
        errors = []
        for dependency in self.info().get('dependencies', {}).keys():
            dep = LocalPackage.by_name(dependency)
            if not dep:
                errors.append('Dependency not found: %r' % dependency)
                continue
            dep.load()

        if errors:
            for error in errors:
                log.error(error)
            return

        def handler():
            # Load plugins immediately
            # processors / loaders will be loaded on demand
            if self.path not in sys.path:
                sys.path.append(self.path)

            # Update IDAUSR variable
            idausr_add(self.path)

            # Immediately load compatible plugins
            self._find_loadable_modules('plugins', ida_loader.load_plugin)

            # Find loadable processor modules, and if exists, invalidate cached process list (proccache).
            invalidates = []
            self._find_loadable_modules('procs', invalidates.append)

            if invalidates:
                invalidate_proccache()

        # Run in main thread
        ida_kernwin.execute_sync(handler, ida_kernwin.MFF_FAST)
Example #9
0
    def wrapper(*args, **kwargs):
        output = [None]

        #
        # this inline function definition is technically what will execute
        # in the context of the main thread. we use this thunk to capture
        # any output the function may want to return to the user.
        #

        def thunk():
            output[0] = function(*args, **kwargs)
            return 1

        if is_mainthread():
            thunk()
        else:
            ida_kernwin.execute_sync(thunk, sync_type)

        # return the output of the synchronized execution
        return output[0]
Example #10
0
def fit_widget_a():
    def do_fit_widget_a():
        ida_graph.viewer_fit_window(widget_a)

    ida_kernwin.execute_sync(do_fit_widget_a, ida_kernwin.MFF_FAST)
Example #11
0
    def handle(self):
        idaapi.msg("Accepting connection from {}\n".format(
            self.client_address[0]))
        while True:
            try:
                data = self.request.recv(1024).decode()
                if len(data) == 0:
                    break
                command = data.strip().split(' ')
                if len(command) == 0:
                    continue
                idaapi.msg('recv> ' + ' '.join(command) + '\n')
                result = False
                if command[0] == 'attachWithExit':
                    if ida_kernwin.execute_sync(ida_dbg.is_debugger_on, 0):
                        ida_kernwin.execute_sync(ida_dbg.exit_process, 0)
                    if len(command) == 1:
                        pid = ida_kernwin.execute_sync(
                            lambda: ida_dbg.attach_process(-1), 0) == 1
                    else:
                        pid = ida_kernwin.execute_sync(
                            lambda: ida_dbg.attach_process(int(command[1])),
                            0) == 1
                    result = (pid == 1)
                elif command[0] == 'continue':
                    result = ida_kernwin.execute_sync(ida_dbg.continue_process,
                                                      0) == 1
                elif command[0] == 'detach':
                    result = ida_kernwin.execute_sync(ida_dbg.detach_process,
                                                      0)
                elif command[0] == 'attach':
                    if len(command) == 1:
                        pid = ida_kernwin.execute_sync(
                            lambda: ida_dbg.attach_process(-1), 0) == 1
                    else:
                        pid = ida_kernwin.execute_sync(
                            lambda: ida_dbg.attach_process(int(command[1])),
                            0) == 1
                    result = (pid == 1)
                elif command[0] == 'exit':
                    result = ida_kernwin.execute_sync(ida_dbg.exit_process, 0)
                elif command[0] == 'isDebugging':
                    result = ida_kernwin.execute_sync(ida_dbg.is_debugger_on,
                                                      0)

                idaapi.msg('res>  ' + str(result) + '\n')
                if result:
                    self.request.sendall(b'T\n')
                else:
                    self.request.sendall(b'F\n')
            except:
                traceback.print_exc()

        idaapi.msg("Closing connection from {}\n".format(
            self.client_address[0]))