def gdb_memory_rw_debug(thread_id, thread_list, addr, length, buf, is_write): ''' Read / Write memory ''' thread = None # First, check if we can read the register from the CPU object for element in thread_list: if element['id'] == thread_id: thread = element break if thread is None: return None if is_write: from api import w_va w_va(thread['pgd'], addr, buf, length) return buf else: try: from api import r_va import binascii mem = r_va(thread['pgd'], addr, length) return mem except Exception as e: raise e
def __write_arg_strings_array(self, pgd, vaddr, array): """ Write a space separated list of argument over a single char array. """ array_ptr = vaddr for el in array: api.w_va(pgd, array_ptr, el + " ", len(el) + 1) array_ptr += (len(el) + 1) # Terminating null character api.w_va(pgd, array_ptr, "\x00", 1)
def __write_env_strings_array(self, pgd, vaddr, array): """ Write a block of null terminated strings, followed by a null character. Env variable format for CreateProcess. """ array_ptr = vaddr for el in array: api.w_va(pgd, array_ptr, el + "\x00", len(el) + 1) array_ptr += (len(el) + 1) # Terminating null character api.w_va(pgd, array_ptr, "\x00", 1)
def __handle_host_read(self, cpu_index, cpu): """ Handle the host_read interface call. Argument in EAX: The file descriptor. Argument in EBX: Pointer to the buffer (VA) where bytes should be read into. Argument in ECX: Size of the buffer. Returns number of bytes read in EAX, or -1 if the call failed. """ if isinstance(cpu, X86CPU): fd = cpu.EAX buf = cpu.EBX size = cpu.ECX elif isinstance(cpu, X64CPU): fd = cpu.RAX buf = cpu.RBX size = cpu.RCX # self.__printer("GuestAgentPlugin: host_read(%d, 0x%08x, %d) called" % # (fd, buf, size)) if fd not in self.__file_descriptors: self.__printer( "HostFilesPlugin: host_read tried to access invalid file descriptor %d" % fd) return pgd = api.get_running_process(cpu_index) try: data = self.__file_descriptors[fd].read(size) # Security check: the buffer should be located on the allowed # boundaries if self.__check_buffer_validity(buf, size): api.w_va(pgd, buf, data, len(data)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", len(data)) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", len(data)) else: self.__printer( "HostFilesPlugin: Declared buffer or buffer size are not" + "within the allowed boundaries %x (%x)" % (buf, size)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1) except Exception as ex: self.__printer( "HostFilesPlugin: Exception %s while trying to read from file descriptor %d" % (str(ex), fd)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1)
def __handle_host_read(self, cpu_index, cpu): """ Handle the host_read interface call. Argument in EAX: The file descriptor. Argument in EBX: Pointer to the buffer (VA) where bytes should be read into. Argument in ECX: Size of the buffer. Returns number of bytes read in EAX, or -1 if the call failed. """ if isinstance(cpu, X86CPU): fd = cpu.EAX buf = cpu.EBX size = cpu.ECX elif isinstance(cpu, X64CPU): fd = cpu.RAX buf = cpu.RBX size = cpu.RCX # self.__printer("GuestAgentPlugin: host_read(%d, 0x%08x, %d) called" % # (fd, buf, size)) if fd not in self.__file_descriptors: self.__printer( "HostFilesPlugin: host_read tried to access invalid file descriptor %d" % fd) return pgd = api.get_running_process(cpu_index) try: data = self.__file_descriptors[fd].read(size) # Security check: the buffer should be located on the allowed # boundaries if self.__check_buffer_validity(buf, size): api.w_va(pgd, buf, data, len(data)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", len(data)) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", len(data)) else: self.__printer("HostFilesPlugin: Declared buffer or buffer size are not" + "within the allowed boundaries %x (%x)" % (buf, size)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1) except Exception as ex: self.__printer( "HostFilesPlugin: Exception %s while trying to read from file descriptor %d" % (str(ex), fd)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1)
def __handle_host_request_exec_path(self, cpu_index, cpu): """ Handle the host_request_exec_path interface call. Argument in EAX: the buffer to write to Argument in EBX: the max size of the buffer to write to Returns number of bytes written in EAX, or -1 if the call failed. """ if isinstance(cpu, X86CPU): buf = cpu.EAX size = cpu.EBX elif isinstance(cpu, X64CPU): buf = cpu.RAX size = cpu.RBX # self.__printer("GuestAgentPlugin: host_request_exec_path(0x%08x, %d) # called" % (buf, size)) pgd = api.get_running_process(cpu_index) try: # Security check: the buffer should be located on the allowed # boundaries if self.__check_buffer_validity(buf, size): api.w_va(pgd, buf, self.__file_to_execute["path"] + "\x00", len(self.__file_to_execute["path"]) + 1) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", len(self.__file_to_execute["path"]) + 1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", len(self.__file_to_execute["path"]) + 1) else: self.__printer( "HostFilesPlugin: Declared buffer or buffer size are not" + "within the allowed boundaries %x (%x)" % (buf, size)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1) except Exception as ex: self.__printer( "HostFilesPlugin: Exception %s while trying to write file path to guest" % (str(ex))) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1)
def __handle_host_request_exec_path(self, cpu_index, cpu): """ Handle the host_request_exec_path interface call. Argument in EAX: the buffer to write to Argument in EBX: the max size of the buffer to write to Returns number of bytes written in EAX, or -1 if the call failed. """ if isinstance(cpu, X86CPU): buf = cpu.EAX size = cpu.EBX elif isinstance(cpu, X64CPU): buf = cpu.RAX size = cpu.RBX # self.__printer("GuestAgentPlugin: host_request_exec_path(0x%08x, %d) # called" % (buf, size)) pgd = api.get_running_process(cpu_index) try: # Security check: the buffer should be located on the allowed # boundaries if self.__check_buffer_validity(buf, size): api.w_va(pgd, buf, self.__file_to_execute[ "path"] + "\x00", len(self.__file_to_execute["path"]) + 1) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", len( self.__file_to_execute["path"]) + 1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", len( self.__file_to_execute["path"]) + 1) else: self.__printer("HostFilesPlugin: Declared buffer or buffer size are not" + "within the allowed boundaries %x (%x)" % (buf, size)) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1) except Exception as ex: self.__printer( "HostFilesPlugin: Exception %s while trying to write file path to guest" % (str(ex))) if isinstance(cpu, X86CPU): api.w_r(cpu_index, "EAX", -1) elif isinstance(cpu, X64CPU): api.w_r(cpu_index, "RAX", -1)
def __write_strings_array(self, pgd, vaddr, array): """ Write a char* arg[] array. """ TARGET_LONG_SIZE = api.get_os_bits() / 8 array_ptr = vaddr strings_ptr = vaddr + TARGET_LONG_SIZE * (len(array) + 1) for i, s in enumerate(array): api.w_va(pgd, array_ptr, struct.pack( "<" + ("L" if TARGET_LONG_SIZE == 4 else "Q"), strings_ptr), TARGET_LONG_SIZE) api.w_va(pgd, strings_ptr, s + "\x00", len(s) + 1) array_ptr += TARGET_LONG_SIZE strings_ptr += len(s) + 1 api.w_va(pgd, array_ptr, "\x00" * TARGET_LONG_SIZE, TARGET_LONG_SIZE)
def set_memory_virtual(pgd, addr, buf): import api api.w_va(pgd, addr, buf)