#include #include #include #include #include #include #include #include #include #include FILE *fp; QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; uint32_t is_SWinsn(struct qemu_plugin_insn *insnPtr) { uint32_t insn = *((uint32_t *)qemu_plugin_insn_data(insnPtr)) & 0xFFFFFFFF; if (qemu_plugin_insn_size(insnPtr) == 4) // is a 32 bits insn { if (riscv32_insn_class[0].pattern == (insn & riscv32_insn_class[0].mask)) // is a sw { return 1; } } return 0; } /* Call-back put on the sw insn */ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t meminfo, uint64_t vaddr, void *insnPtr) { char *disas = qemu_plugin_insn_disas(insnPtr); void *haddr = qemu_plugin_insn_haddr(insnPtr); fprintf(fp, "%p, %s\n", haddr, disas); } /* Call-back triggered on translation block */ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) { struct qemu_plugin_insn *insnPtr; size_t n = qemu_plugin_tb_n_insns(tb); for (size_t insnN = 0; insnN < n; insnN++) { insnPtr = qemu_plugin_tb_get_insn(tb, insnN); if (is_SWinsn(insnPtr)) { fprintf(fp, "\ninsn sw detecté\n"); char *disas = qemu_plugin_insn_disas(insnPtr); void *haddr = qemu_plugin_insn_haddr(insnPtr); fprintf(fp, "%p, %s\n\n", haddr, disas); qemu_plugin_register_vcpu_mem_cb(insnPtr, vcpu_mem, QEMU_PLUGIN_CB_RW_REGS, QEMU_PLUGIN_MEM_RW, (void *)insnPtr); } } } // Call-back triggered on termination of the guest program static void plugin_exit(qemu_plugin_id_t id, void *p) { fprintf(fp, "fin plugin\n"); fclose(fp); } QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info, int argc, char **argv) { fp = fopen("log.txt", "w"); qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans); qemu_plugin_register_atexit_cb(id, plugin_exit, NULL); return 0; }