(self, cfg, addr, func_addr, block, jumpkind, max_level)
return False, [ ]
Resolves the indirect jump in MIPS ELF binaries where all external function calls are indexed using gp.

        :param cfg: A CFG instance.
        :param int addr: IRSB address.
        :param int func_addr: The function address.
        :param pyvex.IRSB block: The IRSB.
        :param str jumpkind: The jumpkind.
        :param int max_level: maximum level for Blade to resolve when looking for sources
        :return: If it was resolved and targets alongside it
        :rtype: tuple
Resolves the indirect jump in MIPS ELF binaries where all external function calls are indexed using gp.
Resolves the indirect jump in MIPS ELF binaries where all external function calls are indexed using gp .
def _resolve(self, cfg, addr, func_addr, block, jumpkind, max_level):
        """
        Resolves the indirect jump in MIPS ELF binaries where all external function calls are indexed using gp.

        :param cfg: A CFG instance.
        :param int addr: IRSB address.
        :param int func_addr: The function address.
        :param pyvex.IRSB block: The IRSB.
        :param str jumpkind: The jumpkind.
        :param int max_level: maximum level for Blade to resolve when looking for sources
        :return: If it was resolved and targets alongside it
        :rtype: tuple
        """

        project = self.project

        b = Blade(cfg.graph, addr, -1, cfg=cfg, project=project, ignore_sp=True, ignore_bp=True,
                  ignored_regs=('gp',), cross_insn_opt=False, stop_at_calls=True, max_level=max_level
                  )

        sources = [n for n in b.slice.nodes() if b.slice.in_degree(n) == 0]
        if not sources:
            return False, []

        source = sources[0]
        source_addr = source[0]
        annotated_cfg = AnnotatedCFG(project, None, detect_loops=False)
        annotated_cfg.from_digraph(b.slice)

        state = project.factory.blank_state(addr=source_addr, mode="fastpath",
                                            remove_options=options.refs,
                                            # suppress unconstrained stack reads for `gp`
                                            add_options={
                                                options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS,
                                                options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
                                                options.NO_CROSS_INSN_OPT,
                                            },
                                            )
        state.regs._t9 = func_addr
        func = cfg.kb.functions.function(addr=func_addr)

        # see if gp is used on this slice at all
        gp_used = self._is_gp_used_on_slice(project, b)

        gp_value = None
        if gp_used:
            if 'gp' not in func.info:
                # this might a special case: gp is only used once in this function, and it can be initialized right
                # before its use site.
                # however, it should have been determined in CFGFast
                # cannot determine the value of gp. quit
                pass
            else:
                gp_value = func.info['gp']

            if gp_value is None:
                l.warning('Failed to determine value of register gp for function %#x.', func.addr)
                return False, []

            # Special handling for cases where `gp` is stored on the stack
            gp_offset = project.arch.registers['gp'][0]
            self._set_gp_load_callback(state, b, project, gp_offset, gp_value)
            state.regs._gp = gp_value

        simgr = self.project.factory.simulation_manager(state)
        simgr.use_technique(Slicecutor(annotated_cfg, force_sat=True))
        simgr.run()

        if simgr.cut:
            # pick the successor that is cut right after executing `addr`
            try:
                target_state = next(iter(cut for cut in simgr.cut if cut.history.addr == addr))
            except StopIteration:
                l.info("Indirect jump at %#x cannot be resolved by %s.", addr, repr(self))
                return False, [ ]
            target = target_state.addr

            if self._is_target_valid(cfg, target) and target != func_addr:
                l.debug("Indirect jump at %#x is resolved to target %#x.", addr, target)
                return True, [ target ]

            l.info("Indirect jump at %#x is resolved to target %#x, which seems to be invalid.", addr, target)
            return False, [ ]

        l.info("Indirect jump at %#x cannot be resolved by %s.", addr, repr(self))
        return False, [ ]
def _resolve ( self , cfg , addr , func_addr , block , jumpkind , max_level ) : project = self . project b = Blade ( cfg . graph , addr , - 1 , cfg = cfg , project = project , ignore_sp = True , ignore_bp = True , ignored_regs = ( 'gp' , ) , cross_insn_opt = False , stop_at_calls = True , max_level = max_level ) sources = [ n for n in b . slice . nodes ( ) if b . slice . in_degree ( n ) == 0 ] if not sources : return False , [ ] source = sources [ 0 ] source_addr = source [ 0 ] annotated_cfg = AnnotatedCFG ( project , None , detect_loops = False ) annotated_cfg . from_digraph ( b . slice ) state = project . factory . blank_state ( addr = source_addr , mode = "fastpath" , remove_options = options . refs , # suppress unconstrained stack reads for `gp` add_options = { options . SYMBOL_FILL_UNCONSTRAINED_REGISTERS , options . SYMBOL_FILL_UNCONSTRAINED_MEMORY , options . NO_CROSS_INSN_OPT , } , ) state . regs . _t9 = func_addr func = cfg . kb . functions . function ( addr = func_addr ) # see if gp is used on this slice at all gp_used = self . _is_gp_used_on_slice ( project , b ) gp_value = None if gp_used : if 'gp' not in func . info : # this might a special case: gp is only used once in this function, and it can be initialized right # before its use site. # however, it should have been determined in CFGFast # cannot determine the value of gp. quit pass else : gp_value = func . info [ 'gp' ] if gp_value is None : l . warning ( 'Failed to determine value of register gp for function %#x.' , func . addr ) return False , [ ] # Special handling for cases where `gp` is stored on the stack gp_offset = project . arch . registers [ 'gp' ] [ 0 ] self . _set_gp_load_callback ( state , b , project , gp_offset , gp_value ) state . regs . _gp = gp_value simgr = self . project . factory . simulation_manager ( state ) simgr . use_technique ( Slicecutor ( annotated_cfg , force_sat = True ) ) simgr . run ( ) if simgr . cut : # pick the successor that is cut right after executing `addr` try : target_state = next ( iter ( cut for cut in simgr . cut if cut . history . addr == addr ) ) except StopIteration : l . info ( "Indirect jump at %#x cannot be resolved by %s." , addr , repr ( self ) ) return False , [ ] target = target_state . addr if self . _is_target_valid ( cfg , target ) and target != func_addr : l . debug ( "Indirect jump at %#x is resolved to target %#x." , addr , target ) return True , [ target ] l . info ( "Indirect jump at %#x is resolved to target %#x, which seems to be invalid." , addr , target ) return False , [ ] l . info ( "Indirect jump at %#x cannot be resolved by %s." , addr , repr ( self ) ) return False , [ ]