Skip to main content

vmi_core/os/
region.rs

1use super::{VmiOs, VmiOsMapped as _, impl_predicate};
2use crate::{MemoryAccess, Va, VmiDriver, VmiError, VmiVa};
3
4impl_predicate! {
5    /// Predicate used by [`VmiOsProcessExt::find_region`].
6    ///
7    /// [`VmiOsProcessExt::find_region`]: super::VmiOsProcessExt::find_region
8    pub trait RegionPredicate & impl for &str {
9        /// Matches a mapped region whose backing file path equals `self`
10        /// case-insensitively.
11        ///
12        /// Private regions and mapped regions without a backing path
13        /// always return `Ok(false)`. Regions do not carry a name of their
14        /// own, so the backing-file path is the only string identifier a
15        /// `&str` predicate can sensibly compare against.
16        fn matches(&self, region: &Os::Region<'_>) -> Result<bool, VmiError> {
17            match region.kind()?.into_mapped() {
18                Some(mapped) if let Some(path) = mapped.path()?.as_deref() => {
19                    let name = match path.rsplit_once(['\\', '/']) {
20                        Some((_, name)) => name,
21                        None => path,
22                    };
23
24                    Ok(name.eq_ignore_ascii_case(self))
25                }
26                _ => Ok(false),
27            }
28        }
29    }
30
31    #[any]
32    pub struct AnyRegion;
33}
34
35/// A trait for memory regions.
36///
37/// This trait provides an abstraction over memory regions within a guest OS.
38pub trait VmiOsRegion<'a, Driver>: VmiVa + 'a
39where
40    Driver: VmiDriver,
41{
42    /// The VMI OS type.
43    type Os: VmiOs<Driver = Driver, Region<'a> = Self>;
44
45    /// Returns the starting virtual address of the memory region.
46    fn start(&self) -> Result<Va, VmiError>;
47
48    /// Returns the ending virtual address of the memory region.
49    fn end(&self) -> Result<Va, VmiError>;
50
51    /// Returns the memory protection of the memory region.
52    fn protection(&self) -> Result<MemoryAccess, VmiError>;
53
54    /// Returns the memory region's kind.
55    fn kind(&self) -> Result<VmiOsRegionKind<'a, Self::Os>, VmiError>;
56}
57
58/// Specifies the kind of memory region.
59pub enum VmiOsRegionKind<'a, Os>
60where
61    Os: VmiOs + 'a,
62{
63    /// A private region of memory.
64    ///
65    /// Such regions are usually created by functions like `VirtualAlloc` on
66    /// Windows.
67    Private,
68
69    /// A mapped region of memory. Might be backed by a file.
70    ///
71    /// Such regions are usually created by functions like `MapViewOfFile` on
72    /// Windows.
73    MappedData(Os::Mapped<'a>),
74
75    /// A mapped image region of memory. Might be backed by a file.
76    ///
77    /// Such regions are usually created by functions like `MapViewOfFile` on
78    /// Windows.
79    MappedImage(Os::Mapped<'a>),
80}
81
82impl<'a, Os> VmiOsRegionKind<'a, Os>
83where
84    Os: VmiOs,
85{
86    /// Checks if the region is private.
87    pub fn is_private(&self) -> bool {
88        matches!(self, Self::Private)
89    }
90
91    /// Checks if the region is mapped.
92    pub fn is_mapped(&self) -> bool {
93        matches!(self, Self::MappedData(_) | Self::MappedImage(_))
94    }
95
96    /// Returns the mapped region.
97    pub fn mapped(&self) -> Option<&Os::Mapped<'a>> {
98        match self {
99            Self::MappedData(mapped) | Self::MappedImage(mapped) => Some(mapped),
100            _ => None,
101        }
102    }
103
104    /// Returns the mapped region.
105    pub fn into_mapped(self) -> Option<Os::Mapped<'a>> {
106        match self {
107            Self::MappedData(mapped) | Self::MappedImage(mapped) => Some(mapped),
108            _ => None,
109        }
110    }
111}