我想将匿名管道句柄传递给子进程。 This答案似乎很好地解释了 C++,但是我想在 C 中这样做。
我是否将句柄转换为整数?或者我将 HANDLE 的内存地址传递给子进程,然后让另一个 HANDLE 指向它?
例如:
家长:
BOOL bCreatePipe, bReadFile;
HANDLE hRead = NULL;
HANDLE hWrite = NULL;
SECURITY_ATTRIBUTES lpPipeAttributes;
lpPipeAttributes.nLength = sizeof(lpPipeAttributes);
lpPipeAttributes.lpSecurityDescriptor = NULL;
lpPipeAttributes.bInheritHandle = TRUE;
// Create pipe file descriptors for parent and child
bCreatePipe = CreatePipe(&hRead, &hWrite, &lpPipeAttributes, (DWORD)BUFFER_SIZE);
if (bCreatePipe == FALSE) {
printf("[-]Error creating IPC pipe : %d", GetLastError());
exit(-1);
}
// Create command line arguments for child process
snprintf(child_cmd, CMD_LINE_SIZE, "%d", &hWrite);
// Create child process to handle request
if ( !CreateProcess(
"C:\\Users\\Child.exe", // No module name (use command line)
child_cmd, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
TRUE, // Set handle inheritance to TRUE (for pipe)
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi) // Pointer to PROCESS_INFORMATION structure
)
{
printf("[-]CreateProcess failed : %d\n", GetLastError());
exit(-1);
}
child :
// Set variables to arguments passed by parent
HANDLE hWrite = atoi(argv[0]);
最佳答案
是的,可以按值传递 HANDLE
。实际上,目前您的代码可以正常工作。但是需要记住 HANDLE
在 64 位系统上是 64 位大小 - 所以不适合 32 位大小的 int
(现在是用户模式句柄值实际上适合 32 位)。所以需要使用 say %I64x
格式来编码句柄值和 _atoi64
或 _wcstoi64
来解码。
例如在父类中:
WCHAR child_cmd[32];
swprintf(child_cmd, L"<%I64x>", (ULONG64)(ULONG_PTR)hWrite);
在 child 身上:
HANDLE hWrite = 0;
if (PWSTR sz = wcschr(GetCommandLineW(), '<'))
{
hWrite = (HANDLE)(ULONG_PTR)_wcstoi64(sz + 1, &sz, 16);
if (*sz != '>')
{
hWrite = 0;
}
}
作为单独的说明 - 使用 CreatePipe
不是最好的选择 - 这个 api 非常糟糕的设计,说一个句柄只写,另一个只读,不能选择异步 I/O,不能使一个句柄继承而另一个不继承(在这种情况下需要)- 最好使用 CreateNamedPipeW
+ CreateFileW
来创建管道对。或 this如果您不想在管道上使用任何名称(从 win7 开始工作)
关于c - 将匿名 PIPE HANDLE 传递给子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52177440/