vmi_os_linux/comps/
mm_struct.rs

1use vmi_core::{Architecture, Va, VmiDriver, VmiError, VmiState, VmiVa};
2
3use super::{LinuxFile, macros::impl_offsets};
4use crate::{ArchAdapter, LinuxOs, MapleTree};
5
6/// A Linux mm struct.
7///
8/// The `mm_struct` structure is responsible for memory management information
9/// of a process. It is responsible for tracking virtual memory mappings,
10/// memory regions, page tables, and other crucial memory-related data.
11///
12/// # Implementation Details
13///
14/// Corresponds to `mm_struct`.
15pub struct LinuxMmStruct<'a, Driver>
16where
17    Driver: VmiDriver,
18    Driver::Architecture: Architecture + ArchAdapter<Driver>,
19{
20    /// The VMI state.
21    vmi: VmiState<'a, Driver, LinuxOs<Driver>>,
22
23    /// The virtual address of the `mm_struct` structure.
24    va: Va,
25}
26
27impl<Driver> VmiVa for LinuxMmStruct<'_, Driver>
28where
29    Driver: VmiDriver,
30    Driver::Architecture: Architecture + ArchAdapter<Driver>,
31{
32    fn va(&self) -> Va {
33        self.va
34    }
35}
36
37impl<'a, Driver> LinuxMmStruct<'a, Driver>
38where
39    Driver: VmiDriver,
40    Driver::Architecture: Architecture + ArchAdapter<Driver>,
41{
42    impl_offsets!();
43
44    /// Creates a new `mm_struct`.
45    pub fn new(vmi: VmiState<'a, Driver, LinuxOs<Driver>>, va: Va) -> Self {
46        Self { vmi, va }
47    }
48
49    /// Returns the page global directory (PGD) of the process.
50    ///
51    /// # Implementation Details
52    ///
53    /// Corresponds to `mm_struct.pgd`.
54    pub fn pgd(&self) -> Result<u64, VmiError> {
55        let offsets = self.offsets();
56        let __mm_struct = &offsets.mm_struct;
57
58        self.vmi.read_field(self.va, &__mm_struct.pgd)
59    }
60
61    /// Returns the executable file of the process.
62    ///
63    /// # Implementation Details
64    ///
65    /// Corresponds to `mm_struct.exe_file`.
66    pub fn exe_file(&self) -> Result<Option<LinuxFile<'a, Driver>>, VmiError> {
67        let offsets = self.offsets();
68        let __mm_struct = &offsets.mm_struct;
69
70        let exe_file = self
71            .vmi
72            .read_va_native(self.va + __mm_struct.exe_file.offset())?;
73
74        if exe_file.is_null() {
75            return Ok(None);
76        }
77
78        Ok(Some(LinuxFile::new(self.vmi, exe_file)))
79    }
80
81    /// Returns the memory map of the process.
82    ///
83    /// This is a data structure for managing virtual memory areas (VMAs).
84    /// It replaces the older mm->mmap (linked list of VMAs) for faster lookups.
85    ///
86    /// # Implementation Details
87    ///
88    /// Corresponds to `mm_struct.mm_mt`.
89    pub fn mm_mt(&self) -> Result<MapleTree<'a, Driver>, VmiError> {
90        let offsets = self.offsets();
91        let __mm_struct = &offsets.mm_struct;
92
93        Ok(MapleTree::new(
94            self.vmi,
95            self.va + __mm_struct.mm_mt.offset(),
96        ))
97    }
98
99    /// Returns the address of the `mm_mt` field.
100    pub fn mm_mt_va(&self) -> Result<Va, VmiError> {
101        let offsets = self.offsets();
102        let __mm_struct = &offsets.mm_struct;
103        Ok(self.va + __mm_struct.mm_mt.offset())
104    }
105}