MCPcopy Create free account
hub / github.com/carlos-al/user-kernel-syscall-hook / map_shellcode_into_process

Function map_shellcode_into_process

driver/src/injector.rs:614–714  ·  view source on GitHub ↗
(
    process_id: HANDLE,
    dll_stats: *const DllStats,
)

Source from the content-addressed store, hash-verified

612type InjectedApcArgs = PVOID;
613
614pub 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

Callers 1

Calls 1

Tested by

no test coverage detected