(self, data_addr, max_size, content_holder=None)
return None, None
Make a guess to the data type.

        Users can provide their own data type guessing code when initializing CFGFast instance, and each guessing
        handler will be called if this method fails to determine what the data is.

        :param int data_addr: Address of the data.
        :param int max_size: The maximum size this data entry can be.
        :return: a tuple of (data type, size). (None, None) if we fail to determine the type or the size.
        :rtype: tuple
Make a guess to the data type.
Make a guess to the data type .
def _guess_data_type(self, data_addr, max_size, content_holder=None):
        """
        Make a guess to the data type.

        Users can provide their own data type guessing code when initializing CFGFast instance, and each guessing
        handler will be called if this method fails to determine what the data is.

        :param int data_addr: Address of the data.
        :param int max_size: The maximum size this data entry can be.
        :return: a tuple of (data type, size). (None, None) if we fail to determine the type or the size.
        :rtype: tuple
        """
        if max_size is None:
            max_size = 0

        # quick check: if it's at the beginning of a binary, it might be the ELF header
        elfheader_sort, elfheader_size = self._guess_data_type_elfheader(data_addr, max_size)
        if elfheader_sort:
            return elfheader_sort, elfheader_size

        try:
            ref = next(iter(self.kb.xrefs.get_xrefs_by_dst(data_addr)))  # type: XRef
            irsb_addr = ref.block_addr
            stmt_idx = ref.stmt_idx
        except StopIteration:
            irsb_addr, stmt_idx = None, None


        if self._seg_list.is_occupied(data_addr) and self._seg_list.occupied_by_sort(data_addr) == 'code':
            # it's a code reference
            # TODO: Further check if it's the beginning of an instruction
            return MemoryDataSort.CodeReference, 0

        pointer_size = self.project.arch.bytes

        # who's using it?
        if isinstance(self.project.loader.main_object, cle.MetaELF):
            plt_entry = self.project.loader.main_object.reverse_plt.get(irsb_addr, None)
            if plt_entry is not None:
                # IRSB is owned by plt!
                return MemoryDataSort.GOTPLTEntry, pointer_size

        # is it in a section with zero bytes, like .bss?
        obj = self.project.loader.find_object_containing(data_addr)
        if obj is None:
            return None, None
        section = obj.find_section_containing(data_addr)
        if section is not None and section.only_contains_uninitialized_data:
            # Nothing much you can do
            return None, None

        r = self._guess_data_type_pointer_array(data_addr, pointer_size, max_size)
        if r is not None:
            return r

        try:
            data = self.project.loader.memory.load(data_addr, 1024)
        except KeyError:
            data = b''

        # Is it an unicode string?
        # TODO: Support unicode string longer than the max length
        if len(data) >= 4 and data[1] == 0 and data[3] == 0 and data[0] in self.PRINTABLES:
            def can_decode(n):
                try:
                    data[:n*2].decode('utf_16_le')
                except UnicodeDecodeError:
                    return False
                return True
            if can_decode(4) or can_decode(5) or can_decode(6):
                running_failures = 0
                last_success = 4
                for i in range(4, len(data) // 2):
                    if can_decode(i):
                        last_success = i
                        running_failures = 0
                        if data[i*2-2] == 0 and data[i*2-1] == 0:
                            break
                    else:
                        running_failures += 1
                        if running_failures > 3:
                            break

                return MemoryDataSort.UnicodeString, last_success

        if data:
            try:
                zero_pos = data.index(0)
            except ValueError:
                zero_pos = None
            if (zero_pos is not None and zero_pos > 0 and all(c in self.PRINTABLES for c in data[:zero_pos])) or \
                    all(c in self.PRINTABLES for c in data):
                # it's a string
                # however, it may not be terminated
                string_data = data if zero_pos is None else data[:zero_pos]
                if content_holder is not None:
                    content_holder.append(string_data)
                return MemoryDataSort.String, min(len(string_data) + 1, 1024)

        for handler in self._data_type_guessing_handlers:
            irsb = None if irsb_addr is None else self.model.get_any_node(irsb_addr).block.vex
            sort, size = handler(self, irsb, irsb_addr, stmt_idx, data_addr, max_size)
            if sort is not None:
                return sort, size

        return None, None
def _guess_data_type ( self , data_addr , max_size , content_holder = None ) : if max_size is None : max_size = 0 # quick check: if it's at the beginning of a binary, it might be the ELF header elfheader_sort , elfheader_size = self . _guess_data_type_elfheader ( data_addr , max_size ) if elfheader_sort : return elfheader_sort , elfheader_size try : ref = next ( iter ( self . kb . xrefs . get_xrefs_by_dst ( data_addr ) ) ) # type: XRef irsb_addr = ref . block_addr stmt_idx = ref . stmt_idx except StopIteration : irsb_addr , stmt_idx = None , None if self . _seg_list . is_occupied ( data_addr ) and self . _seg_list . occupied_by_sort ( data_addr ) == 'code' : # it's a code reference # TODO: Further check if it's the beginning of an instruction return MemoryDataSort . CodeReference , 0 pointer_size = self . project . arch . bytes # who's using it? if isinstance ( self . project . loader . main_object , cle . MetaELF ) : plt_entry = self . project . loader . main_object . reverse_plt . get ( irsb_addr , None ) if plt_entry is not None : # IRSB is owned by plt! return MemoryDataSort . GOTPLTEntry , pointer_size # is it in a section with zero bytes, like .bss? obj = self . project . loader . find_object_containing ( data_addr ) if obj is None : return None , None section = obj . find_section_containing ( data_addr ) if section is not None and section . only_contains_uninitialized_data : # Nothing much you can do return None , None r = self . _guess_data_type_pointer_array ( data_addr , pointer_size , max_size ) if r is not None : return r try : data = self . project . loader . memory . load ( data_addr , 1024 ) except KeyError : data = b'' # Is it an unicode string? # TODO: Support unicode string longer than the max length if len ( data ) >= 4 and data [ 1 ] == 0 and data [ 3 ] == 0 and data [ 0 ] in self . PRINTABLES : def can_decode ( n ) : try : data [ : n * 2 ] . decode ( 'utf_16_le' ) except UnicodeDecodeError : return False return True if can_decode ( 4 ) or can_decode ( 5 ) or can_decode ( 6 ) : running_failures = 0 last_success = 4 for i in range ( 4 , len ( data ) // 2 ) : if can_decode ( i ) : last_success = i running_failures = 0 if data [ i * 2 - 2 ] == 0 and data [ i * 2 - 1 ] == 0 : break else : running_failures += 1 if running_failures > 3 : break return MemoryDataSort . UnicodeString , last_success if data : try : zero_pos = data . index ( 0 ) except ValueError : zero_pos = None if ( zero_pos is not None and zero_pos > 0 and all ( c in self . PRINTABLES for c in data [ : zero_pos ] ) ) or all ( c in self . PRINTABLES for c in data ) : # it's a string # however, it may not be terminated string_data = data if zero_pos is None else data [ : zero_pos ] if content_holder is not None : content_holder . append ( string_data ) return MemoryDataSort . String , min ( len ( string_data ) + 1 , 1024 ) for handler in self . _data_type_guessing_handlers : irsb = None if irsb_addr is None else self . model . get_any_node ( irsb_addr ) . block . vex sort , size = handler ( self , irsb , irsb_addr , stmt_idx , data_addr , max_size ) if sort is not None : return sort , size return None , None