Пример #1
0
def readProcessMappings(process):
    """
    Read all memory mappings of the specified process.

    Return a list of MemoryMapping objects, or empty list if it's not possible
    to read the mappings.

    May raise a ProcessError.
    """
    maps = []
    if not HAS_PROC:
        return maps
    try:
        mapsfile = openProc(process.pid)
    except ProcError as err:
        raise ProcessError(process, "Unable to read process maps: %s" % err)

    before = None
    # save the current ctypes module.
    mappings = Mappings(None)
    # FIXME Debug, but probably useless now that ctypes is in config
    if True:
        import ctypes
        before = ctypes
    try:
        for line in mapsfile:
            line = line.rstrip()
            match = PROC_MAP_REGEX.match(line)
            if not match:
                raise ProcessError(
                    process,
                    "Unable to parse memory mapping: %r" %
                    line)
            log.debug('readProcessMappings %s' % (str(match.groups())))
            _map = ProcessMemoryMapping(
                # cfg,
                process,
                int(match.group(1), 16),
                int(match.group(2), 16),
                match.group(3),
                int(match.group(4), 16),
                int(match.group(5), 16),
                int(match.group(6), 16),
                int(match.group(7)),
                match.group(8))
            mappings.append(_map)
    finally:
        if isinstance(mapsfile, file):
            mapsfile.close()
    # reposition the previous ctypes module.
    if True:
        ctypes = types.set_ctypes(before)
    return mappings
Пример #2
0
 def _make_mmap_with_values(self, intervals, struct_offset=None):
     """Make a memory map, with a fake structure of pointer pattern inside.
     Return the pattern signature"""
     # template of a memory map metadata
     self._mstart = 0x0C00000
     self._mlength = 4096  # end at (0x0c01000)
     # could be 8, it doesn't really matter
     self.word_size = self.config.get_word_size()
     if struct_offset is not None:
         self._struct_offset = struct_offset
     else:
         self._struct_offset = self.word_size * 12  # 12, or any other aligned
     mmap, values = self._make_mmap(self._mstart, self._mlength, self._struct_offset, intervals, self.word_size)
     mappings = Mappings([mmap], "test")
     mappings.config = self.config
     mappings._reset_config()
     return mmap, values
Пример #3
0
    def _load_memory_mappings(self):
        """ make the python objects"""
        self.mappings = Mappings(None, self.dumpname)
        for _start, _end, permissions, offset, devices, inode, mmap_pathname in self.metalines:
            start, end = int(_start, 16), int(_end, 16)
            offset = int(offset, 16)
            inode = int(inode)
            # rebuild filename
            mmap_fname = "%s-%s" % (_start, _end)
            # get devices nums
            major_device, minor_device = devices.split(':')
            major_device = int(major_device, 16)
            minor_device = int(minor_device, 16)
            log.debug('Loading %s - %s' % (mmap_fname, mmap_pathname))
            # open the file in the archive
            try:
                mmap_content_file = self._protected_open_file(
                    mmap_fname,
                    mmap_pathname)
            except (IOError, KeyError) as e:
                log.debug('Ignore absent file : %s' % (e))
                mmap = MemoryMapping(start, end, permissions, offset,
                                     major_device, minor_device, inode, pathname=mmap_pathname)
                self.mappings.append(mmap)
                continue
            # except ValueError,e: # explicit non-loading
            #    log.debug('Ignore useless file : %s'%(e))
            #    mmap = MemoryMapping(start, end, permissions, offset,
            #                                                    major_device, minor_device, inode,pathname=mmap_pathname)
            #    self.mappings.append(mmap)
            #    continue
            except LazyLoadingException as e:
                mmap = FilenameBackedMemoryMapping(e._filename, start, end, permissions, offset,
                                                   major_device, minor_device, inode, pathname=mmap_pathname)
                self.mappings.append(mmap)
                continue

            if isinstance(self.archive, zipfile.ZipFile):  # ZipExtFile is lame
                log.warning(
                    'Using a local memory mapping . Zipfile sux. thx ruby.')
                mmap = MemoryMapping(start, end, permissions, offset,
                                     major_device, minor_device, inode, pathname=mmap_pathname)
                mmap = LocalMemoryMapping.fromBytebuffer(
                    mmap,
                    mmap_content_file.read())
            # use file mmap when file is too big
            elif end - start > config.MAX_MAPPING_SIZE_FOR_MMAP:
                log.warning('Using a file backed memory mapping. no mmap in memory for this memorymap (%s).' % (mmap_pathname) +
                            ' Search will fail. Buffer is needed.')
                mmap = FileBackedMemoryMapping(mmap_content_file, start, end, permissions, offset,
                                               major_device, minor_device, inode, pathname=mmap_pathname)
            else:
                log.debug('Using a MemoryDumpMemoryMapping. small size')
                mmap = MemoryDumpMemoryMapping(mmap_content_file, start, end, permissions, offset,
                                               major_device, minor_device, inode, pathname=mmap_pathname)
            self.mappings.append(mmap)
        self.mappings.init_config(cpu=self._cpu_bits, os_name=self._os_name)
        return
Пример #4
0
class ProcessMemoryDumpLoader(MemoryDumpLoader):

    """ Handles memory load from several recognized format."""
    indexFilename = 'mappings'
    filePrefix = './'

    def _is_valid(self):
        """Validates if we handle the format."""
        if os.path.isdir(self.dumpname):
            if self._test_dir():
                self._open_archive = lambda archive: archive
                self._list_names = os.listdir
                self._open_file = lambda archive, name: file(
                    os.path.sep.join([archive, name]), 'rb')
                return True
        else:
            raise IOError('%s is not a directory' % (self.dumpname))
        return False

    def _test_dir(self):
        try:
            self.archive = self.dumpname
            members = os.listdir(self.archive)
            if self.indexFilename not in members:
                log.error('no mappings index file in the directory.')
                return False
            self.filePrefix = ''
            self.mmaps = [m for m in members if '-0x' in m]
            if len(self.mmaps) > 0:
                return True
        except OSError as e:
            log.info('Not a valid directory')
        return False

    def _protected_open_file(self, mmap_fname, mmap_pathname):
        return self._open_file(self.archive, self.filePrefix + mmap_fname)

    def _load_mappings(self):
        """Loads the mappings content from the dump to a MemoryMappings.

        If an underlying file containing a memory dump does not exists, still
        create a MemoryMap for metadata purposes.
        If the memory map is > config.MAX_MAPPING_SIZE_FOR_MMAP, use a slow FileBackedMemoryMapping.
        Else, load the mapping in memory.
        """
        self._load_metadata()
        self._load_memory_mappings()  # set self.mappings
        return

    def _load_metadata(self):
        """ Load    amemory dump meta data """
        mappingsFile = self._open_file(self.archive, self.indexFilename)
        self.metalines = []
        for l in mappingsFile.readlines():
            fields = l.strip().split(' ')
            if '' in fields:
                fields.remove('')
            self.metalines.append(
                (fields[0],
                 fields[1],
                    fields[2],
                    fields[3],
                    fields[4],
                    fields[5],
                    ' '.join(
                    fields[
                        6:])))
        return

    def _load_memory_mappings(self):
        """ make the python objects"""
        self.mappings = Mappings(None, self.dumpname)
        for _start, _end, permissions, offset, devices, inode, mmap_pathname in self.metalines:
            start, end = int(_start, 16), int(_end, 16)
            offset = int(offset, 16)
            inode = int(inode)
            # rebuild filename
            mmap_fname = "%s-%s" % (_start, _end)
            # get devices nums
            major_device, minor_device = devices.split(':')
            major_device = int(major_device, 16)
            minor_device = int(minor_device, 16)
            log.debug('Loading %s - %s' % (mmap_fname, mmap_pathname))
            # open the file in the archive
            try:
                mmap_content_file = self._protected_open_file(
                    mmap_fname,
                    mmap_pathname)
            except (IOError, KeyError) as e:
                log.debug('Ignore absent file : %s' % (e))
                mmap = MemoryMapping(start, end, permissions, offset,
                                     major_device, minor_device, inode, pathname=mmap_pathname)
                self.mappings.append(mmap)
                continue
            # except ValueError,e: # explicit non-loading
            #    log.debug('Ignore useless file : %s'%(e))
            #    mmap = MemoryMapping(start, end, permissions, offset,
            #                                                    major_device, minor_device, inode,pathname=mmap_pathname)
            #    self.mappings.append(mmap)
            #    continue
            except LazyLoadingException as e:
                mmap = FilenameBackedMemoryMapping(e._filename, start, end, permissions, offset,
                                                   major_device, minor_device, inode, pathname=mmap_pathname)
                self.mappings.append(mmap)
                continue

            if isinstance(self.archive, zipfile.ZipFile):  # ZipExtFile is lame
                log.warning(
                    'Using a local memory mapping . Zipfile sux. thx ruby.')
                mmap = MemoryMapping(start, end, permissions, offset,
                                     major_device, minor_device, inode, pathname=mmap_pathname)
                mmap = LocalMemoryMapping.fromBytebuffer(
                    mmap,
                    mmap_content_file.read())
            # use file mmap when file is too big
            elif end - start > config.MAX_MAPPING_SIZE_FOR_MMAP:
                log.warning('Using a file backed memory mapping. no mmap in memory for this memorymap (%s).' % (mmap_pathname) +
                            ' Search will fail. Buffer is needed.')
                mmap = FileBackedMemoryMapping(mmap_content_file, start, end, permissions, offset,
                                               major_device, minor_device, inode, pathname=mmap_pathname)
            else:
                log.debug('Using a MemoryDumpMemoryMapping. small size')
                mmap = MemoryDumpMemoryMapping(mmap_content_file, start, end, permissions, offset,
                                               major_device, minor_device, inode, pathname=mmap_pathname)
            self.mappings.append(mmap)
        self.mappings.init_config(cpu=self._cpu_bits, os_name=self._os_name)
        return