예제 #1
0
    def dump_memory(self):
        """Dump process memory.
        @return: operation status.
        """
        if not self.pid:
            log.warning("No valid pid specified, memory dump aborted")
            return False

        if not self.is_alive():
            log.warning("The process with pid %d is not alive, memory "
                        "dump aborted", self.pid)
            return False

        self.get_system_info()

        page_size = self.system_info.dwPageSize
        min_addr = self.system_info.lpMinimumApplicationAddress
        max_addr = self.system_info.lpMaximumApplicationAddress
        mem = min_addr

        root = os.path.join(PATHS["memory"], str(int(time.time())))

        if not os.path.exists(root):
            os.makedirs(root)

        # Now upload to host from the StringIO.
        nf = NetlogFile(os.path.join("memory", "%s.dmp" % str(self.pid)))

        process_handle = self.open_process()

        while mem < max_addr:
            mbi = MEMORY_BASIC_INFORMATION()
            count = c_ulong(0)

            if KERNEL32.VirtualQueryEx(process_handle,
                                       mem,
                                       byref(mbi),
                                       sizeof(mbi)) < sizeof(mbi):
                mem += page_size
                continue

            if mbi.State & MEM_COMMIT and \
                    mbi.Type & (MEM_IMAGE | MEM_MAPPED | MEM_PRIVATE):
                buf = create_string_buffer(mbi.RegionSize)
                if KERNEL32.ReadProcessMemory(process_handle,
                                              mem,
                                              buf,
                                              mbi.RegionSize,
                                              byref(count)):
                    nf.sock.sendall(buf.raw)
                mem += mbi.RegionSize
            else:
                mem += page_size

        KERNEL32.CloseHandle(process_handle)
        nf.close()

        log.info("Memory dump of process with pid %d completed", self.pid)
        return True
예제 #2
0
    def dump_memory_block(self, addr, length):
        """Dump process memory.
        @return: operation status.
        """
        if not self.pid:
            log.warning("No valid pid specified, memory dump aborted")
            return False

        if not self.is_alive():
            log.warning(
                "The process with pid %d is not alive, memory "
                "dump aborted", self.pid)
            return False

        self.get_system_info()

        page_size = self.system_info.dwPageSize
        if length < page_size:
            length = page_size

        # Now upload to host from the StringIO.
        idx = self.dumpmem[self.pid] = self.dumpmem.get(self.pid, 0) + 1
        file_name = os.path.join(
            "memory", "block-%s-%s-%s.dmp" % (self.pid, hex(addr), idx))

        process_handle = self.open_process()
        mbi = MEMORY_BASIC_INFORMATION()

        if KERNEL32.VirtualQueryEx(process_handle, addr, byref(mbi),
                                   sizeof(mbi)) == 0:
            log.warning("Couldn't obtain MEM_BASIC_INFO for pid %d address %s",
                        self.pid, hex(addr))
            return False

        # override request with the full mem region attributes
        addr = mbi.BaseAddress
        length = mbi.RegionSize

        count = c_ulong(0)
        try:
            buf = create_string_buffer(length)
            if KERNEL32.ReadProcessMemory(process_handle, addr, buf, length,
                                          byref(count)):
                header = struct.pack("QIIII", addr, length, mbi.State,
                                     mbi.Type, mbi.Protect)
                nf = NetlogFile()
                nf.init(file_name)
                nf.sock.sendall(header)
                nf.sock.sendall(buf.raw)
                nf.close()
            else:
                log.warning(
                    "ReadProcessMemory failed on process_handle %r addr %s length %s",
                    process_handle, hex(addr), hex(length))
        except:
            log.exception(
                "ReadProcessMemory exception on process_handle %r addr %s length %s",
                process_handle, hex(addr), hex(length))

        KERNEL32.CloseHandle(process_handle)

        log.info(
            "Memory block dump of process with pid %d, addr %s, length %s completed",
            self.pid, hex(addr), hex(length))
        return True