Skip to content

Commit

Permalink
plugins/api Add APIs for memory and register reads
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewFasano committed Dec 16, 2022
1 parent f275250 commit 72c661a
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 2 deletions.
35 changes: 33 additions & 2 deletions include/qemu/qemu-plugin.h
Expand Up @@ -355,8 +355,29 @@ size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb);
uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb);

/**
* qemu_plugin_import_function() - return pointer to a function in another
* plugin
* qemu_plugin_get_pc() - returns current program counter
*
*/
uint64_t qemu_plugin_get_pc(void);

/**
* qemu_plugin_get_reg32() - returns a 32-bit register
* @reg_idx: register index
* @error: set to true if an error occurs
*
*/
int32_t qemu_plugin_get_reg32(unsigned int reg_idx, bool* error);

/**
* qemu_plugin_get_reg64() - returns a 64-bit register
* @reg_idx: register index
* @error: set to true if an error occurs
*
*/
int64_t qemu_plugin_get_reg64(unsigned int reg_idx, bool* error);

/**
* qemu_plugin_import_function() - return pointer to a function in another plugin
* @plugin: plugin name
* @function: function name
*
Expand Down Expand Up @@ -410,6 +431,16 @@ bool qemu_plugin_reg_callback(const char *target_plugin, const char *cb_name,
bool qemu_plugin_unreg_callback(const char *target_plugin, const char *cb_name,
cb_func_t function_pointer);

/**
* qemu_plugin_read_guest_virt_mem() - Read a buffer of guest memory
* @gva: Guest virtual address
* @buf: Buffer to copy guest memory into
* @length: Size of buf
*
* Returns: True if the memory was successfully copied into buf
*/
bool qemu_plugin_read_guest_virt_mem(uint64_t gva, char* buf, size_t length);

/**
* qemu_plugin_tb_get_insn() - retrieve handle for instruction
* @tb: opaque handle to TB passed to callback
Expand Down
71 changes: 71 additions & 0 deletions plugins/api.c
Expand Up @@ -52,6 +52,7 @@
#endif
#endif


/* Uninstall and Reset handlers */

void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
Expand Down Expand Up @@ -205,6 +206,76 @@ qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx)
return insn;
}

/*
* Register information
*
* These queries allow the plugin to retrieve information about each
* the current state of registers in the CPU
*/

uint64_t qemu_plugin_get_pc(void) {
CPUState *cpu = current_cpu;
CPUArchState *env = (CPUArchState *)cpu->env_ptr;
target_ulong pc, cs_base;
uint32_t flags;
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
return (uint64_t)pc;
}

bool qemu_plugin_read_guest_virt_mem(uint64_t gva, char* buf, size_t length) {
#ifdef CONFIG_USER_ONLY
return false;
#else
// Convert virtual address to physical, then read it
CPUState *cpu = current_cpu;
uint64_t page = gva & TARGET_PAGE_MASK;
hwaddr gpa = cpu_get_phys_page_debug(cpu, page);
if (gpa == (hwaddr)-1) {
return false;
}

gpa += (gva & ~TARGET_PAGE_MASK);
cpu_physical_memory_rw(gpa, buf, length, false);
return true;
#endif
}

int32_t qemu_plugin_get_reg32(unsigned int reg_idx, bool* error) {
// Should we directly use gdbsub.c's gdb_read_register?
CPUState *cpu = current_cpu;
CPUClass *cc = CPU_GET_CLASS(cpu);
GByteArray* result = g_byte_array_sized_new(4);

int32_t rv = 0;
int bytes_read = cc->gdb_read_register(cpu, result, reg_idx);
*error = (bytes_read == 0);
if (*error) {
return 0;
}
memcpy(&rv, result->data, sizeof(rv));

g_byte_array_free(result, true);
return rv;
}

int64_t qemu_plugin_get_reg64(unsigned int reg_idx, bool* error) {
// Should we directly use gdbsub.c's gdb_read_register?
CPUState *cpu = current_cpu;
CPUClass *cc = CPU_GET_CLASS(cpu);
GByteArray* result = g_byte_array_sized_new(8);

int64_t rv = 0;
int bytes_read = cc->gdb_read_register(cpu, result, reg_idx);
*error = (bytes_read == 0);
if (*error) {
return 0;
}

memcpy(&rv, result->data, sizeof(rv));
g_byte_array_free(result, true);
return rv;
}

/*
* Instruction information
*
Expand Down
4 changes: 4 additions & 0 deletions plugins/qemu-plugins.symbols
Expand Up @@ -3,6 +3,9 @@
qemu_plugin_end_code;
qemu_plugin_entry_code;
qemu_plugin_get_hwaddr;
qemu_plugin_get_reg32;
qemu_plugin_get_reg64;
qemu_plugin_get_pc;
qemu_plugin_import_function;
qemu_plugin_create_callback;
qemu_plugin_run_callback;
Expand All @@ -25,6 +28,7 @@
qemu_plugin_n_vcpus;
qemu_plugin_outs;
qemu_plugin_path_to_binary;
qemu_plugin_read_guest_virt_mem;
qemu_plugin_register_atexit_cb;
qemu_plugin_register_flush_cb;
qemu_plugin_register_vcpu_exit_cb;
Expand Down

0 comments on commit 72c661a

Please sign in to comment.