管道piep使用ReadFile读取阻塞问题解决

来源:互联网 发布:淘宝专业版和智能版 编辑:程序博客网 时间:2024/06/05 03:01

0x01.CreatePipe

管 道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另 一进程就可以从管道的另一端将其读取出来。匿名管道(Anonymous Pipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。

BOOL WINAPI CreatePipe(  _Out_    PHANDLE               hReadPipe,  _Out_    PHANDLE               hWritePipe,  _In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes,  _In_     DWORD                 nSize);

0x02.CreateProcess

BOOL WINAPI CreateProcess(  _In_opt_    LPCTSTR               lpApplicationName,  _Inout_opt_ LPTSTR                lpCommandLine,  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,  _In_        BOOL                  bInheritHandles,  _In_        DWORD                 dwCreationFlags,  _In_opt_    LPVOID                lpEnvironment,  _In_opt_    LPCTSTR               lpCurrentDirectory,  _In_        LPSTARTUPINFO         lpStartupInfo,  _Out_       LPPROCESS_INFORMATION lpProcessInformation);

0x03.管道piep使用ReadFile读取阻塞问题解决

方法一:创建一个pipe然后是cmd执行的结果输出到pipe里,然后再读取,这里遇到一个问题就是在hInput 这个witepipe写完之后得关闭,使write 结束,这样之后的readfile才可以执行而不被阻塞;

int ReadCmdContextOne(){  STARTUPINFO st ;  PROCESS_INFORMATION pi;  HANDLE hOutPut,hInPut;  SECURITY_ATTRIBUTES sa;  DWORD readByte = 0;  int len = 0;  BOOL hResult ;  char buffer[4096];  sa.nLength = sizeof(SECURITY_ATTRIBUTES);  sa.bInheritHandle =TRUE;  sa.lpSecurityDescriptor = NULL;  if(!CreatePipe(&hOutPut,&hInPut,&sa,0))  {    cout<<"create pipe failed erorr="<<GetLastError()<<endl;    return 1;  }  st.cb = sizeof(STARTUPINFO);  GetStartupInfo(&st);  st.hStdOutput = hInPut;  st.hStdError = hInPut;  st.wShowWindow = SW_HIDE;  st.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;  if(!CreateProcess(NULL,"c:\\windows\\system32\\cmd.exe /c ipconfig /all",NULL,  NULL,TRUE,NULL,NULL,NULL,&st,&pi))  {    cout<<"failed create proccess,error="<<GetLastError()<<endl;    return 1;  }  DWORD dwRet = WaitForSingleObject(pi.hProcess,INFINITE);  switch(dwRet)  {    case WAIT_TIMEOUT:    case WAIT_FAILED:      return 1;    case WAIT_OBJECT_0:    CloseHandle(hInPut);//close hInPut handle ,make hte write pipe completes    CloseHandle(pi.hProcess);    CloseHandle(pi.hThread);  }  memset(buffer,0,sizeof(buffer));  do  {      //a write operation completes on the write end of the pipe,so ReadFile can begin    hResult = ReadFile(hOutPut,buffer+len,1024,&readByte,NULL);    len += readByte;    Sleep(200);  }  while(readByte!=0 && hResult);  cout<<buffer<<endl;  CloseHandle(hOutPut);  return 0;}

方法二:
就是执行命令的时候加一个输出重定向到文件,然后再从文件中读取;文件最好建一个临时文件,不过windows还是不会帮我们自动删除的,需要我们自己删除;

void exec(){  HANDLE hFile;  STARTUPINFO st = {sizeof(STARTUPINFO)} ;  PROCESS_INFORMATION pi;  char szTempPath[MAX_PATH];  char szTempFile[MAX_PATH];  char buffer[4096];  char cmdLine[100];  DWORD dwRet ;  DWORD dwReadByte;  dwRet = GetTempPath(MAX_PATH,szTempPath);  if(!SUCCEEDED(dwRet))  {    cout<<"failed to Get temp path"<<GetLastError()<<endl;    return 1;  }  dwRet = GetTempFileName(szTempPath,TEXT("JJJJJay.txt"),0,szTempFile);  if(!SUCCEEDED(dwRet))  {    cout<<"failed to create temp file"<<GetLastError()<<endl;    return 1;  }  memset(cmdLine,0,sizeof(cmdLine));  int strLen = sizeof("c:\\windows\\system32\\cmd.exe /c ipconfig /all >");  memcpy(cmdLine,"c:\\windows\\system32\\cmd.exe /c ipconfig /all >",strLen);  memcpy(cmdLine+strLen-1,szTempFile,sizeof(szTempFile));  cmdLine[strLen+sizeof(szTempFile)] = '\0';  cout<<cmdLine<<endl;  if(!CreateProcess(NULL,cmdLine,NULL,  NULL,TRUE,NULL,NULL,NULL,&st,&pi))  {    cout<<"failed create proccess,error="<<GetLastError()<<endl;    return 1;  }  dwRet = WaitForSingleObject(pi.hProcess,INFINITE);  switch(dwRet)  {    case WAIT_TIMEOUT:    case WAIT_FAILED:      return 1;    case WAIT_OBJECT_0:    CloseHandle(pi.hProcess);    CloseHandle(pi.hThread);  }  hFile = CreateFile(szTempFile,GENERIC_READ,FILE_SHARE_DELETE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);  if(hFile == INVALID_HANDLE_VALUE)  {    cout<<"failed to create file"<<GetLastError()<<endl;    return 0;  }  memset(buffer,0,sizeof(buffer));  int len = 0 ;  do  {    dwRet = ReadFile(hFile,buffer+len,1024,&dwReadByte,NULL);    len += dwRet;  }while(dwRet && dwReadByte!=0);  CloseHandle(hFile);  DeleteFile(szTempFile);  return 0;}
1 0
原创粉丝点击