mem_rs/process_module/
mod.rs1mod read_write;
18
19use std::cell::RefCell;
20use std::mem;
21use std::rc::Rc;
22use windows::Win32::System::Diagnostics::Debug::{IMAGE_NT_HEADERS32, IMAGE_NT_HEADERS64};
23use windows::Win32::System::SystemServices::{IMAGE_DOS_HEADER, IMAGE_EXPORT_DIRECTORY};
24use crate::memory::{BaseReadWrite, ReadWrite};
25use crate::process_data::ProcessData;
26
27#[allow(dead_code)]
28#[derive(Clone)]
29pub struct ProcessModule
30{
31 process_data: Rc<RefCell<ProcessData>>,
32
33 pub id: usize,
34 pub path: String,
35 pub name: String,
36
37 pub base_address: usize,
38 pub size: usize,
39
40 pub memory: Vec<u8>,
41}
42
43impl Default for ProcessModule
44{
45 fn default() -> Self
46 {
47 ProcessModule
48 {
49 process_data: Rc::new(RefCell::new(ProcessData::default())),
50 id: 0,
51 path: String::new(),
52 name: String::new(),
53 base_address: 0,
54 size: 0,
55 memory: Vec::new(),
56 }
57 }
58}
59
60impl ProcessModule
61{
62 pub fn new(process_data: Rc<RefCell<ProcessData>>, id: usize, path: String, name: String, base: usize, size: usize) -> Self
63 {
64 ProcessModule { process_data, id, path, name, base_address: base, size, memory: Vec::new() }
65 }
66
67 pub fn dump_memory(&mut self)
68 {
69 let mut buffer: Vec<u8> = vec![0; self.size];
70 if !self.read_memory_abs(self.base_address, &mut buffer)
71 {
72 return;
73 }
74 self.memory = buffer;
75 }
76
77 pub fn get_exports(&self) -> Vec<(String, usize)>
78 {
79 let mut funcs: Vec<(String, usize)> = Vec::new();
80
81 let mut dos_header_buf: [u8; mem::size_of::<IMAGE_DOS_HEADER>()] = [0; mem::size_of::<IMAGE_DOS_HEADER>()];
82 self.read_memory_abs(self.base_address, &mut dos_header_buf);
83 let dos_header: IMAGE_DOS_HEADER = unsafe{ std::ptr::read(dos_header_buf.as_ptr() as *const _) };
84
85 let export_table_address = if self.process_data.borrow().is_64_bit
86 {
87 let mut nt_headers_buf: [u8; mem::size_of::<IMAGE_NT_HEADERS64>()] = [0; mem::size_of::<IMAGE_NT_HEADERS64>()];
88 self.read_memory_abs(self.base_address + dos_header.e_lfanew as usize, &mut nt_headers_buf);
89 let nt_headers: IMAGE_NT_HEADERS64 = unsafe{ std::ptr::read(nt_headers_buf.as_ptr() as *const _)};
90 nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress
91 }
92 else
93 {
94 let mut nt_headers_buf: [u8; mem::size_of::<IMAGE_NT_HEADERS32>()] = [0; mem::size_of::<IMAGE_NT_HEADERS32>()];
95 self.read_memory_abs(self.base_address + dos_header.e_lfanew as usize, &mut nt_headers_buf);
96 let nt_headers: IMAGE_NT_HEADERS32 =unsafe{ std::ptr::read(nt_headers_buf.as_ptr() as *const _)};
97 nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress
98 };
99
100 if export_table_address == 0
101 {
102 return funcs;
103 }
104
105 let mut export_table_buf: [u8; mem::size_of::<IMAGE_EXPORT_DIRECTORY>()] = [0; mem::size_of::<IMAGE_EXPORT_DIRECTORY>()];
106 self.read_memory_abs(self.base_address + export_table_address as usize, &mut export_table_buf);
107 let export_table: IMAGE_EXPORT_DIRECTORY = unsafe{ std::ptr::read(export_table_buf.as_ptr() as *const _) };
108
109 let name_offset_table = self.base_address + export_table.AddressOfNames as usize;
110 let ordinal_table = self.base_address + export_table.AddressOfNameOrdinals as usize;
111 let function_offset_table = self.base_address + export_table.AddressOfFunctions as usize;
112
113 for i in 0..export_table.NumberOfNames {
114 let mut func_name_offset_buf: [u8; mem::size_of::<u32>()] = [0; mem::size_of::<u32>()];
115 self.read_memory_abs(
116 name_offset_table + i as usize * mem::size_of::<u32>(),
117 &mut func_name_offset_buf,
118 );
119 let func_name_offset: u32 = unsafe{ std::ptr::read(func_name_offset_buf.as_ptr() as *const _)};
120
121 let func_name = read_ascii_string_generic(self, self.base_address + func_name_offset as usize);
122
123 let mut ordinal_index_buf: [u8; mem::size_of::<u16>()] = [0; mem::size_of::<u16>()];
124 self.read_memory_abs(
125 ordinal_table + i as usize * mem::size_of::<u16>(),
126 &mut ordinal_index_buf,
127 );
128 let ordinal_index: u16 = unsafe{ std::ptr::read(ordinal_index_buf.as_ptr() as *const _)};
129
130 let mut func_offset_buf: [u8; mem::size_of::<usize>()] = [0; mem::size_of::<usize>()];
131 self.read_memory_abs(
132 function_offset_table + ordinal_index as usize * mem::size_of::<u32>(),
133 &mut func_offset_buf,
134 );
135 let func_offset: u32 = unsafe{ std::ptr::read(func_offset_buf.as_ptr() as *const _)};
136
137 let func_addr: usize = self.base_address + func_offset as usize;
138
139 funcs.push((func_name, func_addr));
140 }
141 return funcs;
142 }
143}
144
145fn read_ascii_string_generic<T: ReadWrite>(read_write: &T, address: usize) -> String
146{
147 let mut offset: usize = 0;
148 let end_byte: u8 = 0x0;
149
150 let mut output_string: String = String::from("");
151
152 loop {
153 let mut single_char_buf: [u8; 1] = [0];
154 read_write.read_memory_abs(address + offset as usize, &mut single_char_buf);
155 let single_char: u8 = unsafe{ std::ptr::read(single_char_buf.as_ptr() as *const _) };
156
157 if single_char == end_byte {
158 break;
159 }
160
161 output_string.push(single_char as char);
162
163 offset += 1;
164
165 if offset > 512 {
166 panic!("String too long!");
167 }
168 }
169
170 return output_string;
171}