maple_rs/
memory_module.rs1use 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 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
29pub 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;