(self, seq, i, node, addr2nodes: Dict,
                                                      jump_tables: Dict[int,IndirectJump])
return True
A typical jump table involves multiple nodes, which look like the following:

        Head:  s_50 = Conv(32->64, (Load(addr=stack_base-28, size=4, endness=Iend_LE) - 0x3f<32>))<8>
               if (((Load(addr=stack_base-28, size=4, endness=Iend_LE) - 0x3f<32>) <= 0x36<32>))
                    { Goto A<64> } else { Goto B<64> }

        A:     (with an indirect jump)
               Goto((Conv(32->64, Load(addr=(0x40964c<64> + (Load(addr=stack_base-80, size=8, endness=Iend_LE) Mul 0x4<8>)), size=4, endness=Iend_LE)) + 0x40964c<64>))

        B:     (the default case)
A typical jump table involves multiple nodes, which look like the following:
A typical jump table involves multiple nodes which look like the following :
def _make_switch_cases_address_loaded_from_memory(self, seq, i, node, addr2nodes: Dict,
                                                      jump_tables: Dict[int,IndirectJump]) -> bool:
        """
        A typical jump table involves multiple nodes, which look like the following:

        Head:  s_50 = Conv(32->64, (Load(addr=stack_base-28, size=4, endness=Iend_LE) - 0x3f<32>))<8>
               if (((Load(addr=stack_base-28, size=4, endness=Iend_LE) - 0x3f<32>) <= 0x36<32>))
                    { Goto A<64> } else { Goto B<64> }

        A:     (with an indirect jump)
               Goto((Conv(32->64, Load(addr=(0x40964c<64> + (Load(addr=stack_base-80, size=8, endness=Iend_LE) Mul 0x4<8>)), size=4, endness=Iend_LE)) + 0x40964c<64>))

        B:     (the default case)
        """

        try:
            last_stmt = self.cond_proc.get_last_statement(node)
        except EmptyBlockNotice:
            return False
        successor_addrs = extract_jump_targets(last_stmt)
        if len(successor_addrs) != 2:
            return False

        for t in successor_addrs:
            if t in addr2nodes and t in jump_tables:
                # this is a candidate!
                target = t
                break
        else:
            return False

        jump_table = jump_tables[target]
        if jump_table.type != IndirectJumpType.Jumptable_AddressLoadedFromMemory:
            return False

        # extract the comparison expression, lower-, and upper-bounds from the last statement
        cmp = switch_extract_cmp_bounds(last_stmt)
        if not cmp:
            return False
        cmp_expr, cmp_lb, cmp_ub = cmp  # pylint:disable=unused-variable

        # the real indirect jump
        node_a = addr2nodes[target]
        # the default case
        node_b_addr = next(iter(t for t in successor_addrs if t != target))

        # Node A might have been structured. Un-structure it if that is the case.
        r, node_a = self._switch_unpack_sequence_node(seq, node_a, node_b_addr, jump_table.jumptable_entries,
                                                      addr2nodes)
        if not r:
            return False

        # build switch-cases
        cases, node_default, to_remove = self._switch_build_cases(seq, cmp_lb, jump_table.jumptable_entries,
                                                                  node_b_addr, addr2nodes)
        if node_default is None:
            switch_end_addr = node_b_addr
        else:
            # we don't know what the end address of this switch-case structure is. let's figure it out
            switch_end_addr = None
        self._switch_handle_gotos(cases, node_default, switch_end_addr)

        self._make_switch_cases_core(seq, i, node, cmp_expr, cases, node_default, last_stmt.ins_addr, addr2nodes,
                                     to_remove, node_a=node_a)

        return True
def _make_switch_cases_address_loaded_from_memory ( self , seq , i , node , addr2nodes : Dict , jump_tables : Dict [ int , IndirectJump ] ) -> bool : try : last_stmt = self . cond_proc . get_last_statement ( node ) except EmptyBlockNotice : return False successor_addrs = extract_jump_targets ( last_stmt ) if len ( successor_addrs ) != 2 : return False for t in successor_addrs : if t in addr2nodes and t in jump_tables : # this is a candidate! target = t break else : return False jump_table = jump_tables [ target ] if jump_table . type != IndirectJumpType . Jumptable_AddressLoadedFromMemory : return False # extract the comparison expression, lower-, and upper-bounds from the last statement cmp = switch_extract_cmp_bounds ( last_stmt ) if not cmp : return False cmp_expr , cmp_lb , cmp_ub = cmp # pylint:disable=unused-variable # the real indirect jump node_a = addr2nodes [ target ] # the default case node_b_addr = next ( iter ( t for t in successor_addrs if t != target ) ) # Node A might have been structured. Un-structure it if that is the case. r , node_a = self . _switch_unpack_sequence_node ( seq , node_a , node_b_addr , jump_table . jumptable_entries , addr2nodes ) if not r : return False # build switch-cases cases , node_default , to_remove = self . _switch_build_cases ( seq , cmp_lb , jump_table . jumptable_entries , node_b_addr , addr2nodes ) if node_default is None : switch_end_addr = node_b_addr else : # we don't know what the end address of this switch-case structure is. let's figure it out switch_end_addr = None self . _switch_handle_gotos ( cases , node_default , switch_end_addr ) self . _make_switch_cases_core ( seq , i , node , cmp_expr , cases , node_default , last_stmt . ins_addr , addr2nodes , to_remove , node_a = node_a ) return True