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