c - 将匿名 PIPE HANDLE 传递给子进程

标签 c windows

我想将匿名管道句柄传递给子进程。 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/

相关文章:

windows - 从Windows命令行使用foma/flookup

c - 在 c 中安全分配包含各种数组的结构

c - Sublime Text 3 在 OS X 上使用传递的参数编译并运行(在终端中)C

c - 并行化 vector 时的负加速 vector 点积

windows - 如何关闭从 visual studio 中打开的 "orphaned"控制台窗口?

windows - 用于服务发现的 Docker DNS 按名称解析 Windows 容器地址的工作效果不一致

c - 指向从代码复制的函数的指针

sql 包不执行 printf

windows - Vim:\n 与\r

windows - 对于 Windows,一个命令行 bat 文件,显示目录中每个文件的总行数