Reputation: 1663
I am wanting to pass an anonymous Pipe HANDLE to a Child Process. This answer seems to explain it well for C++, however I am wanting to do this in C.
Do I convert the handle into an integer? Or do I pass the memory address of the HANDLE to the child process, and then make another HANDLE pointing to that?
For example:
Parent:
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]);
Upvotes: 1
Views: 2057
Reputation: 33804
yes, this is ok pass HANDLE
by value. in practice currently your code will be work ok. however need remember that HANDLE
is 64-bit size on 64-bit system - so not fit in int
which is 32-bit size (now user mode handle values in practice fit to 32bit). so need use say %I64x
format to encode handle value and _atoi64
or _wcstoi64
to decode.
for example in parent:
WCHAR child_cmd[32];
swprintf(child_cmd, L"<%I64x>", (ULONG64)(ULONG_PTR)hWrite);
and in child:
HANDLE hWrite = 0;
if (PWSTR sz = wcschr(GetCommandLineW(), '<'))
{
hWrite = (HANDLE)(ULONG_PTR)_wcstoi64(sz + 1, &sz, 16);
if (*sz != '>')
{
hWrite = 0;
}
}
as separate note - use CreatePipe
not the best choice - this api very bad design, say one handle only for write, another only for read, can not select asynchronous I/O, can not make one handle inherit and another not (as need in this case) - better use CreateNamedPipeW
+ CreateFileW
for create pipe pair. or this way if you want no name on pipe (work from win7)
Upvotes: 1