예제 #1
0
    def _backward_slice_recursive(self, run, regs, prev):
        temps = set()
        regs = regs.copy()

        stmts = self._get_run(run).irsb.statements

        # Initialize the temps set with whatever in the `next` attribute of this irsb
        next_expr = self._get_run(run).irsb.next
        if type(next_expr) is pyvex.IRExpr.RdTmp:
            temps.add(next_expr.tmp)

        slicer = simuvex.SimSlicer(stmts,
                                   temps,
                                   regs,
                                   inslice_callback=self._inslice_callback,
                                   inslice_callback_infodict={
                                       'irsb_addr': self._get_run(run).addr,
                                       'prev': prev
                                   })
        regs = slicer.final_regs

        prev = slicer.inslice_callback_infodict['prev']

        if regs:
            predecessors = self._graph.predecessors(self._normalize(run))

            for p in predecessors:
                if p not in self._traced_runs:
                    self._traced_runs.add(p)
                    self._backward_slice_recursive(p, regs, prev)
예제 #2
0
    def _backward_slice_recursive(self, level, run, regs, stack_offsets, prev, exit_stmt_idx):

        if level <= 0:
            return

        temps = set()
        regs = regs.copy()

        stmts = self._get_irsb(run).statements

        if exit_stmt_idx is None or exit_stmt_idx == 'default':
            # Initialize the temps set with whatever in the `next` attribute of this irsb
            next_expr = self._get_irsb(run).next
            if type(next_expr) is pyvex.IRExpr.RdTmp:
                temps.add(next_expr.tmp)

        else:
            exit_stmt = self._get_irsb(run).statements[exit_stmt_idx]

            if type(exit_stmt.guard) is pyvex.IRExpr.RdTmp:
                temps.add(exit_stmt.guard.tmp)

            # Put it in our slice
            irsb_addr = self._get_addr(run)
            self._inslice_callback(exit_stmt_idx, exit_stmt, {'irsb_addr': irsb_addr, 'prev': prev})
            prev = (irsb_addr, exit_stmt_idx)

        slicer = simuvex.SimSlicer(self.project.arch, stmts,
                                   target_tmps=temps,
                                   target_regs=regs,
                                   target_stack_offsets=stack_offsets,
                                   inslice_callback=self._inslice_callback,
                                   inslice_callback_infodict={
                                       'irsb_addr' : self._get_addr(run),
                                       'prev' : prev
                                   })
        regs = slicer.final_regs

        if self._ignore_sp and self.project.arch.sp_offset in regs:
            regs.remove(self.project.arch.sp_offset)
        if self._ignore_bp and self.project.arch.bp_offset in regs:
            regs.remove(self.project.arch.bp_offset)

        stack_offsets = slicer.final_stack_offsets

        prev = slicer.inslice_callback_infodict['prev']

        if regs or stack_offsets:
            in_edges = self._graph.in_edges(self._get_cfgnode(run), data=True)

            for pred, _, data in in_edges:
                if pred not in self._traced_runs:
                    self._traced_runs.add(pred)
                    self._backward_slice_recursive(level - 1, pred, regs, stack_offsets, prev, data['stmt_idx'])
예제 #3
0
    def _backward_slice(self):
        '''
        Backward slicing.

        We support the following IRStmts:
        # WrTmp
        # Put

        We support the following IRExprs:
        # Get
        # RdTmp
        # Const

        :return:
        '''

        temps = set()
        regs = set()

        # Retrieve the target: are we slicing from a register(IRStmt.Put), or a temp(IRStmt.WrTmp)?
        stmts = self._get_run(self._dst_run).irsb.statements

        if self._dst_stmt_idx != -1:
            dst_stmt = stmts[self._dst_stmt_idx]

            if type(dst_stmt) is pyvex.IRStmt.Put:
                regs.add(dst_stmt.offset)
            elif type(dst_stmt) is pyvex.IRStmt.WrTmp:
                temps.add(dst_stmt.tmp)
            else:
                raise AngrBladeError(
                    'Incorrect type of the specified target statement. We only support Put and WrTmp.'
                )

        else:
            next_expr = self._get_run(self._dst_run).irsb.next

            if type(next_expr) is pyvex.IRExpr.RdTmp:
                temps.add(next_expr.tmp)
            elif type(next_expr) is pyvex.IRExpr.Const:
                # A const doesn't rely on anything else!
                pass
            else:
                raise AngrBladeError('Unsupported type for irsb.next: %s' %
                                     type(next_expr))

            # Then we gotta start from the very last statement!
            self._dst_stmt_idx = len(stmts) - 1

        slicer = simuvex.SimSlicer(stmts,
                                   temps,
                                   regs,
                                   inslice_callback=self._inslice_callback,
                                   inslice_callback_infodict={
                                       'irsb_addr':
                                       self._get_run(self._dst_run).addr
                                   })
        regs = slicer.final_regs

        prev = slicer.inslice_callback_infodict['prev']

        if regs:
            predecessors = self._graph.predecessors(
                self._normalize(self._dst_run))

            for p in predecessors:
                if p not in self._traced_runs:
                    self._traced_runs.add(p)
                    self._backward_slice_recursive(p, regs, prev)
예제 #4
0
    def _backward_slice(self):
        """
        Backward slicing.

        We support the following IRStmts:
        # WrTmp
        # Put

        We support the following IRExprs:
        # Get
        # RdTmp
        # Const

        :return:
        """

        temps = set()
        regs = set()

        # Retrieve the target: are we slicing from a register(IRStmt.Put), or a temp(IRStmt.WrTmp)?
        stmts = self._get_irsb(self._dst_run).statements

        if self._dst_stmt_idx != -1:
            dst_stmt = stmts[self._dst_stmt_idx]

            if type(dst_stmt) is pyvex.IRStmt.Put:
                regs.add(dst_stmt.offset)
            elif type(dst_stmt) is pyvex.IRStmt.WrTmp:
                temps.add(dst_stmt.tmp)
            else:
                raise AngrBladeError('Incorrect type of the specified target statement. We only support Put and WrTmp.')

            prev = (self._get_addr(self._dst_run), self._dst_stmt_idx)
        else:

            next_expr = self._get_irsb(self._dst_run).next

            if type(next_expr) is pyvex.IRExpr.RdTmp:
                temps.add(next_expr.tmp)
            elif type(next_expr) is pyvex.IRExpr.Const:
                # A const doesn't rely on anything else!
                pass
            else:
                raise AngrBladeError('Unsupported type for irsb.next: %s' % type(next_expr))

            # Then we gotta start from the very last statement!
            self._dst_stmt_idx = len(stmts) - 1

            prev = (self._get_addr(self._dst_run), 'default')

        slicer = simuvex.SimSlicer(self.project.arch, stmts,
                                   target_tmps=temps,
                                   target_regs=regs,
                                   target_stack_offsets=None,
                                   inslice_callback=self._inslice_callback,
                                   inslice_callback_infodict={
                                       'irsb_addr':  self._get_irsb(self._dst_run)._addr,
                                       'prev': prev,
                                   })
        regs = slicer.final_regs
        if self._ignore_sp and self.project.arch.sp_offset in regs:
            regs.remove(self.project.arch.sp_offset)
        if self._ignore_bp and self.project.arch.bp_offset in regs:
            regs.remove(self.project.arch.bp_offset)
        for offset in self._ignored_regs:
            if offset in regs:
                regs.remove(offset)

        stack_offsets = slicer.final_stack_offsets

        prev = slicer.inslice_callback_infodict['prev']

        if regs or stack_offsets:
            cfgnode = self._get_cfgnode(self._dst_run)
            in_edges = self._graph.in_edges(cfgnode, data=True)

            for pred, _, data in in_edges:
                if pred not in self._traced_runs:
                    self._traced_runs.add(pred)
                    self._backward_slice_recursive(self._max_level - 1, pred, regs, stack_offsets, prev, data['stmt_idx'])