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 free(&mut self) -> Result<()>;
10 fn is_loaded(&self) -> bool;
11 fn base_address(&self) -> *const u8;
12 fn size(&self) -> usize;
13
14 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
28pub 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;