vminer 0.1.0

Virtual Machine Introspection library
Documentation
#[cfg(any(feature = "linux", feature = "windows"))]
mod pointer;

#[cfg(any(feature = "linux", feature = "windows"))]
macro_rules! pointer_defs {
    ( $( $core_ty:path = $ptr:ty; )* ) => {
        trait ToPointer<T> {
            fn to_pointer<Os, Ctx>(self, os: &Os, ctx: Ctx) -> Pointer<T, Os, Ctx>;
        }

        $(
            impl ToPointer<$ptr> for $core_ty {
                #[inline]
                fn to_pointer<Os, Ctx>(self, os: &Os, ctx: Ctx) -> Pointer<$ptr, Os, Ctx> {
                    Pointer::new(self.0, os, ctx)
                }
            }

            impl<Os, Ctx> From<Pointer<'_, $ptr, Os, Ctx>> for $core_ty {
                #[inline]
                fn from(ptr: Pointer<$ptr, Os, Ctx>) -> $core_ty {
                    $core_ty(ptr.addr)
                }
            }
        )*
    };
}

#[cfg(feature = "linux")]
pub mod linux;
#[cfg(feature = "linux")]
pub use linux::Linux;

#[cfg(feature = "windows")]
pub mod windows;
#[cfg(feature = "windows")]
pub use windows::Windows;

use alloc::{boxed::Box, string::String};
use core::fmt;
use vmc::VmResult;

pub trait Buildable<B: vmc::Backend>: Sized {
    fn quick_check(_backend: &B) -> Option<OsBuilder> {
        None
    }

    fn build(backend: B, builder: OsBuilder) -> VmResult<Self>;
}

#[derive(Debug, Default)]
pub struct OsBuilder {
    pub symbols: Option<vmc::SymbolsIndexer>,
    pub kpgd: Option<vmc::PhysicalAddress>,
    pub kaslr: Option<vmc::VirtualAddress>,
    pub version: Option<String>,
    pub loader: Option<Box<dyn SymbolLoader + Send + Sync>>,
}

impl OsBuilder {
    #[inline]
    pub fn new() -> Self {
        Self::default()
    }

    #[inline]
    pub fn with_symbols(mut self, symbols: vmc::SymbolsIndexer) -> Self {
        self.symbols = Some(symbols);
        self
    }

    #[inline]
    pub fn with_kpgd(mut self, kpgd: vmc::PhysicalAddress) -> Self {
        self.kpgd = Some(kpgd);
        self
    }

    #[inline]
    pub fn with_kaslr(mut self, kaslr: vmc::VirtualAddress) -> Self {
        self.kaslr = Some(kaslr);
        self
    }

    #[inline]
    pub fn with_version(mut self, version: String) -> Self {
        self.version = Some(version);
        self
    }

    #[inline]
    pub fn build<B: vmc::Backend, Os: Buildable<B>>(self, backend: B) -> VmResult<Os> {
        Os::build(backend, self)
    }
}

#[inline]
pub fn os_builder() -> OsBuilder {
    OsBuilder::new()
}

pub trait SymbolLoader {
    fn load(&self, name: &str, id: &str) -> VmResult<Option<vmc::ModuleSymbols>>;
}

pub struct EmptyLoader;

impl SymbolLoader for EmptyLoader {
    fn load(&self, _name: &str, _id: &str) -> VmResult<Option<vmc::ModuleSymbols>> {
        Ok(None)
    }
}

impl fmt::Debug for dyn SymbolLoader + Send + Sync + '_ {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("SymbolLoader").finish_non_exhaustive()
    }
}