6个版本

9.0.0-v02024年6月3日
8.2.2-v02024年3月11日
8.2.0-v12024年1月10日
8.1.3-v42024年1月10日
8.1.3-v32023年12月19日

#139模拟器

GPL-2.0-only

205KB
4K SLoC

QEMU-PLUGIN

QEMU插件API的高级Rust风格绑定,包括用于在Rust中构建QEMU插件的工具。

示例

以下是一个打印QEMU中运行的程序执行跟踪的最小插件示例。请注意,我们只是在一个库构造函数中注册了一个实现 Plugin 的结构体,库会处理其余部分。

use anyhow::Result;
use ctor::ctor;
use qemu_plugin::{
    plugin::{HasCallbacks, Plugin, Register, PLUGIN},
    PluginId, TranslationBlock,
};
use std::sync::Mutex;

struct TinyTrace {}

impl Register for TinyTrace {}

impl HasCallbacks for TinyTrace {
    fn on_translation_block_translate(
        &mut self,
        _id: PluginId,
        tb: TranslationBlock,
    ) -> Result<()> {
        tb.instructions().enumerate().try_for_each(|(idx, insn)| {
            if idx == 0 {
                println!("====TB: {:08x}", insn.vaddr());
            }

            println!("{:08x}: {}", insn.vaddr(), insn.disas()?);
            Ok::<(), anyhow::Error>(())
        })?;

        Ok(())
    }
}

impl Plugin for TinyTrace {}

#[ctor]
fn init() {
    PLUGIN
        .set(Mutex::new(Box::new(TinyTrace {})))
        .map_err(|_| anyhow::anyhow!("Failed to set plugin"))
        .expect("Failed to set plugin");
}

上述 src/lib.rs 在具有以下 Cargo.toml 的Cargo项目中将编译为 libtiny.so,该文件可以在运行 qemu-system-ARCH -plugin ./libtiny.so

[package]
name = "tiny"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
qemu-plugin = "9.0.0-v0"
anyhow = "1.0.75"
ffi = "0.1.0"
ctor = "0.2.6"

版本控制

截至QEMU 8.2.4,QEMU插件API有多个版本。这使得一些功能变得很强大,比如注册检查和条件回调。版本控制通过编译时特性在 qemu-plugin 包中实现,因为动态库每次只能与一个版本兼容。要选择一个版本,设置如下

qemu-plugin = { version = "9.0.0-v0", features = ["plugin-api-v2"], default-features = false }

qemu-plugin 包的默认插件版本设置为QEMU中正式发布的最新版本。目前,这是V2,发布于8.2.4和9.0.0。如果您需要不同的版本,您 必须 设置 default-features = false

依赖

~0.4–36MB
~547K SLoC