繁体   English   中英

如何将程序的句柄赋予它创建的进程?

[英]How to give a program's Handle to a process it created?

我有两个程序, ParentKid

我希望孩子在父母使用CreateProcess创建孩子之后得到孩子的父母的权利。 传递此句柄的最简单方法似乎是将Handle放入CreateProcess的命令行参数中,但是我看不到将Parent的Handle放入Parent的方法。 GetCurrentProcess返回一个奇怪的非值,而DuplicateHandle在没有Kid's Handle的情况下不起作用(不可能,因为我需要创建Kid来获得Handle,但是CreateProcess也是将Parent's Handle发送到儿童)。

有什么办法可以让Kid轻松地得到Parent's照顾吗?

传递此句柄的最简单方法似乎是将Handle放入CreateProcess的命令行参数中

这是一种方法,但不是唯一的方法。

另一个简单的方法是让Parent将其进程ID从GetCurrentProcessId()发送给Kid ,然后Kid可以使用OpenProcess()来获取Parent的句柄。

我无法看到将“家长的句柄”放入“家长”中。

GetCurrentProcess() ,它返回表示调用过程的伪句柄。 当在调用进程的上下文中使用时,所有接受进程句柄的API都将接受此伪句柄。

但是,为了将调用进程的句柄传递给另一个进程, Parent必须使用DuplicateHandle()将伪句柄转换为真实的句柄(将Parent设置为源进程和目标进程)。 这是记录的行为。

GetCurrentProcess返回一个奇怪的非值,并且没有孩子的句柄, DuplicateHandle不起作用

Parent将来自GetProcessHandle()的伪句柄复制到真实句柄之后,它可以在命令行上将该副本传递给Kid 只需确保重复项是可继承的,然后在CreateProcess()调用中使用bInheritHandles=TRUE ,或将STARTUPINFOEX传递给包含PROC_THREAD_ATTRIBUTE_HANDLE_LIST CreateProcess() (请参见以编程方式控制Win32中新进程继承的句柄 )。

不可能,因为我需要创建Kid来处理它

如果您不想使用可继承的句柄,那么Parent可以替代地创建Kid而不在命令行上传递任何句柄,然后将GetCurrentProcess()伪句柄复制为Kid作为目标进程,然后使用您选择的IPC机制在副本已运行后将其发送给Kid

但是CreateProcess也是将父级句柄发送给孩子的唯一机会

不,这不是唯一的方法。 IPC是另一种方式。

尝试从自己的进程句柄获取父PID:

DWORD pid = GetProcessId(Parent);

然后在孩子中,给定pid,取回手柄:

OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);

PID是一个数字,因此很容易传递。

有关更多详细信息,请参见以下内容:

首先,我们需要获取Kid中父进程的进程ID。 这可以通过调用带有ProcessBasicInformation NtQueryInformationProcess来完成。 PROCESS_BASIC_INFORMATION内部(此结构在ntddk.h中声明)存在InheritedFromUniqueProcessId成员。 严格地说,如果您在创建Kid时使用PROC_THREAD_ATTRIBUTE_PARENT_PROCESS ,则这不是父进程ID,但是如果在调用CreateProcess - InheritedFromUniqueProcessId时未使用此属性,则它将是您的父进程ID。

我们需要了解的是,父级可以终止,并且在此新进程之后以相同的ID开始。 因此,在使用InheritedFromUniqueProcessId打开进程之后,我们需要检查它是否确实是父进程,而不是在父进程退出并重新使用此ID之后创建的新进程。 这可以通过查询进程的开始时间来完成-显然,如果不是父进程,它是在父退出后(无法重用此ID之前)已经启动的,并且在他启动Kid之后退出了。 因此,只有在创建时间> =孩子创建时间的情况下, InheritedFromUniqueProcessId才能成为父对象。 我们可以使用NtQueryInformationProcess通过ProcessTimes查询流程创建时间。 所以最终的代码可以是:

NTSTATUS OpenParent(PHANDLE phProcess, ULONG DesiredAccess)
{
    HANDLE hProcess;
    KERNEL_USER_TIMES kut, _kut;
    PROCESS_BASIC_INFORMATION pbi;

    NTSTATUS status;

    if (0 <= (status = NtQueryInformationProcess(
        NtCurrentProcess(), ProcessBasicInformation, 
        &pbi, sizeof(pbi), 0)) && 
        0 <= (status = NtQueryInformationProcess(
        NtCurrentProcess(), ProcessTimes, 
        &kut, sizeof(kut), 0)))
    {

        static OBJECT_ATTRIBUTES zoa = { sizeof(zoa) };
        CLIENT_ID cid = { (HANDLE)pbi.InheritedFromUniqueProcessId };
        if (0 <= (status = NtOpenProcess(&hProcess, DesiredAccess|
            PROCESS_QUERY_LIMITED_INFORMATION, &zoa, &cid)))
        {

            if (0 > (status = NtQueryInformationProcess(
                hProcess, ProcessTimes, &_kut, sizeof(_kut), 0)) || 
                kut.CreateTime.QuadPart <= _kut.CreateTime.QuadPart)
            {
                NtClose(hProcess);
                return STATUS_PROCESS_IS_TERMINATING;
            }

            *phProcess = hProcess;
        }
    }

    return status;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM