f.omari
f.omari

Reputation: 19

RISC-V fuzzing emulation

I am new to this but I need to emulate RISC-V using qemu. As a start for my fuzzing project, how can I do give qemu an instruction set and get the changes in the registries as an output.

Upvotes: 0

Views: 228

Answers (1)

clove682
clove682

Reputation: 94

I probably understand your question. Because I don't have a riscv-related environment here, I can only provide a solution. For example, in riscv, we design a function to get the values of all registers, relying on qemu's plugin module (such as qemu_plugin_register_vcpu_insn_exec_cb()).

plugin_test.c

#include <inttypes.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <glib.h>

#include <qemu-plugin.h>

QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;

#define CPU_SIZE 32
static int cpu_num;
static int cpu_value[CPU_SIZE]={0};

static void vcpu_insn_exec_before(unsigned int cpu_index, void *)
{
    for (size_t i = 0; i < cpu_num; i++)
    {
        /* code */
        for (size_t j = 0; j < CPU_SIZE; i++)
        {
            
            if(cpu_value[j] != get_cpu_register(i,j)) {
                // The value of cpu has changed
                ...
            } else {
                // The value of cpu has not changed
                ...
            }
        }
        
    }
}

static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
{
    size_t n = qemu_plugin_tb_n_insns(tb);
    size_t i;

    for (i = 0; i < n; i++) {
        struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
        qemu_plugin_register_vcpu_insn_exec_cb(
                insn, vcpu_insn_exec_before, QEMU_PLUGIN_CB_NO_REGS,void *);
    }
}

static void plugin_exit(qemu_plugin_id_t id, void *p)
{
}

QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
                                           const qemu_info_t *info,
                                           int argc, char **argv)
{
    if(info->system_emulation) {
        cpu_num = info->system.smp_vcpus;
    } else {
        cpu_num = 1;
    }
    
    qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
    qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
    return 0;
}

api-ext.c

void *qemu_get_cpu(int index);

static uint32_t get_cpu_register(unsigned int cpu_index, unsigned int reg) {
    uint8_t* cpu = qemu_get_cpu(cpu_index);
    return *(uint32_t*)(cpu + 33488 + 5424 + reg * 4);
}

It should be noted that the content in api-ext.c is obtained from others. This is the function used to obtain the value of arm cpu. You need to check the source code or documentation for riscv.

Upvotes: 1

Related Questions