2011-01-17 12 views
6

Sto tentando di inviare comandi all'ingresso di un'applicazione cmd.exe utilizzando le funzioni di console di lettura/scrittura di basso livello. Non ho problemi a leggere il testo (scraping) usando le funzioni ReadConsole...() e dopo averlo collegato alla console di processo, ma non ho capito come scrivere ad esempio "dir" e avere la console interpretarlo come un comando inviato.Input e reindirizzamento della console a basso livello

Ecco un po 'del mio codice:

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 attributi del processo sono tutti impostati a zero, tranne, naturalmente, l'attributo .cb.

Nulla cambia sullo schermo, tuttavia sto ottenendo un Error 6: Invalid Handle restituito da WriteConsole a STD_INPUT_HANDLE. Se scrivo a (STD_OUTPUT_HANDLE), ottengo il mio dir scritto sullo schermo, ma ovviamente non succede nulla. Immagino che il SetConsoleMode() potrebbe essere d'aiuto, ma ho provato molte combinazioni di modalità, niente di utile. Ho anche creato un'applicazione di console rapida che attende input (scanf()) e restituisce tutto ciò che accade, non ha funzionato.

Ho anche provato a digitare nel prompt di scanf() e poi sbirciare nel buffer di input utilizzando PeekConsoleInput(), restituisce 0, ma l'array INPUT_RECORD è vuoto.

Sono consapevole che c'è un altro modo per aggirare questo usando WriteConsoleInput() per iniettare direttamente gli eventi strutturati INPUT_RECORD nella console, ma questo sarebbe troppo lungo, dovrò inviare ogni tasto in esso.

Spero che la domanda sia chiara. Per favore fatemi sapere se avete bisogno di ulteriori informazioni. Grazie per l'aiuto.

Update 1:

Sono in grado di inviare i tasti premuti a un processo cmd utilizzando WriteConsoleInput() con INPUT_RECORD le strutture, tuttavia, il AttachConsole a volte getta ERROR_GEN_FAILURE #31: A device attached to the system is not functioning., e quindi la INPUT_RECORD non vengono inviati (Error 6: Invalid Handle). Sleep(1000) dopo CreateProcess() prima del AttachConsole() risolve questo problema. I caratteri dir vengono digitati in modo automatico, ma non riesco a capire come inviare la chiave RETURN:

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 rendimenti 0, ma non succede nulla nella console, ho provato a installare SetConsoleMode()-ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT e un combinazione di questi, senza risultati, però. Se premo invio dalla tastiera, tuttavia, viene eseguito il comando dir automaticamente digitato (a differenza delle volte in cui ho solo WriteConsole()), quindi suppongo di essere sulla strada giusta.

L'SSH non invia i tasti effettivi e ottiene il buffer dello schermo effettivo (come TAB e CTRL + C CTRL + D funzionano)? Sto cercando qualcosa del genere.

Aggiornamento 2:

ho trovato il problema con l'iniezione del comando di ritorno. Avrebbe dovuto essere ir[1].Event.KeyEvent.uChar.AsciiChar = '\r';, ovvero uno \r anziché uno \n, molto semplice.

Sembra che non v'è alcun modo di usare WriteConsole() ai comandi di input, si dovrebbe ottenere da parte con l'invio di WriteConsoleInput() INPUT_RECORDs o con la creazione di tubi (non sempre perfetto, ma grande per la maggior parte delle applicazioni dritto in avanti). Un grande vantaggio dell'uso di e VK_DOWN, per accedere alla cronologia della console, (se siamo in CMD) e VK_TAB per il completamento automatico, tutte le sequenze CTRL + _, i tasti ESC e FUNCTION e anche i CLICK MOUSE .

Maggiori informazioni qui: http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx più tonnellate di esempi qui: http://controllingtheinter.net/forums/viewtopic.php?f=116&t=366

Se qualcuno ha altre idee grandi si sentono liberi di chip in Grazie a tutti coloro che hanno preso interesse in questo.. Spero che questo aiuti qualcuno in futuro.

risposta

2

In questo momento si sta tentando di scrivere sul proprio handle stdin, non quello per il processo cmd.exe. Dovrai fare molto più lavoro per reindirizzare l'handle di input per quello. Richiede una pipa. Ecco uno KB article che mostra il codice di riferimento.

Btw: sempre controllare il valore restituito delle funzioni API.

+0

Ho pensato di collegarlo alla console del nuovo processo. 'AttachConsole()' consente questo; quando I 'printf()' dopo aver allegato sto effettivamente stampando in 'cmd.exe'. Ho aggiornato il codice di errore che ho ricevuto da 'WriteConsole()' a 'STD_INPUT_HANDLE' – soulseekah

+0

Condividi solo la finestra della console, il gioco è fatto. Sì, il codice di errore ti mostra cosa sta andando male, non puoi scrivere su un handle di input. –

+0

Ho letto quel codice e l'ho provato ieri, funziona come un incantesimo, ahimè questi programmi generati come 'FTP.exe' e' EDIT.exe' hanno i propri buffer, che non vengono reindirizzati, questo richiede letture e scrittura a basso livello alla console. Essenzialmente voglio clonare una finestra della console, reindirizzando tutto da uno all'altro. – soulseekah

Problemi correlati