![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Selestin |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 20.10.2010 Репутация: нет Всего: нет |
Пишу програму, которая бы проверяла студенческие лабораторные работы, являющиеся консольными приложениями.
Задача: Записывать строку в STDIN студенческой программы, и читать STDOUT. С проблеммами столкнулся попытавшись использовать пайпы, т.к. приложение не всегда имеет инициализированную консоль изначально, я получаю ошибку доступа, обращаясь к хендлу пайпа. Решением было внедрить ДЛЛ в адресное пространство дочернего процесса и работать уже там. Внедрение происходит через CreateProcess с подменой кода. Суть в том что в данной реализации я никак не могу открыть STDIN, чтобы туда что-то записать, в STDOUT пишется нормально. Пытался уже разными способами, результата получить никак не могу. Способы использованные для открытия:
Результатов не получено. Приложения которые корректно создаются CreateProcess(С изначально инициализированной консолью), позволяют корректно записывать данные в stdin через пайп. Спасибо. Это сообщение отредактировал(а) Selestin - 29.10.2010, 22:31 |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Удаление гланд через задницу? А создать пару хэндлов и передать их в качестве stdin и stdout запускаемому процессу (студенческой консольной задаче) через CreateProcess не проще? |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
полагаю, это уже было сделано, но для уточнения: http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx Selestin, ты имеешь ввиду этот вариант, или что-то другое, когда пишешь о пайпах? -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
GoldFinch |
|
||||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 2 Всего: 26 |
![]() Вот это я понимаю, правильный подход. Не работает что-то удаленно - берем и инжектим длл. ---
Если приложение консольное (в PE заголовке в OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI) то консоль будет инициализирована изначально. (если приложение не консольное, то перед его запуском этот флаг можно поменять) |
||||
|
|||||
Selestin |
|
||||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 20.10.2010 Репутация: нет Всего: нет |
Да, этот. При использовании такого способа, на процессе, который изначально не имеет консоли, возникает ошибка доступа.
Чем это мне поможет? Т.к. приложение имеет всегда одну консоль, то предположим AllocConsole студенческой проги вернет мне ошибку, и работа будет выполнятся уже в созданной изначально консоли, но над тестить, в теории может сработать. |
||||
|
|||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
если конечно в студенческой проге нет например такой проверки:
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Selestin |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 20.10.2010 Репутация: нет Всего: нет |
Такой точно нет. А на каком этапе нужно ставить флаг в PE хидер? Создать с флагом CREATE_SUSPENDED и после изменения ресюм делать?
|
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Если первое, то скорее всего эта студенческая программа вообще не консольная (а GUI), снабжать ее любыми консольными хэндлами (как снаружи, так и изнутри) бесполезно. Runtime от GUI приложения скорее всего даже не станет инициализировать stdin/stdout. И попытка сделать в них scanf/printf будет проигнорирована, сколько бы консолей потом не понавешали этой программе ![]() |
|||
|
||||
Selestin |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 20.10.2010 Репутация: нет Всего: нет |
||||
|
||||
leniviy |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 552 Регистрация: 8.2.2003 Где: Спб Репутация: 1 Всего: 5 |
Чтобы прочитать, что вывела тестируемая прога в консоль, необязательно что-то перехватывать.
Как только была вызвана AllocConsole(), можно запустить дочерний процесс. В нужный момент он будет читать буфер консоли и отправлять на проверку. DLL внедрять всё же надо, чтобы она по таймеру проверяла, открыта ли консоль и запускала дочерний процесс. И ввод лучше делать не через поток, а через WriteConsoleInput() в том же дочернем процессе. Так можно протестировать хоть FAR , хоть игрушку Это сообщение отредактировал(а) leniviy - 2.11.2010, 17:34 |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Понятно. Эта прога открывает свою консоль. Ее снаружи перехватить нельзя ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |