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
78 pub fn get_exports(&self) -> Vec<(String, usize)>
79 {
80 let mut funcs: Vec<(String, usize)> = Vec::new();
81
82 let mut dos_header_buf: [u8; mem::size_of::<IMAGE_DOS_HEADER>()] = [0; mem::size_of::<IMAGE_DOS_HEADER>()];
83 self.read_memory_abs(self.base_address, &mut dos_header_buf);
84 let dos_header: IMAGE_DOS_HEADER = unsafe{ std::ptr::read(dos_header_buf.as_ptr() as *const _) };
85
86 let export_table_address = if self.process_data.borrow().is_64_bit
87 {
88 let mut nt_headers_buf: [u8; mem::size_of::<IMAGE_NT_HEADERS64>()] = [0; mem::size_of::<IMAGE_NT_HEADERS64>()];
89 self.read_memory_abs(self.base_address + dos_header.e_lfanew as usize, &mut nt_headers_buf);
90 let nt_headers: IMAGE_NT_HEADERS64 = unsafe{ std::ptr::read(nt_headers_buf.as_ptr() as *const _)};
91 nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress
92 }
93 else
94 {
95 let mut nt_headers_buf: [u8; mem::size_of::<IMAGE_NT_HEADERS32>()] = [0; mem::size_of::<IMAGE_NT_HEADERS32>()];
96 self.read_memory_abs(self.base_address + dos_header.e_lfanew as usize, &mut nt_headers_buf);
97 let nt_headers: IMAGE_NT_HEADERS32 =unsafe{ std::ptr::read(nt_headers_buf.as_ptr() as *const _)};
98 nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress
99 };
100
101 if export_table_address == 0
102 {
103 return funcs;
104 }
105
106 let mut export_table_buf: [u8; mem::size_of::<IMAGE_EXPORT_DIRECTORY>()] = [0; mem::size_of::<IMAGE_EXPORT_DIRECTORY>()];
107 self.read_memory_abs(self.base_address + export_table_address as usize, &mut export_table_buf);
108 let export_table: IMAGE_EXPORT_DIRECTORY = unsafe{ std::ptr::read(export_table_buf.as_ptr() as *const _) };
109
110 let name_offset_table = self.base_address + export_table.AddressOfNames as usize;
111 let ordinal_table = self.base_address + export_table.AddressOfNameOrdinals as usize;
112 let function_offset_table = self.base_address + export_table.AddressOfFunctions as usize;
113
114 for i in 0..export_table.NumberOfNames {
115 let mut func_name_offset_buf: [u8; mem::size_of::<u32>()] = [0; mem::size_of::<u32>()];
116 self.read_memory_abs(
117 name_offset_table + i as usize * mem::size_of::<u32>(),
118 &mut func_name_offset_buf,
119 );
120 let func_name_offset: u32 = unsafe{ std::ptr::read(func_name_offset_buf.as_ptr() as *const _)};
121
122 let func_name = read_ascii_string_generic(self, self.base_address + func_name_offset as usize);
123
124 let mut ordinal_index_buf: [u8; mem::size_of::<u16>()] = [0; mem::size_of::<u16>()];
125 self.read_memory_abs(
126 ordinal_table + i as usize * mem::size_of::<u16>(),
127 &mut ordinal_index_buf,
128 );
129 let ordinal_index: u16 = unsafe{ std::ptr::read(ordinal_index_buf.as_ptr() as *const _)};
130
131 let mut func_offset_buf: [u8; mem::size_of::<usize>()] = [0; mem::size_of::<usize>()];
132 self.read_memory_abs(
133 function_offset_table + ordinal_index as usize * mem::size_of::<u32>(),
134 &mut func_offset_buf,
135 );
136 let func_offset: u32 = unsafe{ std::ptr::read(func_offset_buf.as_ptr() as *const _)};
137
138 let func_addr: usize = self.base_address + func_offset as usize;
139
140 funcs.push((func_name, func_addr));
141 }
142 return funcs;
143 }
144}
145
146fn read_ascii_string_generic<T: ReadWrite>(read_write: &T, address: usize) -> String
147{
148 let mut offset: usize = 0;
149 let end_byte: u8 = 0x0;
150
151 let mut output_string: String = String::from("");
152
153 loop {
154 let mut single_char_buf: [u8; 1] = [0];
155 read_write.read_memory_abs(address + offset as usize, &mut single_char_buf);
156 let single_char: u8 = unsafe{ std::ptr::read(single_char_buf.as_ptr() as *const _) };
157
158 if single_char == end_byte {
159 break;
160 }
161
162 output_string.push(single_char as char);
163
164 offset += 1;
165
166 if offset > 512 {
167 panic!("String too long!");
168 }
169 }
170
171 return output_string;
172}