我有两个程序,Parent和Kid
我希望在父级使用CreateProcess创建Kid之后,Kid获得父级的句柄。传递这个句柄的最简单的方法似乎是将句柄放入CreateProcess的命令行参数中,但是我无法在父进程中看到父句柄。GetCurrentProcess返回一个奇怪的非值,如果没有孩子的句柄,DuplicateHandle就无法工作(不可能,因为我需要创建Kid来获得它的句柄,但是CreateProcess也是将父句柄发送给Kid的唯一机会)。
有什么办法可以让Kid轻松地使用Parent's处理吗?
发布于 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_LIST的CreateProcess() (参见以编程方式控制Win32中的新进程继承哪些句柄)。
不可能,因为我需要创建孩子才能得到它的句柄
如果您不想使用可继承的句柄,那么Parent可以在命令行上不传递任何句柄的情况下创建Kid,然后以Kid作为目标进程复制GetCurrentProcess()伪句柄,然后使用您选择的IPC机制将副本发送给运行后的Kid。
但是
CreateProcess也是向孩子发送父句柄的唯一机会
不,这不是唯一的办法。IPC是另一种方式。
发布于 2018-09-07 00:06:58
尝试从它自己的进程句柄获取父PID:
DWORD pid = GetProcessId(Parent);然后在孩子中,给定pid,把手柄拿回来:
OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);由于PID是一个数字,所以它很容易被传递。
有关更多细节,请参见以下内容:
发布于 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不能仅作为父级,以防它创建时间-- >=孩子创建时间。我们可以使用ProcessTimes和NtQueryInformationProcess查询进程创建时间。因此,最终代码可以是:
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;
}https://stackoverflow.com/questions/52213546
复制相似问题