memflow/os/
module.rs

1//! Describes modules
2
3use crate::prelude::v1::*;
4
5/// Module information structure
6#[repr(C)]
7#[derive(Clone, Debug)]
8#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
9#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
10pub struct ModuleInfo {
11    /// Returns the address of the module header.
12    ///
13    /// # Remarks
14    ///
15    /// On Windows this will be the address where the [`PEB`](https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb) entry is stored.
16    pub address: Address,
17    /// The base address of the parent process.
18    ///
19    /// # Remarks
20    ///
21    /// This field is analog to the `ProcessInfo::address` field.
22    pub parent_process: Address,
23    /// The actual base address of this module.
24    ///
25    /// # Remarks
26    ///
27    /// The base address is contained in the virtual address range of the process
28    /// this module belongs to.
29    pub base: Address,
30    /// Size of the module
31    pub size: umem,
32    /// Name of the module
33    pub name: ReprCString,
34    /// Path of the module
35    pub path: ReprCString,
36    /// Architecture of the module
37    ///
38    /// # Remarks
39    ///
40    /// Emulated processes often have 2 separate lists of modules, one visible to the emulated
41    /// context (e.g. all 32-bit modules in a WoW64 process), and the other for all native modules
42    /// needed to support the process emulation. This should be equal to either
43    /// `ProcessInfo::proc_arch`, or `ProcessInfo::sys_arch` of the parent process.
44    pub arch: ArchitectureIdent,
45}
46
47pub type ModuleInfoCallback<'a> = OpaqueCallback<'a, ModuleInfo>;
48
49/// Pair of address and architecture used for callbacks
50#[repr(C)]
51#[derive(Clone, Debug)]
52#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
53#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
54pub struct ModuleAddressInfo {
55    pub address: Address,
56    pub arch: ArchitectureIdent,
57}
58
59pub type ModuleAddressCallback<'a> = OpaqueCallback<'a, ModuleAddressInfo>;
60
61/// Import information structure
62#[repr(C)]
63#[derive(Clone, Debug)]
64#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
65#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
66pub struct ImportInfo {
67    /// Name of the import
68    pub name: ReprCString,
69    /// Offset of this import from the containing modules base address
70    pub offset: umem,
71}
72
73pub type ImportCallback<'a> = OpaqueCallback<'a, ImportInfo>;
74
75/// Export information structure
76#[repr(C)]
77#[derive(Clone, Debug)]
78#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
79#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
80pub struct ExportInfo {
81    /// Name of the export
82    pub name: ReprCString,
83    /// Offset of this export from the containing modules base address
84    pub offset: umem,
85}
86
87pub type ExportCallback<'a> = OpaqueCallback<'a, ExportInfo>;
88
89/// Section information structure
90#[repr(C)]
91#[derive(Clone, Debug)]
92#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
93#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
94pub struct SectionInfo {
95    /// Name of the section
96    pub name: ReprCString,
97    /// Virtual address of this section (essentially module_info.base + virtual_address)
98    pub base: Address,
99    /// Size of this section
100    pub size: umem,
101}
102
103impl SectionInfo {
104    /// Checks whether this section is of given name, ignoring '.' or '__' prefix.
105    pub fn is_section(&self, name: &str) -> bool {
106        let mut n = self.name.as_ref();
107        if let Some(stripped) = n.strip_prefix('.') {
108            n = stripped;
109        } else if let Some(stripped) = n.strip_prefix("__") {
110            n = stripped;
111        } else {
112            return false;
113        }
114        n == name
115    }
116
117    /// Checks whether given section is 'text', ignoring prefix.
118    pub fn is_text(&self) -> bool {
119        self.is_section("text")
120    }
121}
122
123pub type SectionCallback<'a> = OpaqueCallback<'a, SectionInfo>;