[英]How to give a program's Handle to a process it created?
我有两个程序, Parent
和Kid
我希望孩子在父母使用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.