vmi_core/core/
memory_access.rs

1use serde::{Deserialize, Serialize};
2
3bitflags::bitflags! {
4    /// Memory access permission flags.
5    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
6    pub struct MemoryAccess: u8 {
7        /// Read permission.
8        const R = 0b00000001;
9
10        /// Write permission.
11        const W = 0b00000010;
12
13        /// Execute permission.
14        const X = 0b00000100;
15
16        /// Combined Read and Write permissions.
17        const RW = Self::R.bits() | Self::W.bits();
18
19        /// Combined Write and Execute permissions.
20        const WX = Self::W.bits() | Self::X.bits();
21
22        /// Combined Read and Execute permissions.
23        const RX = Self::R.bits() | Self::X.bits();
24
25        /// Full access: Read, Write, and Execute permissions.
26        const RWX = Self::R.bits() | Self::W.bits() | Self::X.bits();
27    }
28}
29
30bitflags::bitflags! {
31    /// Options for controlling memory access monitoring.
32    ///
33    /// These options can be used to fine-tune the behavior of memory access
34    /// monitoring, allowing you to ignore certain types of memory accesses
35    /// and improve performance.
36    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
37    pub struct MemoryAccessOptions: u8 {
38        /// Ignore page-walk updates caused by the CPU.
39        ///
40        /// When this flag is set, memory accesses that are solely the result of
41        /// CPU-initiated page-table walks will not trigger an [`EventMemoryAccess`].
42        /// This is useful for filtering out irrelevant events when monitoring
43        /// page-table modifications.
44        ///
45        /// # Notes
46        ///
47        /// This option is only effective when the [`MemoryAccess:W`] is not set.
48        ///
49        /// [`EventMemoryAccess`]: ../vmi_arch_amd64/struct.EventMemoryAccess.html
50        const IGNORE_PAGE_WALK_UPDATES = 0b00000001;
51    }
52}
53
54impl std::fmt::Display for MemoryAccess {
55    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
56        let mut result = [b'-'; 3];
57
58        if self.contains(MemoryAccess::R) {
59            result[0] = b'r';
60        }
61        if self.contains(MemoryAccess::W) {
62            result[1] = b'w';
63        }
64        if self.contains(MemoryAccess::X) {
65            result[2] = b'x';
66        }
67
68        // SAFETY: The `result` array is always valid UTF-8.
69        f.write_str(unsafe { std::str::from_utf8_unchecked(&result) })
70    }
71}