maple_rs/
memory_module.rs

1use crate::Result;
2use std::ffi::OsStr;
3
4pub trait MemoryModule {
5    fn get_proc_address(&self, name: &str) -> Result<*const u8>;
6    fn get_proc_address_ordinal(&self, ordinal: u16) -> Result<*const u8>;
7    fn execute_entry_point(&self) -> Result<()>;
8    fn call_dll_entry_point(&self, reason: u32) -> Result<bool>;
9    fn free(&mut self) -> Result<()>;
10    fn is_loaded(&self) -> bool;
11    fn base_address(&self) -> *const u8;
12    fn size(&self) -> usize;
13
14    // Resource management
15    fn find_resource(&self, name: Option<&str>, resource_type: Option<&str>) -> Result<*const u8>;
16    fn find_resource_ex(
17        &self,
18        name: Option<&str>,
19        resource_type: Option<&str>,
20        language: u16,
21    ) -> Result<*const u8>;
22    fn sizeof_resource(&self, resource: *const u8) -> Result<usize>;
23    fn load_resource(&self, resource: *const u8) -> Result<*const u8>;
24    fn load_string(&self, id: u32, buffer: &mut [u16]) -> Result<usize>;
25    fn load_string_ex(&self, id: u32, buffer: &mut [u16], language: u16) -> Result<usize>;
26}
27
28// Function type definitions for custom callbacks
29pub type CustomAllocFunction = fn(
30    size: usize,
31    allocation_type: u32,
32    protect: u32,
33    user_data: *mut std::ffi::c_void,
34) -> *mut u8;
35pub type CustomFreeFunction =
36    fn(ptr: *mut u8, size: usize, free_type: u32, user_data: *mut std::ffi::c_void) -> bool;
37pub type CustomLoadLibraryFunction =
38    fn(filename: &OsStr, user_data: *mut std::ffi::c_void) -> *mut std::ffi::c_void;
39pub type CustomGetProcAddressFunction =
40    fn(module: *mut std::ffi::c_void, name: &str, user_data: *mut std::ffi::c_void) -> *const u8;
41pub type CustomFreeLibraryFunction =
42    fn(module: *mut std::ffi::c_void, user_data: *mut std::ffi::c_void) -> bool;
43
44pub struct MemoryModuleBuilder {
45    pub resolve_imports: bool,
46    pub process_relocations: bool,
47    pub call_dll_main: bool,
48    pub ignore_missing_imports: bool,
49    pub alloc_function: Option<CustomAllocFunction>,
50    pub free_function: Option<CustomFreeFunction>,
51    pub load_library_function: Option<CustomLoadLibraryFunction>,
52    pub get_proc_address_function: Option<CustomGetProcAddressFunction>,
53    pub free_library_function: Option<CustomFreeLibraryFunction>,
54    pub user_data: *mut std::ffi::c_void,
55}
56
57impl Default for MemoryModuleBuilder {
58    fn default() -> Self {
59        Self {
60            resolve_imports: true,
61            process_relocations: true,
62            call_dll_main: true,
63            ignore_missing_imports: false,
64            alloc_function: None,
65            free_function: None,
66            load_library_function: None,
67            get_proc_address_function: None,
68            free_library_function: None,
69            user_data: std::ptr::null_mut(),
70        }
71    }
72}
73
74impl MemoryModuleBuilder {
75    pub fn new() -> Self {
76        Self::default()
77    }
78
79    pub fn resolve_imports(mut self, resolve: bool) -> Self {
80        self.resolve_imports = resolve;
81        self
82    }
83
84    pub fn process_relocations(mut self, process: bool) -> Self {
85        self.process_relocations = process;
86        self
87    }
88
89    pub fn call_dll_main(mut self, call: bool) -> Self {
90        self.call_dll_main = call;
91        self
92    }
93
94    pub fn ignore_missing_imports(mut self, ignore: bool) -> Self {
95        self.ignore_missing_imports = ignore;
96        self
97    }
98
99    pub fn alloc_function(mut self, func: CustomAllocFunction) -> Self {
100        self.alloc_function = Some(func);
101        self
102    }
103
104    pub fn free_function(mut self, func: CustomFreeFunction) -> Self {
105        self.free_function = Some(func);
106        self
107    }
108
109    pub fn load_library_function(mut self, func: CustomLoadLibraryFunction) -> Self {
110        self.load_library_function = Some(func);
111        self
112    }
113
114    pub fn get_proc_address_function(mut self, func: CustomGetProcAddressFunction) -> Self {
115        self.get_proc_address_function = Some(func);
116        self
117    }
118
119    pub fn free_library_function(mut self, func: CustomFreeLibraryFunction) -> Self {
120        self.free_library_function = Some(func);
121        self
122    }
123
124    pub fn user_data(mut self, data: *mut std::ffi::c_void) -> Self {
125        self.user_data = data;
126        self
127    }
128
129    pub fn load_from_memory(self, data: &[u8]) -> Result<Box<dyn MemoryModule>> {
130        #[cfg(windows)]
131        {
132            use crate::windows::WindowsMemoryModule;
133            WindowsMemoryModule::from_memory_with_options(data, &self)
134                .map(|m| Box::new(m) as Box<dyn MemoryModule>)
135        }
136
137        #[cfg(unix)]
138        {
139            use crate::linux::LinuxMemoryModule;
140            LinuxMemoryModule::from_memory_with_options(data, &self)
141                .map(|m| Box::new(m) as Box<dyn MemoryModule>)
142        }
143    }
144}
145
146pub const DLL_PROCESS_ATTACH: u32 = 1;
147pub const DLL_THREAD_ATTACH: u32 = 2;
148pub const DLL_THREAD_DETACH: u32 = 3;
149pub const DLL_PROCESS_DETACH: u32 = 0;