(self)
return new_data_found
:return: True if new data entries are found, False otherwise.
        :rtype: bool
def _tidy_data_references(self):
        """

        :return: True if new data entries are found, False otherwise.
        :rtype: bool
        """

        # Make sure all memory data entries cover all data sections
        keys = sorted(self._memory_data.keys())
        for i, data_addr in enumerate(keys):
            data = self._memory_data[data_addr]
            if self._addr_in_exec_memory_regions(data.address):
                # TODO: Handle data in code regions (or executable regions)
                pass
            else:
                if i + 1 != len(keys):
                    next_data_addr = keys[i + 1]
                else:
                    next_data_addr = None

                # goes until the end of the section/segment
                # TODO: the logic needs more testing

                sec = self.project.loader.find_section_containing(data_addr)
                next_sec_addr = None
                if sec is not None:
                    last_addr = sec.vaddr + sec.memsize
                else:
                    # it does not belong to any section. what's the next adjacent section? any memory data does not go
                    # beyong section boundaries
                    next_sec = self.project.loader.find_section_next_to(data_addr)
                    if next_sec is not None:
                        next_sec_addr = next_sec.vaddr

                    seg = self.project.loader.find_segment_containing(data_addr)
                    if seg is not None:
                        last_addr = seg.vaddr + seg.memsize
                    else:
                        # We got an address that is not inside the current binary...
                        l.warning('_tidy_data_references() sees an address %#08x that does not belong to any '
                                  'section or segment.', data_addr
                                  )
                        last_addr = None

                if next_data_addr is None:
                    boundary = last_addr
                elif last_addr is None:
                    boundary = next_data_addr
                else:
                    boundary = min(last_addr, next_data_addr)

                if next_sec_addr is not None:
                    boundary = min(boundary, next_sec_addr)

                if boundary is not None:
                    data.max_size = boundary - data_addr

                if data.max_size is None:
                    print('wtf')

        keys = sorted(self._memory_data.keys())

        new_data_found = False

        i = 0
        # pylint:disable=too-many-nested-blocks
        while i < len(keys):
            data_addr = keys[i]
            i += 1

            memory_data = self._memory_data[data_addr]

            if memory_data.sort == MemoryDataSort.SegmentBoundary:
                continue

            content_holder = [ ]

            # let's see what sort of data it is
            if memory_data.sort in (MemoryDataSort.Unknown, MemoryDataSort.Unspecified) or \
                    (memory_data.sort == MemoryDataSort.Integer and memory_data.size == self.project.arch.bytes):
                data_type, data_size = self._guess_data_type(data_addr, memory_data.max_size,
                                                             content_holder=content_holder)
            else:
                data_type, data_size = memory_data.sort, memory_data.size

            if data_type is not None:
                memory_data.size = data_size
                memory_data.sort = data_type

                if len(content_holder) == 1:
                    memory_data.content = content_holder[0]

                if memory_data.max_size is not None and (0 < memory_data.size < memory_data.max_size):
                    # Create another memory_data object to fill the gap
                    new_addr = data_addr + memory_data.size
                    new_md = MemoryData(new_addr, None, None, max_size=memory_data.max_size - memory_data.size)
                    self._memory_data[new_addr] = new_md
                    # Make a copy of all old references
                    old_crs = self.kb.xrefs.get_xrefs_by_dst(data_addr)
                    crs = [ ]
                    for old_cr in old_crs:
                        cr = old_cr.copy()
                        cr.memory_data = new_md
                        crs.append(cr)
                    self.kb.xrefs.add_xrefs(crs)
                    keys.insert(i, new_addr)

                if data_type == MemoryDataSort.PointerArray:
                    # make sure all pointers are identified
                    pointer_size = self.project.arch.bytes
                    old_crs = self.kb.xrefs.get_xrefs_by_dst(data_addr)

                    for j in range(0, data_size, pointer_size):
                        ptr = self._fast_memory_load_pointer(data_addr + j)

                        # is this pointer coming from the current binary?
                        obj = self.project.loader.find_object_containing(ptr, membership_check=False)
                        if obj is not self.project.loader.main_object:
                            # the pointer does not come from current binary. skip.
                            continue

                        if self._seg_list.is_occupied(ptr):
                            sort = self._seg_list.occupied_by_sort(ptr)
                            if sort == 'code':
                                continue
                            if sort == 'pointer-array':
                                continue
                            # TODO: other types
                        if ptr not in self._memory_data:
                            new_md = MemoryData(ptr, 0, MemoryDataSort.Unknown, pointer_addr=data_addr + j)
                            self._memory_data[ptr] = new_md
                            # Make a copy of the old reference
                            crs = [ ]
                            for old_cr in old_crs:
                                cr = old_cr.copy()
                                cr.memory_data = new_md
                                crs.append(cr)
                            self.kb.xrefs.add_xrefs(crs)
                            new_data_found = True

            else:
                memory_data.size = memory_data.max_size

            self._seg_list.occupy(data_addr, memory_data.size, memory_data.sort)

        return new_data_found
def _tidy_data_references ( self ) : # Make sure all memory data entries cover all data sections keys = sorted ( self . _memory_data . keys ( ) ) for i , data_addr in enumerate ( keys ) : data = self . _memory_data [ data_addr ] if self . _addr_in_exec_memory_regions ( data . address ) : # TODO: Handle data in code regions (or executable regions) pass else : if i + 1 != len ( keys ) : next_data_addr = keys [ i + 1 ] else : next_data_addr = None # goes until the end of the section/segment # TODO: the logic needs more testing sec = self . project . loader . find_section_containing ( data_addr ) next_sec_addr = None if sec is not None : last_addr = sec . vaddr + sec . memsize else : # it does not belong to any section. what's the next adjacent section? any memory data does not go # beyong section boundaries next_sec = self . project . loader . find_section_next_to ( data_addr ) if next_sec is not None : next_sec_addr = next_sec . vaddr seg = self . project . loader . find_segment_containing ( data_addr ) if seg is not None : last_addr = seg . vaddr + seg . memsize else : # We got an address that is not inside the current binary... l . warning ( '_tidy_data_references() sees an address %#08x that does not belong to any ' 'section or segment.' , data_addr ) last_addr = None if next_data_addr is None : boundary = last_addr elif last_addr is None : boundary = next_data_addr else : boundary = min ( last_addr , next_data_addr ) if next_sec_addr is not None : boundary = min ( boundary , next_sec_addr ) if boundary is not None : data . max_size = boundary - data_addr if data . max_size is None : print ( 'wtf' ) keys = sorted ( self . _memory_data . keys ( ) ) new_data_found = False i = 0 # pylint:disable=too-many-nested-blocks while i < len ( keys ) : data_addr = keys [ i ] i += 1 memory_data = self . _memory_data [ data_addr ] if memory_data . sort == MemoryDataSort . SegmentBoundary : continue content_holder = [ ] # let's see what sort of data it is if memory_data . sort in ( MemoryDataSort . Unknown , MemoryDataSort . Unspecified ) or ( memory_data . sort == MemoryDataSort . Integer and memory_data . size == self . project . arch . bytes ) : data_type , data_size = self . _guess_data_type ( data_addr , memory_data . max_size , content_holder = content_holder ) else : data_type , data_size = memory_data . sort , memory_data . size if data_type is not None : memory_data . size = data_size memory_data . sort = data_type if len ( content_holder ) == 1 : memory_data . content = content_holder [ 0 ] if memory_data . max_size is not None and ( 0 < memory_data . size < memory_data . max_size ) : # Create another memory_data object to fill the gap new_addr = data_addr + memory_data . size new_md = MemoryData ( new_addr , None , None , max_size = memory_data . max_size - memory_data . size ) self . _memory_data [ new_addr ] = new_md # Make a copy of all old references old_crs = self . kb . xrefs . get_xrefs_by_dst ( data_addr ) crs = [ ] for old_cr in old_crs : cr = old_cr . copy ( ) cr . memory_data = new_md crs . append ( cr ) self . kb . xrefs . add_xrefs ( crs ) keys . insert ( i , new_addr ) if data_type == MemoryDataSort . PointerArray : # make sure all pointers are identified pointer_size = self . project . arch . bytes old_crs = self . kb . xrefs . get_xrefs_by_dst ( data_addr ) for j in range ( 0 , data_size , pointer_size ) : ptr = self . _fast_memory_load_pointer ( data_addr + j ) # is this pointer coming from the current binary? obj = self . project . loader . find_object_containing ( ptr , membership_check = False ) if obj is not self . project . loader . main_object : # the pointer does not come from current binary. skip. continue if self . _seg_list . is_occupied ( ptr ) : sort = self . _seg_list . occupied_by_sort ( ptr ) if sort == 'code' : continue if sort == 'pointer-array' : continue # TODO: other types if ptr not in self . _memory_data : new_md = MemoryData ( ptr , 0 , MemoryDataSort . Unknown , pointer_addr = data_addr + j ) self . _memory_data [ ptr ] = new_md # Make a copy of the old reference crs = [ ] for old_cr in old_crs : cr = old_cr . copy ( ) cr . memory_data = new_md crs . append ( cr ) self . kb . xrefs . add_xrefs ( crs ) new_data_found = True else : memory_data . size = memory_data . max_size self . _seg_list . occupy ( data_addr , memory_data . size , memory_data . sort ) return new_data_found