Entrada e redirecionamento de console de baixo nível
Estou tentando enviar comandos para a entrada de umcmd.exe
aplicativo usando as funções do console de leitura / gravação de baixo nível. Não tenho problemas para ler o texto (raspagem) usando oReadConsole...()
eWriteConsole()
depois de ter se conectado ao console do processo, mas ainda não descobri como escrever, por exemplo"dir"
e faça com que o console o interprete como um comando enviado.
Aqui está um pouco do meu código:
CreateProcess(NULL, "cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
AttachConsole(pi.dwProcessId);
strcpy(buffer, "dir");
WriteConsole(GetStdHandle(STD_INPUT_HANDLE), buffer, strlen(buffer), &charRead, NULL);
STARTUPINFO
todos os atributos do processo são definidos como zero, exceto, é claro, o.cb
atributo.
Nada muda na tela, no entanto, estou recebendo umError 6: Invalid Handle
retornou deWriteConsole
paraSTD_INPUT_HANDLE
. Se eu escrever para(STD_OUTPUT_HANDLE)
Eu recebo meudir
escrito na tela, mas nada, é claro, acontece. estou a adivinharSetConsoleMode()
pode ser útil, mas eu tentei muitas combinações de modos, nada ajudou. Também criei um aplicativo de console rápido que aguarda a entrada (scanf()
) e ecoa de volta o que entra, não funcionou.
Eu também tentei digitar noscanf()
promp e espie o buffer de entrada usandoPeekConsoleInput()
, retorna 0, mas oINPUT_RECORD
matriz está vazia.
Estou ciente de que existe outra maneira de contornar isso usandoWriteConsoleInput()
para injetar diretamente eventos estruturados INPUT_RECORD no console, mas isso seria muito longo, vou ter que enviar cada pressionamento de tecla nele.
Espero que a pergunta seja clara. Entre em contato se precisar de mais informações. Obrigado pela ajuda.
Atualização 1:
Posso enviar pressionamentos de tecla a umcmd
processo usandoWriteConsoleInput()
comINPUT_RECORD
estruturas, no entanto, oAttachConsole
às vezes jogaERROR_GEN_FAILURE #31: A device attached to the system is not functioning.
e, portanto, oINPUT_RECORD
não são enviados (Error 6: Invalid Handle
)Sleep(1000)
depois deCreateProcess()
antesAttachConsole()
resolve isso. Os personagensdir
são digitados automaticamente, mas não consigo descobrir como enviar oRETURN
chave:
ir[0].EventType = KEY_EVENT;
ir[0].Event.KeyEvent.bKeyDown = TRUE;
ir[0].Event.KeyEvent.dwControlKeyState = 0;
ir[0].Event.KeyEvent.uChar.UnicodeChar = '\n';
ir[0].Event.KeyEvent.wRepeatCount = 1;
ir[0].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
ir[1].EventType = KEY_EVENT;
ir[1].Event.KeyEvent.bKeyDown = FALSE;
ir[1].Event.KeyEvent.dwControlKeyState = 0;
ir[1].Event.KeyEvent.uChar.UnicodeChar = '\n';
ir[1].Event.KeyEvent.wRepeatCount = 1;
ir[1].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
ir[1].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir, 2, &charRead);
WriteConsoleInput
retorna0
, mas nada acontece no console, tentei configurarSetConsoleMode()
paraENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT
e uma combinação dos mesmos, sem resultados, no entanto. Se eu pressionar enter no teclado, no entanto, o teclado digitado automaticamentedir
comando executa (diferente dos momentos em que eu apenasWriteConsole()
), então acho que estou no caminho certo.
O SSH não envia as teclas pressionadas reais e obtém o buffer de tela real (como TAB e CTRL + C CTRL + D funcionam)? Estou atrás de algo parecido.
Atualização 2:
Encontrei o problema ao injetar o comando de retorno. Deveria ter ficadoir[1].Event.KeyEvent.uChar.AsciiChar = '\r';
isto é, um\r
em vez de um\n
, super simples.
Parece que não há como usarWriteConsole()
para introduzir comandos, deve-se passar enviandoWriteConsoleInput()
INPUT_RECORDs ou criando pipes (que nem sempre são perfeitos, mas são ótimos para as aplicações mais diretas). Uma grande vantagem de usarWriteConsoleInput()
é que você pode enviarVK_UP
eVK_DOWN
, para acessar o histórico do console (se estivermos no CMD) eVK_TAB
para preenchimento automático, todas as seqüências CTRL + _, teclas ESC e FUNCTION e até MOUSE CLICKS.
Mais informações aqui:http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx mais toneladas de exemplos aqui:http://controllingtheinter.net/forums/viewtopic.php?f=116&t=366
Se alguém tiver outras ótimas idéias, sinta-se à vontade para participar. Obrigado a todos que se interessaram por isso. Espero que isso ajude alguém no futuro.