Пример #1
0
 def _find_free_space(self,
                      size,
                      min_addr=0,
                      max_addr=MAX_UINT64,
                      alignment=0x10000):
     """
     Finds a region of memory that is free, larger than 'size' arg,
     and aligned.
     """
     sections = list(self.memory_info.values())
     for i in range(0, len(sections)):
         addr = util.align(sections[i].address + sections[i].size,
                           alignment=alignment)
         # Enable allocating memory in the middle of a gap when the
         # min requested address falls in the middle of a gap
         if addr < min_addr:
             addr = min_addr
         # Cap the gap's max address by accounting for the next
         # section's start address, requested max address, and the
         # max possible address
         max_gap_addr = (self.max_addr if i == len(sections) -
                         1 else sections[i + 1].address)
         max_gap_addr = min(max_gap_addr, max_addr)
         # Ensure the end address is less than the max and the start
         # address is free
         if addr + size < max_gap_addr and self._is_free(addr):
             return addr
     raise OutOfMemoryException()
Пример #2
0
    def map_file_anywhere(
        self,
        filename: str,
        offset: int = 0,
        size: int = 0,
        preferred_address: int = None,
        min_addr: int = 0x1000,
        max_addr: int = 0xFFFFFFFFFFFFFFFF,
        alignment: int = 0x1000,
        top_down: bool = False,
        prot: int = ProtType.RWX,
        shared: bool = False,
    ) -> int:
        """
        Maps a region of memory with requested size, within the
        addresses specified. The size and start address will respect the
        alignment.

        Args:
            filename: Name of the file to memory map
            offset: Page-aligned offset of file to start mapping
            size: # of bytes to map. This will be rounded up to the
                nearest page.
            preferred_address: If the specified address is available,
                it will be used for the mapping.
            min_addr: The lowest address that could be mapped.
            max_addr: The highest address that could be mapped.
            alignment: Ensures the size and start address are multiples
                of this. Must be a multiple of 0x1000. Default 0x1000.
            top_down: If True, the region will be mapped to the
                highest available address instead of the lowest.
            prot: RWX permissions of the mapped region. Defaults to
                granting all permissions.
            shared: if True, region is shared with subprocesses.
        Returns:
            Start address of mapped region.
        """
        if size == 0:
            with open(filename, "rb") as f:
                size = os.fstat(f.fileno()).st_size
        size = util.align(size)
        address = self.find_free_space(
            size,
            preferred_address=preferred_address,
            min_addr=min_addr,
            max_addr=max_addr,
            alignment=alignment,
            top_down=top_down,
        )
        if address is None:
            raise OutOfMemoryException()
        self.map_file(
            address,
            filename,
            offset=offset,
            size=size,
            prot=prot,
            shared=shared,
        )
        return address
Пример #3
0
 def _split_region(
     self,
     mr: MemoryRegion,
     address: int,
     size: int,
     do_delete: bool = False,
 ):
     chunk_end = address + size
     if (address <= mr.address and chunk_end > mr.end) or size == 0:
         return
     if address > mr.end or chunk_end <= mr.address:
         raise OutOfMemoryException()
     self._mem_unmap_region(mr)
     if address < mr.address:
         address = mr.address
     if chunk_end > mr.end + 1:
         chunk_end = mr.end + 1
     l_size = address - mr.address
     m_size = chunk_end - address
     r_size = mr.end + 1 - chunk_end
     if l_size > 0:
         l_mr = copy.copy(mr)
         l_mr.shrink(mr.address, l_size)
         self._mem_map_region(l_mr)
     if m_size > 0 and not do_delete:
         m_mr = copy.copy(mr)
         m_mr.shrink(address, m_size)
         self._mem_map_region(m_mr)
     if r_size > 0:
         r_mr = copy.copy(mr)
         r_mr.shrink(chunk_end, r_size)
         self._mem_map_region(r_mr)
Пример #4
0
    def map_anywhere(
        self,
        size: int,
        preferred_address: int = None,
        name: str = "",
        kind: str = "",
        module_name: str = "",
        min_addr: int = 0x1000,
        max_addr: int = 0xFFFFFFFFFFFFFFFF,
        alignment: int = 0x1000,
        top_down: bool = False,
        prot: int = ProtType.RWX,
        shared: bool = False,
    ) -> int:
        """
        Maps a region of memory with requested size, within the
        addresses specified. The size and start address will respect the
        alignment.

        Args:
            size: # of bytes to map. This will be rounded up to match
                the alignment.
            preferred_address: If the specified address is available,
                it will be used for the mapping.
            name: String used to identify mapped region. Used for
                debugging.
            kind: String used to identify the purpose of the mapped
                region. Used for debugging.
            module_name: String used to identify the module that mapped
                this region.
            min_addr: The lowest address that could be mapped.
            max_addr: The highest address that could be mapped.
            alignment: Ensures the size and start address are multiples
                of this. Must be a multiple of 0x1000. Default 0x1000.
            top_down: If True, the region will be mapped to the
                highest available address instead of the lowest.
            prot: RWX permissions of the mapped region. Defaults to
                granting all permissions.
            shared: if True, region is shared with subprocesses.
        Returns:
            Start address of mapped region.
        """
        address = self.find_free_space(
            size,
            preferred_address=preferred_address,
            min_addr=min_addr,
            max_addr=max_addr,
            alignment=alignment,
            top_down=top_down,
        )
        if address is None:
            raise OutOfMemoryException()
        self.map(
            address,
            util.align(size),
            name=name,
            kind=kind,
            module_name=module_name,
            prot=prot,
            shared=shared,
        )
        return address