英文:
Using Pipes for bidirectional communication(Windows API)
问题
我理解你的问题。你试图编写一个程序,通过使用管道向 cmd.exe
提供输入并通过管道获取输出,但在通过 PARENT_WRITE
提供输入后,无法通过另一个管道 PARENT_READ
获取输出。以下是你的代码的翻译:
#include <stdio.h>
#include <windows.h>
#define BUFFER_LENGTH 1024
void handle_cleanup(STARTUPINFOW, PROCESS_INFORMATION);
DWORD WINAPI ReadPipe(LPVOID);
HANDLE CMD_WRITE, PARENT_READ, CMD_READ, PARENT_WRITE;
int CreateProcessCMD(void){
DWORD ThreadID;
DWORD bytes_written;
HANDLE hProcessCMD;
STARTUPINFOW PSTARTUPINFO;
PROCESS_INFORMATION PPROCESSINFO;
SECURITY_ATTRIBUTES SECURITYATTR;
SECURITYATTR.nLength = sizeof(SECURITY_ATTRIBUTES);
SECURITYATTR.bInheritHandle = TRUE;
SECURITYATTR.lpSecurityDescriptor = NULL;
if(!CreatePipe(&PARENT_READ,&CMD_WRITE, &SECURITYATTR,0)){
printf("无法创建管道");
return EXIT_FAILURE;
}
printf("CreatePipe(PARENT_READ, CMD_WRITE) - 成功!\n");
if(!CreatePipe(&CMD_READ,&PARENT_WRITE, &SECURITYATTR,0)){
printf("无法创建管道");
return EXIT_FAILURE;
}
printf("CreatePipe(CMD_READ, PARENT_WRITE) - 成功!\n");
ZeroMemory(&PSTARTUPINFO, sizeof(STARTUPINFO));
printf("ZeroMemory(&PSTARTUPINFO, sizeof(STARTUPINFO) - 清零 STARTUPINFO 结构成功!\n");
PSTARTUPINFO.cb = sizeof(STARTUPINFO);
PSTARTUPINFO.hStdOutput = CMD_WRITE;
printf("CMD_WRITE ---> %x\n", CMD_WRITE);
printf("STARTINFO.hStdOutput ---> %x\n", PSTARTUPINFO.hStdOutput);
PSTARTUPINFO.hStdInput = CMD_READ;
printf("CMD_READ ---> %x\n", CMD_READ);
printf("STARTINFO.hStdInput ---> %x\n", PSTARTUPINFO.hStdInput);
PSTARTUPINFO.dwFlags |= STARTF_USESTDHANDLES;
PSTARTUPINFO.dwFlags |= STARTF_USESHOWWINDOW;
PSTARTUPINFO.wShowWindow = SW_SHOWNORMAL;
BOOL success = CreateProcessW(L"C:\\Windows\\System32\\cmd.exe",
NULL,
NULL,
NULL,
TRUE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
NULL,
NULL,
&PSTARTUPINFO,
&PPROCESSINFO);
if(!success){
printf("CreateProcessW() --> 无法创建进程!\n");
printf("[-] 关闭程序");
return EXIT_FAILURE;
}
printf("C:\\Windows\\System32\\cmd.exe 启动,PID ---> %i\n", PPROCESSINFO.dwProcessId);
HANDLE hThread = CreateThread(NULL, 0, ReadPipe, NULL, 0, &ThreadID);
if(hThread == NULL){
printf("CreateThread() --> 失败,返回 %i\n", GetLastError());
return EXIT_FAILURE;
}
printf("CreateThread() --> 创建新线程,TID --> %i\n", ThreadID);
Sleep(2000);
while(TRUE){
char cmd[256];
printf("提示> ");
gets(cmd);
WriteFile(PARENT_WRITE, cmd, strlen(cmd), &bytes_written, NULL);
printf("WriteFile() --> 写入 %i 字节\n", bytes_written);
}
hProcessCMD = PPROCESSINFO.hProcess;
switch (WaitForSingleObject(hProcessCMD, INFINITE))
{
case WAIT_ABANDONED :
printf("WaitForSingleObject(hProcess, Timeout) ---> 返回 WAIT_ABANDONED\n");
break;
case WAIT_OBJECT_0:
printf("WaitForSingleObject(hProcess, Timeout) ---> 指定对象的状态已标志 (进程已终止)\n");
break;
case WAIT_TIMEOUT:
printf("WaitForSingleObject(hProcess, Timeout) ---> 返回 WAIT_TIMEOUT\n");
break;
case WAIT_FAILED:
printf("WaitForSingleObject(hProcess, Timeout) ---> 失败,返回 %i\n", GetLastError());
break;
default:
break;
}
handle_cleanup(PSTARTUPINFO, PPROCESSINFO);
return EXIT_SUCCESS;
}
int main(void){
printf("父进程 PID -------> %u\n", GetCurrentProcessId());
if(CreateProcessCMD()){
printf("CreateProcessCMD() - 函数返回 EXIT_FAILURE\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
void handle_cleanup(STARTUPINFOW startupinfo, PROCESS_INFORMATION processinfo ){
if(!CloseHandle(startupinfo.hStdInput)) printf("[-] 无法关闭标准输入句柄\n");
if(!CloseHandle(startupinfo.hStdOutput)) printf("[-] 无法关闭标准输出句柄\n");
if(!CloseHandle(startupinfo.hStdError)) printf("[-] 无法关闭标准错误句柄\n");
if(!CloseHandle(processinfo.hProcess)) printf("[-] 无法关闭进程句柄\n");
if(!CloseHandle(processinfo.hThread)) printf("[-] 无法关闭线程句柄\n");
}
DWORD WINAPI ReadPipe(LPVOID lpThreadParameter){
char buffer[BUFFER_LENGTH];
DWORD bytes_read_from_pipe;
while(TRUE) {
int ret = ReadFile(PARENT_READ, buffer, BUFFER_LENGTH, &bytes_read_from_pipe, NULL);
printf("ReadFile() --> 读取 %i\n", bytes_read_from_pipe);
if(bytes_read_from_pipe>0){
printf("%s\n", buffer);
ZeroMemory(buffer, BUFFER_LENGTH);
bytes_read_from_pipe = 0;
continue;
}
break;
}
}
至于你的输出问题,确保 cmd.exe
的输出通过 PARENT_READ
管道写入。你可以尝试添加更多的调试语句来查看问题所在。希望这有助于解决你的问题。如果你需要更多帮助,请随时提问。
英文:
I am trying to write a program that supplies input to cmd.exe
and retrieve it's output through the use of pipes.(2 Sets of pipes). However after supplying input through PARENT_WRITE
I get no output through the other pipe, PARENT_READ
. Here's the code:
#include <stdio.h>
#include <windows.h>
#define BUFFER_LENGTH 1024
void handle_cleanup(STARTUPINFOW, PROCESS_INFORMATION);
DWORD WINAPI ReadPipe(LPVOID);
HANDLE CMD_WRITE, PARENT_READ, CMD_READ, PARENT_WRITE;
int CreateProcessCMD(void){
DWORD ThreadID;
DWORD bytes_written;
HANDLE hProcessCMD;
STARTUPINFOW PSTARTUPINFO;
PROCESS_INFORMATION PPROCESSINFO;
SECURITY_ATTRIBUTES SECURITYATTR;
SECURITYATTR.nLength = sizeof(SECURITY_ATTRIBUTES);
SECURITYATTR.bInheritHandle = TRUE;
SECURITYATTR.lpSecurityDescriptor = NULL;
if(!CreatePipe(&PARENT_READ,&CMD_WRITE, &SECURITYATTR,0)){
printf("Could not create pipe");
return EXIT_FAILURE;
}
printf("CreatePipe(PARENT_READ, CMD_WRITE) - Success!\n");
if(!CreatePipe(&CMD_READ,&PARENT_WRITE, &SECURITYATTR,0)){
printf("Could not create pipe");
return EXIT_FAILURE;
}
printf("CreatePipe(CMD_READ, PARENT_WRITE) - Success!\n");
ZeroMemory(&PSTARTUPINFO, sizeof(STARTUPINFO));
printf("ZeroMemory(&PSTARTUPINFO, sizeof(STARTUPINFO) - Zeroing STARTUPINFO structure success!\n");
PSTARTUPINFO.cb = sizeof(STARTUPINFO);
PSTARTUPINFO.hStdOutput = CMD_WRITE;
printf("CMD_WRITE ---> %x\n", CMD_WRITE);
printf("STARTINFO.hStsOutput ---> %x\n", PSTARTUPINFO.hStdOutput);
PSTARTUPINFO.hStdInput = CMD_READ;
printf("CMD_READ ---> %x\n", CMD_READ);
printf("STARTINFO.hStdsInput ---> %x\n", PSTARTUPINFO.hStdInput);
PSTARTUPINFO.dwFlags |= STARTF_USESTDHANDLES;
PSTARTUPINFO.dwFlags |= STARTF_USESHOWWINDOW;
PSTARTUPINFO.wShowWindow = SW_SHOWNORMAL;
BOOL success = CreateProcessW(L"C:\\Windows\\System32\\cmd.exe",
NULL,
NULL,
NULL,
TRUE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
NULL,
NULL,
&PSTARTUPINFO,
&PPROCESSINFO);
if(!success){
printf("CreateProcessW() --> Could not create process!\n");
printf("[-] Closing program");
return EXIT_FAILURE;
}
printf("C:\\Windows\\System32\\cmd.exe started with PID ---> %i\n", PPROCESSINFO.dwProcessId);
HANDLE hThread = CreateThread(NULL, 0, ReadPipe, NULL, 0, &ThreadID);
if(hThread == NULL){
printf("CreateThread() --> Failed, Returned %i\n", GetLastError());
return EXIT_FAILURE;
}
printf("CreateThread() --> New thread created with TID --> %i\n", ThreadID);
Sleep(2000);
while(TRUE){
char cmd[256];
printf("Prompt> ");
gets(cmd);
WriteFile(PARENT_WRITE, cmd, strlen(cmd), &bytes_written, NULL);
printf("WriteFile() --> Wrote %i bytes\n", bytes_written);
}
hProcessCMD = PPROCESSINFO.hProcess;
switch (WaitForSingleObject(hProcessCMD, INFINITE))
{
case WAIT_ABANDONED :
printf("WaitForSingleObject(hProcess, Timeout) ---> Returned WAIT_ABANDONED\n");
break;
case WAIT_OBJECT_0:
printf("WaitForSingleObject(hProcess, Timeout) ---> The state of the specified object is signaled (Process has terminated)\n");
break;
case WAIT_TIMEOUT:
printf("WaitForSingleObject(hProcess, Timeout) ---> Returned WAIT_TIMEOUT\n");
break;
case WAIT_FAILED:
printf("WaitForSingleObject(hProcess, Timeout) ---> Failed, Returned &i\n", GetLastError());
break;
default:
break;
}
handle_cleanup(PSTARTUPINFO, PPROCESSINFO);
return EXIT_SUCCESS;
}
int main(void){
printf("Parent PID ------> %u\n", GetCurrentProcessId());
if(CreateProcessCMD()){
printf("CreateProcessCMD() - Function returned EXIT_FAILURE\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
void handle_cleanup(STARTUPINFOW startupinfo, PROCESS_INFORMATION processinfo ){
if(!CloseHandle(startupinfo.hStdInput)) printf("[-] Could not close stdin handle\n");
if(!CloseHandle(startupinfo.hStdOutput)) printf("[-] Could not close stdout handle\n");
if(!CloseHandle(startupinfo.hStdError)) printf("[-] Could not close stderr handle\n");
if(!CloseHandle(processinfo.hProcess)) printf("[-] Could not close process handle\n");
if(!CloseHandle(processinfo.hThread)) printf("[-] Could not close thread handle\n");
}
DWORD WINAPI ReadPipe(LPVOID lpThreadParameter){
char buffer[BUFFER_LENGTH];
DWORD bytes_read_from_pipe;
while(TRUE) {
int ret = ReadFile(PARENT_READ, buffer, BUFFER_LENGTH, &bytes_read_from_pipe, NULL);
printf("ReadFile() --> Read %i\n", bytes_read_from_pipe);
if(bytes_read_from_pipe>0){
printf("%s\n", buffer);
ZeroMemory(buffer, BUFFER_LENGTH);
bytes_read_from_pipe = 0;
continue;
}
break;
}
}
And the output:
Parent PID ------> 12064
CreatePipe(PARENT_READ, CMD_WRITE) - Success!
CreatePipe(CMD_READ, PARENT_WRITE) - Success!
ZeroMemory(&PSTARTUPINFO, sizeof(STARTUPINFO) - Zeroing STARTUPINFO structure success!
CMD_WRITE ---> 100
STARTINFO.hStsOutput ---> 100
CMD_READ ---> 104
STARTINFO.hStdsInput ---> 104
C:\Windows\System32\cmd.exe started with PID ---> 8700
CreateThread() --> New thread created with TID --> 16680
ReadFile() --> Read 43
Microsoft Windows [Version ...]
ReadFile() --> Read 89
(c) Microsoft Corporation. All rights reserved.
C:\Users\<USER>\Sandbox\>
Prompt> where calc.exe
WriteFile() --> Wrote 14 bytes
Prompt>
WriteFile() --> Wrote 0 bytes
I seem to be able to write to it and cannot seem to be able to retrieve any output, ReadFile()
Simple hangs
I am fairly new to the Windows API
答案1
得分: 1
如Hans Passant所说,你忘记了写回车键的按下。
在添加了这个之后:
strcat_s(cmd, "\r\n");
它将正常工作。
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论