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}