use vmi_core::{Va, VmiError, VmiState, VmiVa, driver::VmiRead};
use super::WindowsObject;
use crate::{ArchAdapter, WindowsOs, offset};
pub struct WindowsTrapFrame<'a, Driver>
where
Driver: VmiRead,
Driver::Architecture: ArchAdapter<Driver>,
{
vmi: VmiState<'a, WindowsOs<Driver>>,
va: Va,
}
impl<'a, Driver> From<WindowsTrapFrame<'a, Driver>> for WindowsObject<'a, Driver>
where
Driver: VmiRead,
Driver::Architecture: ArchAdapter<Driver>,
{
fn from(value: WindowsTrapFrame<'a, Driver>) -> Self {
Self::new(value.vmi, value.va)
}
}
impl<Driver> VmiVa for WindowsTrapFrame<'_, Driver>
where
Driver: VmiRead,
Driver::Architecture: ArchAdapter<Driver>,
{
fn va(&self) -> Va {
self.va
}
}
impl<'a, Driver> WindowsTrapFrame<'a, Driver>
where
Driver: VmiRead,
Driver::Architecture: ArchAdapter<Driver>,
{
pub fn new(vmi: VmiState<'a, WindowsOs<Driver>>, va: Va) -> Self {
Self { vmi, va }
}
pub fn instruction_pointer(&self) -> Result<Va, VmiError> {
let KTRAP_FRAME = offset!(self.vmi, _KTRAP_FRAME);
self.vmi.read_va_native(self.va + KTRAP_FRAME.Rip.offset())
}
pub fn stack_pointer(&self) -> Result<Va, VmiError> {
let KTRAP_FRAME = offset!(self.vmi, _KTRAP_FRAME);
self.vmi.read_va_native(self.va + KTRAP_FRAME.Rsp.offset())
}
}