![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите разобраться с доступом к содержимому окна вывода консоли
vertal © (2004-04-25 01:02:00)Я устанавливаю горячую клавишу , при обработке события от ее нажатия хочу проверить , является ли активное окно(не моей программы) консольным , и если да , то получить его экран вывода(символы и атрибуты).Пишу:
...
Var
IsFocusOnConsole:Bool;
ConsoleScreenBufferInfo:_Console_Screen_Buffer_Info;
begin
IsFocusOnConsole:=GetConsoleScreenBufferInfo
(GetForegroundWindow,ConsoleScreenBufferInfo);
...
End;
Проблема в том , что IsFocusOnConsole=0 всегда , даже если активно консольное окно , а GetLastError возвращает 6(INVALID_HANDLE_VALUE).Подскажите , что здесь не так?
vertal (2004-05-08 00:13:00) [1]to Bin[23]
Спасибо за ссылки , обязательно посмотрю .
Я тут правда уже раскопал на http://www.madshi.netмодуль , который имеет функцию InjectLibrary/UnInjectLibrary , которая работает во всех виндах . Теперь по горячей клавише вызываю эту функцию , внедряю свою библиотеку с собственно алгоритмом преобразования и все работает , только при условии , что активная консоль - это Windows - программа (far) или DOS - программа , но которая запускалась в той же консоли фаром .Если же активная консоль - DOS - программа , запущенная не из-под фара , то задачу опять не удается решить.
марсианин (2004-05-07 23:44:00) [2]здравый смысл подсказывает, что мы слегка перегибаем палку.. для того, чтоб получить доступ к чужой консоле внедряем ДЛЛ, перехватываем вызовы ВинАПИ и тп..
наверняка майкрософт придумал чего по-проще.. напр. AttachConsole вполне подошла бы, но она только на семействе WinNT.. может быть, для 98 кроме внедрения/перехвата выхода нет.. но стоит еще порыться
BiN (2004-05-07 13:39:00) [3]Видел у Рихтера вариант внедрения с CreateRemoteThread , но хочу , чтобы работало во всех виндах.
Можете что-нибудь посоветовать?
http://delphimaster.ru/articles/Dapi/index.html
http://internals.com/articles/apispy/apispy.htm
http://maxcomputing.narod.ru/ahijack2.html
http://maxcomputing.narod.ru/ahijack3.html
vertal (2004-05-07 01:52:00) [4]Сорри за предыдущее сообщение - я несколько повторился
Теперь проверил и по ParamStr(0)... ParamStr(0) возвращает имя exe только если активно GUI приложение ; если активна консоль (и DOS - и Windows - программ , неважно ) , то ParamStr(0)=[SYSDIR]\kernel32.dll . Что это значит ?
Я теперь думаю , глобальный хук нельзя применять для внедрения в адресное пространство консольных приложений (о чем в принципе сказано и у Рихтера , и в MS SDK Help ), да и сам хук на клавиатуру в принципе не работает в консоле (специфицированная функция вызывается только при нажатии PrintScreen в консоли , при нажатии любых других клавиш она не вызывается ).
Видел у Рихтера вариант внедрения с CreateRemoteThread , но хочу , чтобы работало во всех виндах.
Можете что-нибудь посоветовать?
vertal (2004-05-07 00:52:00) [5]> проверь это, идентифицируй процесс, выведи окошко с paramstr(0) чтоли :)
Ситуация следующая:
GetStdHandle(STD_OUTPUT_HANDLE),совершенно необходимая функция для дальнейших действий , у меня отрабатывает успешно в двух случаях :
1) Из моего exe консольной программы
2) При вызове из dll - плагина к far , если явно вызывается farом через OpenPlugin
При вызове же из обработчика события , на который установлен глобальный хук из этой же dll(в соответствии с рекомендациями Рихтера) , GetStdHandle(STD_OUTPUT_HANDLE) всегда неуспешна (возвращает -1), даже если активно консольное окно .dll по-моему все-таки загружается в АП активного процесса , о чем я сужу по признакам:
а) Выполняется ее код инициализации при отображении в каждый новый процесс(то что между Begin и End.)
б) GetWindowText(GetActiveWindow,buf,buflen) пишет в буфер заголовок активного окна
GetLastError после GetStdHandle(STD_OUTPUT_HANDLE) возвращает при первом вызове из нового процесса
2 (ERROR_FILE_NOT_FOUND)
, а при всех последующих -
87 (ERROR_INVALID_PARAMETER)
Кто-нить знает , что здесь не так?
Polevi (2004-05-06 08:04:00) [6]>хотя теперь dll по идее должна работать в адресном пространстве приложения
проверь это, идентифицируй процесс, выведи окошко с paramstr(0) чтоли :)
vertal (2004-05-06 01:20:00) [7]Код , подобный [14] , действительно работает , спасибо за разъяснения . Однако пока не получается выполнить его по горячей клавишше и для любого окна (отработало это только в виде плагина к фару , при явном вызове функции из dll фаром).А когда обрабатываю свою глобальную ловушку , установленную из этой же dll , результат все время такой , как описано в [1] , хотя теперь dll по идее должна работать в адресном пространстве приложения , которому направлялось событие от нажатия клавиш (и она в него загружается , GetWindowText(GetActiveWindow,...) дает заголовок любого активного окна)
VMcL (2004-05-04 03:25:00) [8]>>vertal © (04.05.04 00:33) [17]
>Хорошо , как в таком случае можно внедриться в адресное пространство другого приложения?
Способов несколько. См. в книге Рихтера:
http://www.podgoretsky.com/ftp/Docs/Classics/Richter/
vertal (2004-05-04 00:33:00) [9]>по нажатию горяечей клавиши ты должен внедрить свой код в
>адресное пространство конмольного процесса и передеать ему
>управление.
Хорошо , как в таком случае можно внедриться в адресное пространство другого приложения?
Polevi (2004-05-03 09:13:00) [10]> [15] vertal (03.05.04 00:29)
твоя задача заключается в том, чтоюы выполнить похожий код в чужом процессе
по нажатию горяечей клавиши ты должен внедрить свой код в адресное пространство конмольного процесса и передеать ему управление. этот код получит хендл буфера с помощью GetStdHandle, и любым IPC механизмом передаст его содержимое буфера твоей программе
vertal (2004-05-03 00:29:00) [11]В этом примере как я понимаю происходит получение стандартной консоли , ассоциированной с вызывающим эти функции (GetStdHandle) приложением. Мне же не нужно создавать никаких консолей , а к описанной задаче этот пример мало подходит.
Марсианин (2004-05-02 03:00:00) [12]почитал хелп -- нихрена не понял.. если надо внедряться -- внедримся, а если я хочу получить его в своем приложении?
впрочем пример из МСДН вносит некотурую ясность
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
SMALL_RECT srctWindow;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // вот мы его, родимого, получили
// Get the current screen buffer size and window position.
if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
MyErrorExit("GetConsoleScreenBufferInfo");
// Set srctWindow to the current window size and location.
srctWindow = csbiInfo.srWindow;
// If window is not at the screen buffer top, move it up one line.
if ( srctWindow.Top > 0 )
{
srctWindow.Top -= 1; // move top up by one row
srctWindow.Bottom -= 1; // move bottom up by one row
if (! SetConsoleWindowInfo(
hStdout, // screen buffer handle
TRUE, // absolute coordinates
&srctWindow)) // specifies new location
MyErrorExit("SetConsoleWindowInfo");
}
The same scrolling can be done by specifying changes in the window coordinates.
// Get the current screen buffer window position.
if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
MyErrorExit("GetConsoleScreenBufferInfo");
// If window is not at the screen buffer top, move it up one line.
if (csbiInfo.srWindow.Top > 0)
{
srctWindow.Top = -1; // move top up by one row
srctWindow.Bottom = -1; // move bottom up by one row
srctWindow.Left = 0; // no change
srctWindow.Right = 0; // no change
if (! SetConsoleWindowInfo(
hStdout, // screen buffer handle
FALSE, // deltas, not absolute
&srctWindow)) // specifies new location
{
MyErrorExit("SetConsoleWindowInfo");
}
}
vertal (2004-05-01 01:28:00) [13]Ну не нашел я , как получить этот хендл . А внедриться в чужой процесс - это как ?
BiN (2004-04-30 23:13:00) [14]Polevi © (30.04.04 13:48) [11]
Можно и драйвер для этого написать, а смысл?
править образ kernel32 в общедоступной памяти - оправдывает ли цель средства. imho трудно будет избежать сбоев системы.
Polevi (2004-04-30 13:48:00) [15]внедриться в чужой процесс можно и в 9x
BiN (2004-04-30 09:49:00) [16]хотя нет в XP еще есть AttachConsole
BiN (2004-04-30 09:22:00) [17]можно внедриться в консольный процесс
imho это единственный 100%-й способ (конечно для NT и иже с ним)
Polevi (2004-04-30 08:13:00) [18]можно внедриться в консольный процесс
Cobalt (2004-04-30 00:41:00) [19]Даю наводку - как получить хендл консольного буфера (или что там у него)?
Это вы знаете? Или, быть может, сможете найти?
Я, например, не в курсе. Но, если бы передо мной стояла бы эта проблема, то это был бы мой первый ход.
vertal (2004-04-30 00:28:00) [20]Цель - получить экран вывода активной консольной программы в описанных условиях и далее провести некоторые операции с этим экраном. Провести операции - не проблема , проблема , как я уже сказал , заключается в том , что GetConsoleScreenBufferInfo и ReadConsoleOutput не отрабатывают , как я хочу.Если вам очень интересно , то могу сказать , что я задумал программу , которая по этой горячей клавише (Ctrl+PrintScreen в идеале ) будет запихивать в буфер html-код этого экрана с сохранением цветов , таким образом можно будет получать компактные "скриншоты" консольных прог.