(
process_id: HANDLE,
dll_stats: *const DllStats,
)
| 612 | type InjectedApcArgs = PVOID; |
| 613 | |
| 614 | pub unsafe fn map_shellcode_into_process( |
| 615 | process_id: HANDLE, |
| 616 | dll_stats: *const DllStats, |
| 617 | ) -> Result<(InjectedApcCallback, InjectedApcArgs), Error> { |
| 618 | let process_reference = ProcessReference::attach(process_id)?; |
| 619 | let load_library = get_module_symbol_address("ntdll.dll", "LdrLoadDll"); |
| 620 | |
| 621 | let mut user_apc_args = UserApcArgs { |
| 622 | dll_path: UNICODE_STRING { |
| 623 | Length: 0, |
| 624 | MaximumLength: 0, |
| 625 | Buffer: null_mut(), |
| 626 | }, |
| 627 | buffer: [0; 256], |
| 628 | retval: null_mut(), |
| 629 | load_library: unsafe { transmute::<*mut c_void, LdrLoadDll>(load_library.unwrap()) }, |
| 630 | }; |
| 631 | |
| 632 | //make the contents of dll_path.Buffer be contained on a field on the same struct, avoiding references to kernel memory |
| 633 | let path: Vec<WCHAR> = "agent.dll".encode_utf16().collect(); |
| 634 | let len = path.len().min(255); |
| 635 | user_apc_args.buffer[..len].copy_from_slice(&path[..len]); |
| 636 | |
| 637 | user_apc_args.dll_path.Length = (len * 2) as u16; |
| 638 | user_apc_args.dll_path.MaximumLength = user_apc_args.dll_path.Length + 2; // + null-terminator |
| 639 | user_apc_args.dll_path.Buffer = user_apc_args.buffer.as_mut_ptr(); |
| 640 | |
| 641 | // Allocate and copy the user apc args to target process |
| 642 | |
| 643 | let mut injected_apc_args = null_mut(); |
| 644 | let mut injected_apc_args_size = size_of::<UserApcArgs>() as SIZE_T; |
| 645 | |
| 646 | unsafe { |
| 647 | if !nt_success!(ZwAllocateVirtualMemory( |
| 648 | NtCurrentProcess(), |
| 649 | &mut injected_apc_args, |
| 650 | 0, |
| 651 | &mut injected_apc_args_size, |
| 652 | MEM_COMMIT, |
| 653 | PAGE_READWRITE, |
| 654 | )) { |
| 655 | return Err(Error::UNSUCCESSFUL); |
| 656 | }; |
| 657 | RtlCopyMemoryNonTemporal( |
| 658 | injected_apc_args, |
| 659 | &user_apc_args as *const _ as _, |
| 660 | size_of::<UserApcArgs>() as SIZE_T, |
| 661 | ) |
| 662 | } |
| 663 | //Still need to update the dll_path.Buffer field, as it points to kernel memory |
| 664 | |
| 665 | // Calculate the new buffer address in user space, which is the address of `injected_apc_args` plus the offset of `buffer` |
| 666 | let new_buffer_address = injected_apc_args as usize + 32; // `buffer` starts at offset 32 |
| 667 | |
| 668 | // Access the UNICODE_STRING within the copied struct to adjust the `Buffer` pointer |
| 669 | let args = &mut *((injected_apc_args as usize) as *mut UserApcArgs); |
| 670 | args.dll_path.Buffer = new_buffer_address as *mut _; |
| 671 |
no test coverage detected