Skip to main content

vmi_os_windows/comps/
name_info.rs

1use vmi_core::{Va, VmiError, VmiState, VmiVa, driver::VmiRead};
2
3use super::WindowsObject;
4use crate::{ArchAdapter, WindowsOs, WindowsOsExt as _, offset};
5
6/// A name information for a Windows object.
7///
8/// This structure stores the name and directory information
9/// associated with a named kernel object.
10///
11/// # Implementation Details
12///
13/// Corresponds to `_OBJECT_HEADER_NAME_INFO`.
14pub struct WindowsObjectHeaderNameInfo<'a, Driver>
15where
16    Driver: VmiRead,
17    Driver::Architecture: ArchAdapter<Driver>,
18{
19    /// The VMI state.
20    vmi: VmiState<'a, WindowsOs<Driver>>,
21
22    /// Address of the `_OBJECT_HEADER_NAME_INFO` structure.
23    va: Va,
24}
25
26impl<Driver> VmiVa for WindowsObjectHeaderNameInfo<'_, Driver>
27where
28    Driver: VmiRead,
29    Driver::Architecture: ArchAdapter<Driver>,
30{
31    fn va(&self) -> Va {
32        self.va
33    }
34}
35
36impl<Driver> std::fmt::Debug for WindowsObjectHeaderNameInfo<'_, Driver>
37where
38    Driver: VmiRead,
39    Driver::Architecture: ArchAdapter<Driver>,
40{
41    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42        let directory = self.directory();
43        let name = self.name();
44
45        f.debug_struct("WindowsObjectHeaderNameInfo")
46            .field("directory", &directory)
47            .field("name", &name)
48            .finish()
49    }
50}
51
52impl<'a, Driver> WindowsObjectHeaderNameInfo<'a, Driver>
53where
54    Driver: VmiRead,
55    Driver::Architecture: ArchAdapter<Driver>,
56{
57    /// Creates a new Windows object header name info.
58    pub fn new(vmi: VmiState<'a, WindowsOs<Driver>>, va: Va) -> Self {
59        Self { vmi, va }
60    }
61
62    /// Returns the directory object associated with the object name.
63    ///
64    /// # Implementation Details
65    ///
66    /// Corresponds to `_OBJECT_HEADER_NAME_INFO.Directory`.
67    pub fn directory(&self) -> Result<Option<WindowsObject<'a, Driver>>, VmiError> {
68        let OBJECT_HEADER_NAME_INFO = offset!(self.vmi, _OBJECT_HEADER_NAME_INFO);
69
70        let directory = self
71            .vmi
72            .read_va_native(self.va + OBJECT_HEADER_NAME_INFO.Directory.offset())?;
73
74        if directory.is_null() {
75            return Ok(None);
76        }
77
78        Ok(Some(WindowsObject::new(self.vmi, directory)))
79    }
80
81    /// Returns the name of the object.
82    ///
83    /// # Implementation Details
84    ///
85    /// Corresponds to `_OBJECT_HEADER_NAME_INFO.Name`.
86    pub fn name(&self) -> Result<String, VmiError> {
87        let OBJECT_HEADER_NAME_INFO = offset!(self.vmi, _OBJECT_HEADER_NAME_INFO);
88
89        self.vmi
90            .os()
91            .read_unicode_string(self.va + OBJECT_HEADER_NAME_INFO.Name.offset())
92    }
93
94    /// Constructs the full path of a named object from its name information.
95    ///
96    /// # Implementation Details
97    pub fn full_path(&self) -> Result<String, VmiError> {
98        let mut path = String::new();
99
100        if let Some(directory) = self.directory()? {
101            if let Some(directory_path) = directory.full_path()? {
102                path.push_str(&directory_path);
103            }
104
105            if directory.va() != self.vmi.os().object_root_directory()?.va() {
106                path.push('\\');
107            }
108        }
109
110        path.push_str(&self.name()?);
111
112        Ok(path)
113    }
114}