Search code examples
c++windowswinapiterminal

I can't figure out how to pass a command to the windows terminal input control. C++


I am trying to write a program with which it will be possible to send a command highlighted in the browser to the terminal. I stumble on the fact that I can't figure out how to transfer any command to the terminal that my program opens. That's how I launch the terminal:

PROCESS_INFORMATION processInfo;
STARTUPINFO startupInfo = { sizeof(startupInfo) };
ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);

ZeroMemory(&processInfo, sizeof(processInfo));

char cmdPath[] = "C:\\Windows\\System32\\cmd.exe";
CreateProcess(cmdPath, nullptr, nullptr, nullptr, FALSE,
    CREATE_NEW_CONSOLE, nullptr, nullptr, &startupInfo, &processInfo);

Solution

  • RbMm's opinion is completely right. No matter supplying input to cmd or retrieve it's output. Pipe is an efficient method. Here is the sample:

    #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);
          strcat_s(cmd, "\r\n");
          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;
       }
    }