Exemplo n.º 1
0
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """
    This address space can be used in conjunction with LibVMI
    and the Python bindings for LibVMI.  The end result is that
    you can connect Volatility to view the memory of a running
    virtual machine from any virtualization platform that
    LibVMI supports.

    For this AS to be instantiated, we need the VM name to
    connect to.
    """

    order = 90

    def __init__(self, base, config, layered=False, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        addrspace.BaseAddressSpace.__init__(self, base, config, **kwargs)
        self.as_assert(base is None or layered, 'Must be first Address Space')
        self.as_assert(config.LOCATION.startswith("vmi://"),
                       "Location doesn't start with vmi://")

        domain = config.LOCATION[len("vmi://"):]
        self.vmi = Libvmi(domain, partial=True)
        self.dtb = self.vmi.get_vcpu_reg(CR3, 0)

    def close(self):
        self.vmi.destroy()

    def read(self, addr, length):
        buffer, bytes_read = self.vmi.read_pa(addr, length)
        if bytes_read != length:
            raise RuntimeError('Error while reading physical memory at '
                               '{}'.format(hex(addr)))
        return buffer

    def zread(self, addr, length):
        buffer, bytes_read = self.vmi.read_pa(addr, length)
        if bytes_read != length:
            # fill with zeroes
            buffer += bytes(length - bytes_read).decode()
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return 4096 < addr < self.vmi.get_memsize() - 1

    def get_available_addresses(self):
        yield (0, self.vmi.get_memsize())
Exemplo n.º 2
0
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """An address space which operates on top of Libvmi's interface."""

    __abstract = False
    __name = "vmi"
    order = 90
    __image = True

    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(url, "Filename must be specified in session (e.g. "
                       "session.SetParameter('filename', 'vmi://domain').")
        self.as_assert(url.startswith(URL_PREFIX),
                       "The domain must be passed with the URL prefix {}".format(URL_PREFIX))
        domain = url[len(URL_PREFIX):]
        self.as_assert(domain, "domain name missing after {}".format(URL_PREFIX))

        super(VMIAddressSpace, self).__init__(base=base, session=session, **kwargs)
        self.vmi = Libvmi(domain, partial=True)

    def close(self):
        self.vmi.destroy()

    def read(self, addr, size):
        buffer, bytes_read = self.vmi.read_pa(addr, size)
        if bytes_read != size:
            raise RuntimeError('Error while reading physical memory at {}'.format(hex(addr)))
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return 4096 < addr < self.vmi.get_memsize() - 1

    def get_available_addresses(self):
        yield (4096, self.vmi.get_memsize() - 4096)

    def get_mappings(self, start=0, end=2 ** 64):
        yield addrspace.Run(start=0, end=self.vmi.get_memsize(), file_offset=0, address_space=self)
Exemplo n.º 3
0
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """An address space which operates on top of Libvmi's interface."""

    __abstract = False
    __name = "vmi"
    order = 90
    volatile = True
    __image = True

    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(
            url, "Filename must be specified in session (e.g. "
            "session.SetParameter('filename', 'vmi:///domain').")
        vmi_url = urlparse(url)
        self.as_assert(vmi_url.scheme == SCHEME, "URL scheme must be vmi://")
        self.as_assert(vmi_url.path, "No domain name specified")
        domain = vmi_url.path[1:]
        # hypervisor specified ?
        self.mode = None
        hypervisor = vmi_url.netloc
        if hypervisor:
            self.mode = VMIMode[hypervisor.upper()]
        # query parameters ?
        self.volatile = True
        if vmi_url.query:
            params = parse_qs(vmi_url.query, strict_parsing=True)
            try:
                self.volatile = strtobool((params['volatile'][0]))
            except KeyError:
                raise RuntimeError('Invalid query parameters in vmi:// URI')
        # build Libvmi instance
        super(VMIAddressSpace, self).__init__(base=base,
                                              session=session,
                                              **kwargs)
        self.vmi = Libvmi(domain, mode=self.mode, partial=True)
        self.min_addr = 0
        self.max_addr = self.vmi.get_memsize() - 1
        # pause in case volatile has been disabled
        if not self.volatile:
            self.vmi.pause_vm()
        # register flush hook to destroy vmi instance when session.Flush() is called
        session.register_flush_hook(self, self.close)

    def close(self):
        if not self.volatile:
            self.vmi.resume_vm()
        self.vmi.destroy()

    def read(self, addr, size):
        buffer, _ = self.vmi.read_pa(addr, size, padding=True)
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return self.min_addr <= addr <= self.max_addr

    def get_available_addresses(self):
        yield (self.min_addr, self.max_addr)

    def get_mappings(self, start=0, end=2**64):
        yield addrspace.Run(start=self.min_addr,
                            end=self.max_addr,
                            file_offset=0,
                            address_space=self)
Exemplo n.º 4
0
Arquivo: vmi.py Projeto: google/rekall
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """An address space which operates on top of Libvmi's interface."""

    __abstract = False
    __name = "vmi"
    order = 90
    volatile = True
    __image = True

    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(url, "Filename must be specified in session (e.g. "
                       "session.SetParameter('filename', 'vmi:///domain').")
        vmi_url = urlparse(url)
        self.as_assert(vmi_url.scheme == SCHEME, "URL scheme must be vmi://")
        self.as_assert(vmi_url.path, "No domain name specified")
        domain = vmi_url.path[1:]
        # hypervisor specified ?
        self.mode = None
        hypervisor = vmi_url.netloc
        if hypervisor:
            self.mode = VMIMode[hypervisor.upper()]
        # query parameters ?
        self.volatile = True
        if vmi_url.query:
            params = parse_qs(vmi_url.query, strict_parsing=True)
            try:
                self.volatile = strtobool((params['volatile'][0]))
            except KeyError:
                raise RuntimeError('Invalid query parameters in vmi:// URI')
        # build Libvmi instance
        super(VMIAddressSpace, self).__init__(base=base, session=session,
                                              **kwargs)
        self.vmi = Libvmi(domain, mode=self.mode, partial=True)
        self.min_addr = 0
        self.max_addr = self.vmi.get_memsize() - 1
        # pause in case volatile has been disabled
        if not self.volatile:
            self.vmi.pause_vm()
        # register flush hook to destroy vmi instance when session.Flush() is called
        session.register_flush_hook(self, self.close)

    def close(self):
        if not self.volatile:
            self.vmi.resume_vm()
        self.vmi.destroy()

    def read(self, addr, size):
        buffer, _ = self.vmi.read_pa(addr, size, padding=True)
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return self.min_addr <= addr <= self.max_addr

    def get_available_addresses(self):
        yield (self.min_addr, self.max_addr)

    def get_mappings(self, start=0, end=2 ** 64):
        yield addrspace.Run(start=self.min_addr, end=self.max_addr,
                            file_offset=0, address_space=self)