RISC-V模糊仿真

发布于 2025-01-24 14:57:26 字数 72 浏览 4 评论 0原文

我是新手,但我需要使用QEMU模拟RISC-V。作为我的模糊项目的开始,我该如何为Qemu提供指令集并获得注册表中的更改作为输出。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人│生佛魔见 2025-01-31 14:57:26

我可能理解你的问题。因为我在这里没有与RISCV相关的环境,所以我只能提供解决方案。
例如,在RISCV中,我们设计一个函数以获取所有寄存器的值,依赖于QEMU的插件模块(例如qemu_plugin_register_vcpu_insn_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);
}

应注意,Api-ext.c中的内容是从其他人那里获得的。这是用于获得ARM CPU值的功能。您需要检查RISCV的源代码或文档。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文