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