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}