Получение данных из консольного окна другого приложения
Мы уже умеем перехватывать ввод и вывод консольных приложений, но этот способ работает только для тех процессов, которые мы сами запустили. Но иногда надо получать информацию из консольных приложений, которые уже были запущены в системе или могут быть запущены в дальнейшем, но не нами. А еще бывают консольные приложения, вывод которых невозможно перенаправить и, соответственно, невозможно получить описанным ранее способом. Для них также придется использовать способ из этой статьи.Для начала как всегда несколько структур, которые изначально не описаны в FASM. Они нам понадобятся для работы с консольным окном:
Code (Assembler) : Убрать нумерацию
- struct COORD
- X dw ?
- Y dw ?
- ends
- struct SMALL_RECT
- Left dw ?
- Top dw ?
- Right dw ?
- Bottom dw ?
- ends
- struct CONSOLE_SCREEN_BUFFER_INFO
- dwSize COORD
- dwCursorPosition COORD
- wAttributes dw ?
- srWindow SMALL_RECT
- dwMaximumWindowSize COORD
- ends
Код достаточно простой, но несколько пояснений все-таки требуется. Зачем вызывать FreeConsole перед аттачем к консоли? Дело в том, что каждое приложение единовременно может работать только с одной консолью. При попытке подключиться к другой консоли, не разорвав связь с уже подключенной, система вернет ошибку. Функция FreeConsole разрывает связь с любой консолью, соединенной с вашим процессом. Даже если из своего кода вы никаких консолей пока не подключали, теоретически это могли сделать сторонние модули или внедренный код. Ситуация крайне маловероятная, но хорошим тоном будет ее предусмотреть.
При чтении данных из консольного окна вы можете забрать сразу все данные, но они будут переданы единой строкой без переносов. Для чтения построчно надо определить длину строки и выполнять последовательно чтение каждой строки, меняя начальные координаты позиции для чтения. Впрочем, если вам надо, например, просто узнать наличие каких-нибудь данных в консоли, то никто не запрещает читать ее единым куском. Финальные пробелы в строках не обрезаются, это также придется делать вашей программе.
Code (Assembler) : Убрать нумерацию
- ; Найти консольное окно
- invoke FindWindow,NULL,szTitle
- or eax,eax
- jz loc_exit
- ; Узнать ID процесса, связанного с консолью
- invoke GetWindowThreadProcessId,eax,pID
- ; Процесс может быть соединен только с одной консолью,
- ; поэтому надо на всякий случай отсоединиться от
- ; других консолей
- invoke FreeConsole
- ; Присоединиться к найденной консоли
- invoke AttachConsole,[pID]
- or eax,eax
- jz loc_exit
- ; Получить стандартный хэндл вывода
- invoke GetStdHandle,STD_OUTPUT_HANDLE
- mov [hOut],eax
- ; Получить информацию об окне консоли
- invoke GetConsoleScreenBufferInfo,[hOut],csbi
- ; Счетчик строк
- xor eax,eax
- ; Длина строки
- movzx ebx,[csbi.dwMaximumWindowSize.X]
- loc_read_y:
- push eax
- ; Координаты для чтения строки из консоли
- mov [grab.X],0
- mov [grab.Y],ax
- ; Прочитать строку из консоли
- invoke ReadConsoleOutputCharacter,[hOut],buff,ebx,[grab],tmp
- ; ...
- ; Теперь в buff содержится строка из консольного окна
- ; ...
- ; Следующая строка
- pop eax
- inc eax
- ; Все строки обработали?
- cmp ax,[csbi.dwMaximumWindowSize.Y]
- jb loc_read_y
- ; Отсоединиться от консоли
- invoke FreeConsole
- loc_exit:
- invoke ExitProcess,0
В приложении пример программы с исходным текстом, которая ищет консольное окно по заголовку (console_source.exe), получает из него все содержимое и выводит полученный текст в своем диалоговом окне.
Просмотров: 2041 | Комментариев: 0
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария