Entrada de consola de bajo nivel y redireccionamiento
Estoy tratando de enviar comandos a la entrada de uncmd.exe
aplicación que utiliza las funciones de consola de lectura / escritura de bajo nivel. No tengo problemas para leer el texto (scraping) usando elReadConsole...()
yWriteConsole()
funciona después de haberse conectado a la consola de proceso, pero no he descubierto cómo escribir, por ejemplo"dir"
y haga que la consola lo interprete como un comando enviado.
Aquí hay un poco de mi 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 los atributos del proceso están establecidos en cero, excepto, por supuesto, el.cb
atributo.
Nada cambia en la pantalla, sin embargo, recibo unError 6: Invalid Handle
regresó deWriteConsole
aSTD_INPUT_HANDLE
. Si escribo a(STD_OUTPUT_HANDLE)
Consigo midir
escrito en la pantalla, pero por supuesto no pasa nada. Estoy adivinandoSetConsoleMode()
puede ser de ayuda, pero he probado muchas combinaciones de modos, nada ayudó. También he creado una aplicación de consola rápida que espera entrada (scanf()
) y repite todo lo que entra, no funcionó.
También he intentado escribir en elscanf()
preguntar y luego mirar en el búfer de entrada usandoPeekConsoleInput()
, devuelve 0, pero elINPUT_RECORD
La matriz está vacía.
Soy consciente de que hay otra forma de evitar esto usandoWriteConsoleInput()
para inyectar directamente eventos estructurados INPUT_RECORD en la consola, pero esto sería demasiado tiempo, tendré que enviar cada pulsación de tecla.
Espero que la pregunta sea clara. Avíseme si necesita más información. Gracias por tu ayuda.
Actualización 1:
Puedo enviar pulsaciones de teclas acmd
proceso utilizandoWriteConsoleInput()
conINPUT_RECORD
estructuras, sin embargo, elAttachConsole
a veces tiraERROR_GEN_FAILURE #31: A device attached to the system is not functioning.
, y así elINPUT_RECORD
no se envían (Error 6: Invalid Handle
)Sleep(1000)
despuésCreateProcess()
antes deAttachConsole()
resuelve esto Los caracteresdir
se escriben automáticamente, pero no puedo entender cómo enviar elRETURN
llave:
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
devoluciones0
, pero no pasa nada en la consola, he intentado configurarSetConsoleMode()
aENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT
y una combinación de los mismos, sin resultados, sin embargo. Sin embargo, si presiono Intro desde el teclado, se escribe automáticamentedir
el comando se ejecuta (a diferencia de las veces en que soloWriteConsole()
), así que supongo que estoy en el camino correcto.
¿SSH no envía las pulsaciones de teclas reales y obtiene el búfer de pantalla real (como TAB y CTRL + C CTRL + D funciona)? Estoy detrás de algo así.
Actualización 2:
Encontré el problema al inyectar el comando de retorno. Debería haber sidoir[1].Event.KeyEvent.uChar.AsciiChar = '\r';
es decir, un\r
en vez de una\n
Súper simple.
Parece que no hay forma de usarWriteConsole()
para ingresar comandos, uno debe pasar enviandoWriteConsoleInput()
INPUT_RECORDs o creando tuberías (que no siempre son perfectas, pero son excelentes para la mayoría de las aplicaciones sencillas). Una gran ventaja de usarWriteConsoleInput()
es que uno puede enviarVK_UP
yVK_DOWN
, para acceder al historial de la consola (si estamos en CMD) yVK_TAB
para autocompletar, todas las secuencias CTRL + _, ESC y teclas de FUNCIÓN e incluso CLIC RATONES.
Más información aquí:http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx más toneladas de ejemplos aquí:http://controllingtheinter.net/forums/viewtopic.php?f=116&t=366
Si alguien tiene otras ideas geniales, siéntase libre de contribuir. Gracias a todos los que se interesaron por esto. Espero que esto ayude a alguien en el futuro.