将匿名PIPE HANDLE传递给子进程

时间:2018-09-05 05:07:10

标签: c windows

我想将匿名Pipe HANDLE传递给子进程。 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);
    }

孩子:

// Set variables to arguements passed by parent 
HANDLE hWrite = atoi(argv[0]);

1 个答案:

答案 0 :(得分:1)

是的,可以按值传递HANDLE。实际上,当前您的代码可以正常工作。但是请记住,HANDLE在64位系统上为64位大小-因此不适合在32位大小的int中使用(现在,用户模式的句柄值实际上适合于32bit < / em>)。因此需要使用%I64x格式来编码句柄值,并使用_atoi64_wcstoi64来解码。

例如在父母中:

WCHAR child_cmd[32];
swprintf(child_cmd, L"<%I64x>", (ULONG64)(ULONG_PTR)hWrite);

和孩子:

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)