basic_process_list/basic-process-list.rs
1//! This example demonstrates how to enumerate the running processes of a
2//! Windows guest running inside a Xen domain.
3
4use anyhow::{Context as _, Error};
5use isr::cache::IsrCache;
6use vmi::{
7 VcpuId, VmiCore, VmiSession,
8 arch::amd64::Amd64,
9 driver::xen::VmiXenDriver,
10 os::{VmiOsProcess as _, windows::WindowsOs},
11};
12
13fn main() -> Result<(), Error> {
14 // Setup VMI.
15 let driver = VmiXenDriver::<Amd64>::try_from_env()?
16 .context("invalid VMI_XEN_DOMAIN environment variable")?;
17 let core = VmiCore::new(driver)?;
18
19 // Try to find the kernel information.
20 // This is necessary in order to load the profile.
21 let kernel_info = {
22 // Pause the VM to get consistent state.
23 let _pause_guard = core.pause_guard()?;
24
25 // Get the register state for the first vCPU.
26 let registers = core.registers(VcpuId(0))?;
27
28 // On AMD64 architecture, the kernel is usually found using the
29 // `MSR_LSTAR` register, which contains the address of the system call
30 // handler. This register is set by the operating system during boot
31 // and is left unchanged (unless some rootkits are involved).
32 //
33 // Therefore, we can take an arbitrary registers at any point in time
34 // (as long as the OS has booted and the page tables are set up) and
35 // use them to find the kernel.
36 WindowsOs::find_kernel(&core, ®isters)?.expect("kernel information")
37 };
38
39 // Load the profile.
40 // The profile contains offsets to kernel functions and data structures.
41 let isr = IsrCache::new("cache")?;
42 let entry = isr.entry_from_codeview(kernel_info.codeview)?;
43 let profile = entry.profile()?;
44
45 // Create the VMI session.
46 tracing::info!("Creating VMI session");
47 let os = WindowsOs::<VmiXenDriver<Amd64>>::new(&profile)?;
48 let session = VmiSession::new(&core, &os);
49
50 // Pause the VM again to get consistent state.
51 let paused = session.pause_guard()?;
52
53 // Create a new `VmiState` with the boot CPU registers.
54 let vmi = paused.state();
55
56 // Get the list of processes and print them.
57 for process in vmi.os().processes()? {
58 let process = process?;
59
60 println!(
61 "{} [{}] {} (root @ {})",
62 process.object()?,
63 process.id()?,
64 process.name()?,
65 process.translation_root()?
66 );
67 }
68
69 Ok(())
70}