memory_rs/internal/
process_info.rs

1use crate::error::{Error, ErrorType};
2use crate::internal::memory_region::*;
3use crate::wrap_winapi;
4use anyhow::Result;
5use windows_sys::Win32::Foundation::HINSTANCE;
6use windows_sys::Win32::System::LibraryLoader::GetModuleHandleW;
7use windows_sys::Win32::System::ProcessStatus::{K32GetModuleInformation, MODULEINFO};
8use windows_sys::Win32::System::Threading::GetCurrentProcess;
9
10/// Struct that contains some very basic information of a executable or DLL.
11#[derive(Debug)]
12pub struct ProcessInfo {
13    pub handle: HINSTANCE,
14    pub region: MemoryRegion,
15}
16
17impl ProcessInfo {
18    /// Create the ProcessInfo. This function can fail in case where
19    /// the `GetModuleInformation` fails.
20    pub fn new(name: Option<&str>) -> Result<ProcessInfo> {
21        let module = match name {
22            Some(n) => {
23                let mut name_ = n.to_string();
24                name_.push('\0');
25                let name_wide: Vec<u16> = name_.encode_utf16().collect();
26                unsafe { wrap_winapi!(GetModuleHandleW(name_wide.as_ptr()), x == 0)? }
27            }
28            None => unsafe { wrap_winapi!(GetModuleHandleW(std::ptr::null()), x == 0)? },
29        };
30
31        let module_addr = module as usize;
32
33        let module_size: usize;
34        unsafe {
35            let process = GetCurrentProcess();
36            let mut module_info: MODULEINFO = std::mem::zeroed();
37            wrap_winapi!(
38                K32GetModuleInformation(
39                    process,
40                    module,
41                    &mut module_info,
42                    std::mem::size_of::<MODULEINFO>() as u32,
43                ),
44                x == 0
45            )?;
46
47            module_size = module_info.SizeOfImage as usize;
48        }
49
50        if module_addr == 0x0 {
51            return Err(
52                Error::new(ErrorType::Internal, "Base address can't be 0".to_string()).into(),
53            );
54        }
55
56        if module_size == 0x0 {
57            return Err(Error::new(
58                ErrorType::Internal,
59                "Size of the module can't be 0".to_string(),
60            )
61            .into());
62        }
63
64        let region = MemoryRegion::new(module_addr, module_size, true)?;
65
66        Ok(ProcessInfo {
67            handle: module,
68            region,
69        })
70    }
71}