ntdll/NtDuplicateObject.ps1

function NtDuplicateObject
{
    <#
    .SYNOPSIS
 
    The NtDuplicateObject routine creates a handle that is a duplicate of the specified source handle.
 
    .PARAMETER SourceProcessHandle
 
    A handle to the source process for the handle being duplicated.
 
    .PARAMETER SourceHandle
 
    The handle to duplicate.
 
    .PARAMETER TargetProcessHandle
 
    A handle to the target process that is to receive the new handle. This parameter is optional and can be specified as NULL if the DUPLICATE_CLOSE_SOURCE flag is set in Options.
 
    .PARAMETER DesiredAccess
 
    An ACCESS_MASK value that specifies the desired access for the new handle.
 
    .PARAMETER InheritHandle
 
    .PARAMETER Options
 
    A set of flags to control the behavior of the duplication operation.
 
    .DESCRIPTION
     
    The source handle is evaluated in the context of the specified source process. The calling process must have PROCESS_DUP_HANDLE access to the source process. The duplicate handle is created in the handle table of the specified target process. The calling process must have PROCESS_DUP_HANDLE access to the target process.
     
    By default, the duplicate handle is created with the attributes specified by the HandleAttributes parameter, and with the access rights specified by the DesiredAccess parameter. If necessary, the caller can override one or both defaults by setting the DUPLICATE_SAME_ATTRIBUTES and DUPLICATE_SAME_ACCESS flags in the Options parameter.
     
    If the call to this function occurs in user mode, you should use the name "NtDuplicateObject" instead of "ZwDuplicateObject".
     
    .NOTES
 
    (func ntdll NtDuplicateObject ([UInt32]) @(
        [IntPtr], #_In_ HANDLE hSourceProcessHandle
        [IntPtr], #_In_ HANDLE hSourceHandle
        [IntPtr], #_In_ HANDLE hTargetProcessHandle
        [IntPtr].MakeByRefType(), #_Out_ LPHANDLE lpTargetHandle
        [Int32], #_In_ DWORD dwDesiredAccess
        [Int32], #_In_ BOOL bInheritHandle
        [Int32] #_In_ DWORD dwOptions
    ) -EntryPoint NtDuplicateObject -SetLastError)
 
    .LINK
 
    https://msdn.microsoft.com/en-us/library/windows/hardware/ff566445(v=vs.85).aspx
 
    .EXAMPLE
    #>


    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true)]
        [IntPtr]
        $SourceProcessHandle,

        [Parameter(Mandatory = $true)]
        [IntPtr]
        $SourceHandle,

        [Parameter(Mandatory = $true)]
        [IntPtr]
        $TargetProcessHandle,

        [Parameter()]
        [UInt32]
        $DesiredAccess = 0,

        [Parameter()]
        [bool]
        $InheritHandle = $false,

        [Parameter()]
        [ValidateSet('SAME_ATTRIBUTES','SAME_ACCESS','CLOSE_SOURCE')]
        [string]
        $Options = 'SAME_ATTRIBUTES'
    )

    #[PSReflectFunctions.ntdll]::NtDuplicateObject($hSourceProcess, $hSource, $hTargetProcess, [Ref]$TargetHandle, 0, $false, 2)
    $TargetHandle = [IntPtr]::Zero
    $SUCCESS = $ntdll::NtDuplicateObject($SourceProcessHandle, $SourceHandle, $TargetProcessHandle, [ref]$TargetHandle, 0, $InheritHandle, $DUPLICATE_OPTIONS::$Options)

    if($SUCCESS -ne 0)
    {
        throw "[NtDuplicateObject] Error: $($SUCCESS)"
    }

    Write-Output $TargetHandle
}