use anyhow::{Context as _, Error};
use isr::cache::IsrCache;
use tracing_subscriber::EnvFilter;
use vmi::{
VcpuId, VmiCore, VmiSession, arch::amd64::Amd64, driver::xen::VmiXenDriver,
os::windows::WindowsOs,
};
pub fn create_vmi_session() -> Result<VmiSession<'static, WindowsOs<VmiXenDriver<Amd64>>>, Error> {
let filter = EnvFilter::default()
.add_directive(tracing::Level::DEBUG.into())
.add_directive("reqwest=warn".parse()?)
.add_directive("rustls=warn".parse()?);
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_target(false)
.init();
let driver = VmiXenDriver::<Amd64>::try_from_env()?
.context("invalid VMI_XEN_DOMAIN environment variable")?;
let core = VmiCore::new(driver)?;
let kernel_info = {
let _pause_guard = core.pause_guard()?;
let registers = core.registers(VcpuId(0))?;
WindowsOs::find_kernel(&core, ®isters)?.context("cannot find kernel information")?
};
tracing::info!(codeview = ?kernel_info.codeview, "loading kernel profile");
let isr = IsrCache::new("cache")?;
let entry = isr.entry_from_codeview(kernel_info.codeview)?;
let entry = Box::leak(Box::new(entry));
let profile = entry.profile()?;
tracing::info!("creating VMI session");
let os = WindowsOs::<VmiXenDriver<Amd64>>::new(&profile)?;
let core = Box::leak(Box::new(core));
let os = Box::leak(Box::new(os));
Ok(VmiSession::new(core, os))
}