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
use serde::{Deserialize, Serialize};
bitflags::bitflags! {
/// Memory access permission flags.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct MemoryAccess: u8 {
/// Read permission.
const R = 0b00000001;
/// Write permission.
const W = 0b00000010;
/// Execute permission.
const X = 0b00000100;
/// Combined Read and Write permissions.
const RW = Self::R.bits() | Self::W.bits();
/// Combined Write and Execute permissions.
const WX = Self::W.bits() | Self::X.bits();
/// Combined Read and Execute permissions.
const RX = Self::R.bits() | Self::X.bits();
/// Full access: Read, Write, and Execute permissions.
const RWX = Self::R.bits() | Self::W.bits() | Self::X.bits();
}
}
bitflags::bitflags! {
/// Options for controlling memory access monitoring.
///
/// These options can be used to fine-tune the behavior of memory access
/// monitoring, allowing you to ignore certain types of memory accesses
/// and improve performance.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct MemoryAccessOptions: u8 {
/// Ignore page-walk updates caused by the CPU.
///
/// When this flag is set, memory accesses that are solely the result of
/// CPU-initiated page-table walks will not trigger an [`EventMemoryAccess`].
/// This is useful for filtering out irrelevant events when monitoring
/// page-table modifications.
///
/// # Notes
///
/// This option is only effective when the [`MemoryAccess:W`] is not set.
///
/// [`EventMemoryAccess`]: ../vmi_arch_amd64/struct.EventMemoryAccess.html
const IGNORE_PAGE_WALK_UPDATES = 0b00000001;
}
}
impl std::fmt::Display for MemoryAccess {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut result = [b'-'; 3];
if self.contains(MemoryAccess::R) {
result[0] = b'r';
}
if self.contains(MemoryAccess::W) {
result[1] = b'w';
}
if self.contains(MemoryAccess::X) {
result[2] = b'x';
}
// SAFETY: The `result` array is always valid UTF-8.
f.write_str(unsafe { std::str::from_utf8_unchecked(&result) })
}
}