Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Попытка записи в stdin 
:(
    Опции темы
Selestin
Дата 29.10.2010, 22:30 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Пишу програму, которая бы проверяла студенческие лабораторные работы, являющиеся консольными приложениями.

Задача: Записывать строку в STDIN студенческой программы, и читать STDOUT.

С проблеммами столкнулся попытавшись использовать пайпы, т.к. приложение не всегда имеет инициализированную консоль изначально, я получаю ошибку доступа, обращаясь к хендлу пайпа.

Решением было внедрить ДЛЛ в адресное пространство дочернего процесса и работать уже там.
Внедрение происходит через CreateProcess с подменой кода.

Суть в том что в данной реализации я никак не могу открыть STDIN, чтобы туда что-то записать, в STDOUT пишется нормально. Пытался уже разными способами, результата получить никак не могу.

Способы использованные для открытия:
Код

1) CreateFile( (LPCWSTR)"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 );
 
2) DuplicateHandle(GetCurrentProcess(),GetStdHandle(STD_INPUT_HANDLE),GetCurrentProcess(),&stdin_pseudo,GENERIC_READ | GENERIC_WRITE,FALSE,NULL)
 
3)  lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
 fp = _fdopen( hConHandle, "w" );
 
4) CreatePipe(&stdin_pipe_output, &stdin_pipe_input, lpsa,25000);
 
5) WriteFile(GetStdHandle(STD_INPUT_HANDLE),"1234\n",5,&BytesBuffer,NULL)

Результатов не получено.

Приложения которые корректно создаются CreateProcess(С изначально инициализированной консолью), позволяют корректно записывать данные в stdin через пайп.

Спасибо.

Это сообщение отредактировал(а) Selestin - 29.10.2010, 22:31
PM MAIL   Вверх
xvr
Дата 1.11.2010, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Selestin @  29.10.2010,  22:30 Найти цитируемый пост)
С проблеммами столкнулся попытавшись использовать пайпы, т.к. приложение не всегда имеет инициализированную консоль изначально, я получаю ошибку доступа, обращаясь к хендлу пайпа.

Решением было внедрить ДЛЛ в адресное пространство дочернего процесса и работать уже там.
Внедрение происходит через CreateProcess с подменой кода.
Удаление гланд через задницу?

А создать пару хэндлов и передать их в качестве stdin и stdout запускаемому процессу (студенческой консольной задаче) через CreateProcess не проще?


PM MAIL   Вверх
GremlinProg
Дата 1.11.2010, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(xvr @  1.11.2010,  15:00 Найти цитируемый пост)
А создать пару хэндлов и передать их в качестве stdin и stdout запускаемому процессу (студенческой консольной задаче) через CreateProcess не проще?


Цитата(Selestin @  30.10.2010,  00:30 Найти цитируемый пост)
С проблеммами столкнулся попытавшись использовать пайпы, т.к. приложение не всегда имеет инициализированную консоль изначально, я получаю ошибку доступа, обращаясь к хендлу пайпа.


полагаю, это уже было сделано, но для уточнения: http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx
Selestin, ты имеешь ввиду этот вариант, или что-то другое, когда пишешь о пайпах?


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GoldFinch
Дата 1.11.2010, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



Цитата(Selestin @  29.10.2010,  23:30 Найти цитируемый пост)
Решением было внедрить ДЛЛ в адресное пространство дочернего процесса и работать уже там.

 smile 

Вот это я понимаю, правильный подход. Не работает что-то удаленно - берем и инжектим длл.

---

Цитата(Selestin @  29.10.2010,  23:30 Найти цитируемый пост)
приложение не всегда имеет инициализированную консоль изначально

Если приложение консольное (в PE заголовке в OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI) то консоль будет инициализирована изначально. (если приложение не консольное, то перед его запуском этот флаг можно поменять)
PM MAIL ICQ   Вверх
Selestin
Дата 2.11.2010, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Цитата

полагаю, это уже было сделано, но для уточнения: http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx
Selestin, ты имеешь ввиду этот вариант, или что-то другое, когда пишешь о пайпах?

Да, этот. При использовании такого способа, на процессе, который изначально не имеет консоли, возникает ошибка доступа.

Цитата

Если приложение консольное (в PE заголовке в OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI) то консоль будет инициализирована изначально. (если приложение не консольное, то перед его запуском этот флаг можно поменять) 

Чем это мне поможет?
Т.к. приложение имеет всегда одну консоль, то предположим AllocConsole студенческой проги вернет мне ошибку, и работа будет выполнятся уже в созданной изначально консоли, но над тестить, в теории может сработать.
PM MAIL   Вверх
GremlinProg
Дата 2.11.2010, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Selestin @  2.11.2010,  16:30 Найти цитируемый пост)
и работа будет выполнятся уже в созданной изначально консоли

если конечно в студенческой проге нет например такой проверки:
Код

if( !::AllocConsole() ){
  // без консоли я работать не буду
  return 0;
}




--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Selestin
Дата 2.11.2010, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Такой точно нет. А на каком этапе нужно ставить флаг в PE хидер? Создать с флагом CREATE_SUSPENDED и после изменения ресюм делать?
PM MAIL   Вверх
xvr
Дата 2.11.2010, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Selestin @  2.11.2010,  14:30 Найти цитируемый пост)
При использовании такого способа, на процессе, который изначально не имеет консоли, возникает ошибка доступа.
Уточни, пожалуйста - 'процессе, который изначально не имеет консоли' имеется в виду запускаемый (студенческий) процесс? Или твой, который всех запускает?
Если первое, то скорее всего эта студенческая программа вообще не консольная (а GUI), снабжать ее любыми консольными хэндлами (как снаружи, так и изнутри) бесполезно. Runtime от GUI приложения скорее всего даже не станет инициализировать stdin/stdout. И попытка сделать в них scanf/printf будет проигнорирована, сколько бы консолей потом не понавешали этой программе  smile 

PM MAIL   Вверх
Selestin
Дата 2.11.2010, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Имеется ввиду запускаемый процесс. Вот его дебаг:
link
PM MAIL   Вверх
leniviy
Дата 2.11.2010, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Чтобы прочитать, что вывела тестируемая прога в консоль, необязательно что-то перехватывать. 
Как только была вызвана AllocConsole(), можно запустить дочерний процесс. В нужный момент он будет читать буфер консоли и отправлять на проверку.
DLL внедрять всё же надо, чтобы она по таймеру проверяла, открыта ли консоль и запускала дочерний процесс.

И ввод лучше делать не через поток, а через WriteConsoleInput() в том же дочернем процессе.

Так можно протестировать хоть FAR , хоть игрушку



Это сообщение отредактировал(а) leniviy - 2.11.2010, 17:34
PM MAIL   Вверх
xvr
Дата 2.11.2010, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Selestin @ 2.11.2010,  17:27)
Имеется ввиду запускаемый процесс. Вот его дебаг:
link

Понятно. Эта прога открывает свою консоль. Ее снаружи перехватить нельзя  smile Тут действительно нужен inject. Посмотри библиотеку Detour от MS - она как раз для этого

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1165 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.