首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将程序的句柄赋予它创建的进程?

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

Stack Overflow用户
提问于 2018-09-06 23:58:29
回答 3查看 733关注 0票数 1

我有两个程序,ParentKid

我希望在父级使用CreateProcess创建Kid之后,Kid获得父级的句柄。传递这个句柄的最简单的方法似乎是将句柄放入CreateProcess的命令行参数中,但是我无法在父进程中看到父句柄。GetCurrentProcess返回一个奇怪的非值,如果没有孩子的句柄,DuplicateHandle就无法工作(不可能,因为我需要创建Kid来获得它的句柄,但是CreateProcess也是将父句柄发送给Kid的唯一机会)。

有什么办法可以让Kid轻松地使用Parent's处理吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-07 00:43:57

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

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

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

我看不出父母的手柄在父母里面。

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

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

GetCurrentProcess返回一个奇怪的非值,如果没有孩子的句柄,DuplicateHandle就不能工作

Parent将伪句柄从GetProcessHandle()复制到实际句柄后,它可以在命令行上将该复制传递给Kid。只需确保复制是可继承的,然后在CreateProcess()调用中使用CreateProcess(),或者将一个STARTUPINFOEX传递给包含PROC_THREAD_ATTRIBUTE_HANDLE_LISTCreateProcess() (参见以编程方式控制Win32中的新进程继承哪些句柄)。

不可能,因为我需要创建孩子才能得到它的句柄

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

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

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

票数 3
EN

Stack Overflow用户

发布于 2018-09-07 00:06:58

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

代码语言:javascript
复制
DWORD pid = GetProcessId(Parent);

然后在孩子中,给定pid,把手柄拿回来:

代码语言:javascript
复制
OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);

由于PID是一个数字,所以它很容易被传递。

有关更多细节,请参见以下内容:

票数 1
EN

Stack Overflow用户

发布于 2018-09-07 00:53:41

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

我们需要理解的是,这个父进程可以终止,并且在这个新进程以相同的id开始之后。因此,在我们用InheritedFromUniqueProcessId打开进程之后,我们需要检查这个进程是否真的是父进程,而不是新进程,它是在父进程退出并重用这个id之后创建的。这可以通过查询进程启动时间来完成--很明显,如果这个不是父进程,那么它已经在父进程退出(在这个id不能被重用之前)启动,并且父进程在他启动时就退出了。因此,InheritedFromUniqueProcessId不能仅作为父级,以防它创建时间-- >=孩子创建时间。我们可以使用ProcessTimesNtQueryInformationProcess查询进程创建时间。因此,最终代码可以是:

代码语言:javascript
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52213546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档