mem_rs/process/
process_modules.rs

1// This file is part of the mem-rs distribution (https://github.com/FrankvdStam/mem-rs).
2// Copyright (c) 2022 Frank van der Stam.
3// https://github.com/FrankvdStam/mem-rs/blob/main/LICENSE
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, version 3.
8//
9// This program is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17use std::cell::RefCell;
18use std::ffi::c_void;
19use std::mem::size_of;
20use std::rc::Rc;
21use windows::Win32::Foundation::{HANDLE, HINSTANCE, HMODULE, MAX_PATH};
22use windows::Win32::System::ProcessStatus::{K32EnumProcessModules, K32GetModuleFileNameExW, K32GetModuleInformation, MODULEINFO};
23use crate::helpers::{get_file_name_from_string, w32str_to_string};
24use crate::process::Process;
25use crate::process_data::ProcessData;
26use crate::process_module::ProcessModule;
27
28impl Process
29{
30    pub fn get_process_modules(handle: HANDLE, process_data: &Rc<RefCell<ProcessData>>) -> Vec<ProcessModule>
31    {
32        unsafe
33        {
34            let mut result = Vec::new();
35
36            //Get amount of hmodules in current process
37            let mut required_size: u32 = 0;
38            let _ = K32EnumProcessModules(handle, 0 as *mut HMODULE, 0, &mut required_size);
39            let size = (required_size / size_of::<HINSTANCE>() as u32) as u32;
40
41            //Get modules
42            let mut modules: Vec<HMODULE> = vec![HMODULE::default(); size as usize];
43            let _ = K32EnumProcessModules(handle, modules.as_mut_ptr(), required_size.clone(), &mut required_size).unwrap();
44
45            for i in 0..modules.len()
46            {
47                let mut mod_name = [0; MAX_PATH as usize];
48
49                if K32GetModuleFileNameExW(Some(handle), Some(modules[i as usize]), &mut mod_name) != 0
50                {
51                    let file_path = w32str_to_string(&mod_name.to_vec());
52                    let file_name = get_file_name_from_string(&file_path);
53
54                    let mut info: MODULEINFO = MODULEINFO
55                    {
56                        lpBaseOfDll: 0 as *mut c_void,
57                        SizeOfImage: 0,
58                        EntryPoint: 0 as *mut c_void,
59                    };
60
61                    if K32GetModuleInformation(handle, modules[i as usize], &mut info, size_of::<MODULEINFO>() as u32).as_bool()
62                    {
63                        let module_base = info.lpBaseOfDll as usize;
64                        let module_size = info.SizeOfImage as usize;
65                        result.push(ProcessModule::new(process_data.clone(), modules[i as usize].0 as usize, file_path, file_name, module_base, module_size));
66                    }
67                }
68            }
69            return result;
70        }
71    }
72}