Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > Попытка записи в stdin |
Автор: Selestin 29.10.2010, 22:30 | ||
Пишу програму, которая бы проверяла студенческие лабораторные работы, являющиеся консольными приложениями. Задача: Записывать строку в STDIN студенческой программы, и читать STDOUT. С проблеммами столкнулся попытавшись использовать пайпы, т.к. приложение не всегда имеет инициализированную консоль изначально, я получаю ошибку доступа, обращаясь к хендлу пайпа. Решением было внедрить ДЛЛ в адресное пространство дочернего процесса и работать уже там. Внедрение происходит через CreateProcess с подменой кода. Суть в том что в данной реализации я никак не могу открыть STDIN, чтобы туда что-то записать, в STDOUT пишется нормально. Пытался уже разными способами, результата получить никак не могу. Способы использованные для открытия:
Результатов не получено. Приложения которые корректно создаются CreateProcess(С изначально инициализированной консолью), позволяют корректно записывать данные в stdin через пайп. Спасибо. |
Автор: GremlinProg 1.11.2010, 13:06 | ||||
полагаю, это уже было сделано, но для уточнения: http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx Selestin, ты имеешь ввиду этот вариант, или что-то другое, когда пишешь о пайпах? |
Автор: GoldFinch 1.11.2010, 14:04 | ||||
![]() Вот это я понимаю, правильный подход. Не работает что-то удаленно - берем и инжектим длл. ---
Если приложение консольное (в PE заголовке в OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI) то консоль будет инициализирована изначально. (если приложение не консольное, то перед его запуском этот флаг можно поменять) |
Автор: Selestin 2.11.2010, 14:30 | ||||
Да, этот. При использовании такого способа, на процессе, который изначально не имеет консоли, возникает ошибка доступа.
Чем это мне поможет? Т.к. приложение имеет всегда одну консоль, то предположим AllocConsole студенческой проги вернет мне ошибку, и работа будет выполнятся уже в созданной изначально консоли, но над тестить, в теории может сработать. |
Автор: GremlinProg 2.11.2010, 14:40 | ||
если конечно в студенческой проге нет например такой проверки:
|
Автор: Selestin 2.11.2010, 14:54 |
Такой точно нет. А на каком этапе нужно ставить флаг в PE хидер? Создать с флагом CREATE_SUSPENDED и после изменения ресюм делать? |
Автор: xvr 2.11.2010, 16:45 | ||
Если первое, то скорее всего эта студенческая программа вообще не консольная (а GUI), снабжать ее любыми консольными хэндлами (как снаружи, так и изнутри) бесполезно. Runtime от GUI приложения скорее всего даже не станет инициализировать stdin/stdout. И попытка сделать в них scanf/printf будет проигнорирована, сколько бы консолей потом не понавешали этой программе ![]() |
Автор: Selestin 2.11.2010, 17:27 |
Имеется ввиду запускаемый процесс. Вот его дебаг: http://paste.org/pastebin/view/20366 |
Автор: leniviy 2.11.2010, 17:32 |
Чтобы прочитать, что вывела тестируемая прога в консоль, необязательно что-то перехватывать. Как только была вызвана AllocConsole(), можно запустить дочерний процесс. В нужный момент он будет читать буфер консоли и отправлять на проверку. DLL внедрять всё же надо, чтобы она по таймеру проверяла, открыта ли консоль и запускала дочерний процесс. И ввод лучше делать не через поток, а через WriteConsoleInput() в том же дочернем процессе. Так можно протестировать хоть FAR , хоть игрушку |
Автор: xvr 2.11.2010, 20:33 | ||
Понятно. Эта прога открывает свою консоль. Ее снаружи перехватить нельзя ![]() |