def init_os(self, config_mode=VMIConfig.GLOBAL_FILE_ENTRY, config=ffi.NULL): init_error = ffi.new("vmi_init_error_t *") ghash_ref = dict() if config_mode == VMIConfig.STRING: config = config.encode() elif config_mode == VMIConfig.DICT: # need to convert config to a GHashTable g_str_hash_addr = ffi.addressof(lib, "g_str_hash") g_str_equal_addr = ffi.addressof(lib, "g_str_equal") ghash = lib.g_hash_table_new(g_str_hash_addr, g_str_equal_addr) for k, v in list(config.items()): key = k.encode() if isinstance(v, str): value = v.encode() elif isinstance(v, int): value = ffi.new("int*", v) else: raise RuntimeError("Invalid value {} in config".format(v)) lib.g_hash_table_insert(ghash, key, value) # keep a reference to avoid GC ghash_ref[key] = value config = ghash os = lib.vmi_init_os(self.vmi, config_mode.value, config, init_error) return VMIOS(os), init_error[0]
def read(self, ctx, count): buffer = ffi.new("char[]", count) bytes_read = ffi.new("size_t *") status = lib.vmi_read(self.vmi, ctx.to_ffi(), count, buffer, bytes_read) check(status) # transform into Python bytes buffer = ffi.unpack(buffer, bytes_read[0]) return buffer, bytes_read[0]
def read_va(self, vaddr, pid, count): buffer = ffi.new("char[]", count) bytes_read = ffi.new("size_t *") status = lib.vmi_read_va(self.vmi, vaddr, pid, count, buffer, bytes_read) check(status) # transform into Python bytes buffer = ffi.unpack(buffer, bytes_read[0]) return buffer, bytes_read[0]
def read_ksym(self, symbol, count): buffer = ffi.new("char[]", count) bytes_read = ffi.new("size_t *") status = lib.vmi_read_ksym(self.vmi, symbol.encode(), count, buffer, bytes_read) check(status) # transform into Python bytes buffer = ffi.string(buffer, bytes_read[0]) return buffer, bytes_read[0]
def to_ffi(self): ffi_ctx = ffi.new("access_context_t *") ffi_ctx.translate_mechanism = self.tr_mechanism.value if self.tr_mechanism == TranslateMechanism.KERNEL_SYMBOL: ffi_ctx.ksym = ffi.new("char []", self.ksym.encode()) else: ffi_ctx.addr = self.addr ffi_ctx.dtb = self.dtb ffi_ctx.pid = self.pid return ffi_ctx
def read_pa(self, paddr, count, padding=False): buffer = ffi.new("char[]", count) bytes_read = ffi.new("size_t *") status = lib.vmi_read_pa(self.vmi, paddr, count, buffer, bytes_read) # transform into Python bytes buffer = ffi.unpack(buffer, bytes_read[0]) if padding: if VMIStatus(status) == VMIStatus.FAILURE: # pad with zeroes pad_size = count - bytes_read[0] buffer += bytes(pad_size) else: check(status) return buffer, bytes_read[0]
def get_kernel_struct_offset(self, struct_name, member): value = ffi.new("addr_t *") status = lib.vmi_get_kernel_struct_offset(self.vmi, struct_name.encode(), member.encode(), value) check(status) return value[0]
def write(self, ctx, buffer): cffi_buffer = ffi.from_buffer(buffer) bytes_written = ffi.new("size_t *") count = len(buffer) status = lib.vmi_write(self.vmi, ctx.to_ffi(), count, cffi_buffer, bytes_written) check(status) return bytes_written[0]
def write_pa(self, paddr, buffer): cffi_buffer = ffi.from_buffer(buffer) bytes_written = ffi.new("size_t *") count = len(buffer) status = lib.vmi_write_pa(self.vmi, paddr, count, cffi_buffer, bytes_written) check(status) return bytes_written[0]
def get_access_mode(self, domain, init_flags, init_data): if not init_flags & INIT_DOMAINNAME and not init_flags & INIT_DOMAINID: raise RuntimeError( "init_flags must be either INIT_DOMAINAME or INIT_DOMAINID") domain = domain.encode() cffi_mode = ffi.new("vmi_mode_t *") status = lib.vmi_get_access_mode(self.vmi, domain, init_flags, init_data, cffi_mode) check(status) return VMIMode(cffi_mode[0])
def write_addr_pa(self, paddr, value): cffi_value = ffi.new("addr_t *", value) status = lib.vmi_write_addr_pa(self.vmi, paddr, cffi_value) check(status)
def write_addr_va(self, vaddr, pid, value): cffi_value = ffi.new("addr_t *", value) status = lib.vmi_write_addr_va(self.vmi, vaddr, pid, cffi_value) check(status)
def write_addr_ksym(self, symbol, value): cffi_value = ffi.new("addr_t *", value) status = lib.vmi_write_addr_ksym(self.vmi, symbol.encode(), cffi_value) check(status)
def read_64(self, ctx): value = ffi.new("uint64_t *") status = lib.vmi_read_64(self.vmi, ctx.to_ffi(), value) check(status) return value[0]
def slat_get_domain_state(self): state = ffi.new("bool *") status = lib.vmi_slat_get_domain_state(self.vmi, state) check(status) return bool(state[0])
def get_vcpu_reg(self, reg, vcpu): value = ffi.new("uint64_t *") status = lib.vmi_get_vcpureg(self.vmi, value, reg, vcpu) check(status) return value[0]
def dtb_to_pid(self, dtb): pid = ffi.new("vmi_pid_t *") status = lib.vmi_dtb_to_pid(self.vmi, dtb, pid) check(status) return pid[0]
def read_addr_va(self, vaddr, pid): value = ffi.new("addr_t *") status = lib.vmi_read_addr_va(self.vmi, vaddr, pid, value) check(status) return value[0]
def read_addr_pa(self, paddr): value = ffi.new("addr_t *") status = lib.vmi_read_addr_pa(self.vmi, paddr, value) check(status) return value[0]
def read_addr_ksym(self, symbol): value = ffi.new("addr_t *") status = lib.vmi_read_addr_ksym(self.vmi, symbol.encode(), value) check(status) return value[0]
def pagetable_lookup(self, dtb, vaddr): paddr = ffi.new("addr_t *") status = lib.vmi_pagetable_lookup(self.vmi, dtb, vaddr, paddr) check(status) return paddr[0]
def pagetable_lookup_extended(self, dtb, vaddr): page_info = ffi.new("page_info_t *") status = lib.vmi_pagetable_lookup_extended(self.vmi, dtb, vaddr, page_info) check(status) return page_info
def get_offset(self, offset_name): offset = ffi.new("addr_t *") status = lib.vmi_get_offset(self.vmi, offset_name.encode(), offset) check(status) return offset[0]
def write_64(self, ctx, value): cffi_value = ffi.new("uint64_t *", value) status = lib.vmi_write_64(self.vmi, ctx.to_ffi(), cffi_value) check(status)
def pid_to_dtb(self, pid): dtb = ffi.new('addr_t *') status = lib.vmi_pid_to_dtb(self.vmi, pid, dtb) check(status) return dtb[0]
def write_addr(self, ctx, value): cffi_value = ffi.new("addr_t *", value) status = lib.vmi_write_addr(self.vmi, ctx.to_ffi(), cffi_value) check(status)
def get_vcpuregs(self, vcpu): registers_t = ffi.new("registers_t *") status = lib.vmi_get_vcpuregs(self.vmi, registers_t, vcpu) check(status) return Registers(registers_t)
def __init__(self, regs=None): self.cffi_regs = regs if not self.cffi_regs: self.cffi_regs = ffi.new('registers_t *')
def slat_create(self): slat_id = ffi.new("uint16_t *") status = lib.vmi_slat_create(self.vmi, slat_id) check(status) return slat_id[0]
def read_addr(self, ctx): value = ffi.new("addr_t *") status = lib.vmi_read_addr(self.vmi, ctx.to_ffi(), value) check(status) return value[0]