(self)
Backward slicing.

        We support the following IRStmts:
        # WrTmp
        # Put

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

        :return:
Backward slicing.
Backward slicing .
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)?
        try:
            stmts = self._get_irsb(self._dst_run).statements
        except SimTranslationError:
            return

        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_STATEMENT)

        if not temps and not regs:
            # no dependency
            return

        slicer = 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 'jumpkind' in data:
                    if self._stop_at_calls and data['jumpkind'] == 'Ijk_Call':
                        # Skip calls
                        continue
                if self.project.is_hooked(pred.addr):
                    # Skip SimProcedures
                    continue
                self._backward_slice_recursive(self._max_level - 1, pred, regs, stack_offsets, prev,
                                               data.get('stmt_idx', None)
                                               )
def _backward_slice ( self ) : temps = set ( ) regs = set ( ) # Retrieve the target: are we slicing from a register(IRStmt.Put), or a temp(IRStmt.WrTmp)? try : stmts = self . _get_irsb ( self . _dst_run ) . statements except SimTranslationError : return 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_STATEMENT ) if not temps and not regs : # no dependency return slicer = 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 'jumpkind' in data : if self . _stop_at_calls and data [ 'jumpkind' ] == 'Ijk_Call' : # Skip calls continue if self . project . is_hooked ( pred . addr ) : # Skip SimProcedures continue self . _backward_slice_recursive ( self . _max_level - 1 , pred , regs , stack_offsets , prev , data . get ( 'stmt_idx' , None ) )