PDA

Просмотр полной версии : ХУК(искал, но не нашел)



Keith
28.02.2005, 22:29
Три вопроса:

1. SetWindowsHookEx(WH_GETMESSAGE,...) не вешается на первичный поток, который был создан и сразу приостановлен(CREATE_SUSPENDED). На сколько я понял – это из-за 'WH_GETMESSAGE'. Посоветуйте на что еще можно повесить хук для того, чтобы он работал в 98-XP.

2. Мне нужно, чтобы чужой поток, на который я делаю хук, выполнял определенный код, когда мой поток вызывает UnhookWindowsHookEx(). Как это лучше сделать?

3. Как лучше передать информацию(строка + хэндл) из потока на который поставлен хук в поток, который устанавливал хук? Я так понимаю, что потоку на который вешается хук надо будет передавать свой ThreadId? Как это лучше сделать?

Выслушаю любые мысли. Заранее - большое СПАСИБО.

Eugie
01.03.2005, 16:56
1. И правильно не вешается :) - поток ведь приостановлен. Чтобы хук был установлен, должна быть вызвана (явно или неявно) какая-либо функция выборки сообщений (PeekMessage или GetMessage).

2. UnhookWindowsHookEx() выгружает hook_proc DLL из памяти, поэтому код завершения можно выполнять на THREAD_DETACH (или PROCESS_DETACH) в DllMain().

3. Зачем Вам это нужно?

Keith
01.03.2005, 23:06
1. Может быть 'WH_GETMESSAGE' можно чем-то заменить?

2. Иногда долго не выгружает, хотя в GetMsgProc() только:
return(CallNextHookEx(g_hhook, code, wParam, lParam));

3. Мне нужно внедрять свой код в чужой поток, чтобы он там выполнялся два раза: при вредрении(вкл. перехват API) и при отключении(выкл. перехват API), но при этом нужно, чтобы код можно было внедрять в поток, который находиться в SUSPENDED. Это нужно, чтобы ни один вызов API не был пропущен.
Работать должно в win98/2000/XP, поэтому и выбрал хуки.

Вот немного подробнее:
My_DLL: имеет две функции: my_init() и my_exit(). Первая устанавливает перехват CreateProcess(), вторая — снимает.
My_Thread: устанавливает глобальный HotKey, при нажатии которого в процесс активного окна(GetForegroundWindow()) внедряется моя dll и выполняется my_init(). Если этот процесс захочет создать свою копию, т.е. вызовет CreateProcess(thisProgName,...), то на нее надо сразу вешать мою dll и выполнять my_init() _до_ выполнения команд первичного потока. Для этого я и хочу добавлять к шестому параметру CREATE_SUSPENDED, потом устанавливать хук, а потом вызывать ResumeThread() для первичного потока. Если опять нажат HotKey и активно окно процесса в котором висит моя dll, то выполнять my_exit() в этом процессе.

Eugie
02.03.2005, 16:45
Может быть 'WH_GETMESSAGE' можно чем-то заменить?

Вряд ли это поможет. Ведь внедрение (глобального хука) предполагает загрузку DLL, т.е. ОС должна неявно вызвать LoadLibrary в контексте процесса, а это невозможно, если процесс приостановлен. А главное, я не понимаю, зачем все это нужно. Вы смотрели пример Рихтера? Он перехватывает MessageBox, ничего не приостанавливая. Что мешает сделать то же самое для CreateProcess?


Иногда долго не выгружает

Не дольше нескольких секунд. Это критично?

Keith
03.03.2005, 01:19
Вряд ли это поможет. Ведь внедрение (глобального хука) предполагает загрузку DLL, т.е. ОС должна неявно вызвать LoadLibrary в контексте процесса, а это невозможно, если процесс приостановлен.
Спасибо, теперь я понял!


А главное, я не понимаю, зачем все это нужно. Вы смотрели пример Рихтера? Он перехватывает MessageBox, ничего не приостанавливая. Что мешает сделать то же самое для CreateProcess?
Да, конечно я смотрел пример Рихтера.

Порядок выполнения команд может быть таким:

[thread1]
CreateProcess(); [thread2]
API_функция();
API_функция();
API_функция();
API_функция();
SetWindowsHookEx(...,th2);

То есть сначала thread1 выполняет CreateProcess() а потом процессор переключается на thread2 и начинает вызывать API_функции(), которые я не смогу перехватить, так как SetWindowsHookEx(...,th2) еще не будет вызван.

Keith
03.03.2005, 14:50
Глюк произошел с броузером. И должно было быть два столбика: левый - [thread1], CreateProcess();, SetWindowsHookEx(...,th2);
правый - [thread2], API_функция(); API_функция(); API_функция(); API_функция();

Eugie
03.03.2005, 16:57
Ну, тут уж ничего не поделаешь. Да, установка хука занимает какое-то время, в многозадачной среде это по определению асинхронная операция. Вас ведь не смущает тот факт, что до того, как Вы повесите свой хук, в системе уже были процессы, которые делали неперехваченные API- вызовы? Это по-простому называется 'закон обратной силы не имеет'. Причем свои собственные потоки Вы всегда можете приостановить, скажем на nnn миллисекунд, а вот чужие - далеко не все (на некоторые системные просто не хватит привилегий). Так что IMHO это неизбежные издержки метода.

PS. Удалил дубликат Вашего сообщения

Keith
03.03.2005, 18:56
Вас ведь не смущает тот факт, что до того, как Вы повесите свой хук, в системе уже были процессы, которые делали неперехваченные API- вызовы? Причем свои собственные потоки Вы всегда можете приостановить, скажем на nnn миллисекунд, а вот чужие - далеко не все (на некоторые системные просто не хватит привилегий)
Не смущает, т.к. перехватывать надо не во всех процессах, а в тех, которые создаю я. Может быть кроме CREATE_SUSPENDED можно еще как-то приостановить первичный поток, но так, чтобы вызов LoadLibrary(), требуемый для SetWindowsHookEx() выполнился?
В общем: надо выполнить код, меняющий IAT до первой команды создаваемого первичного потока, но работать это должно в 98/2000/XP.

зы Спасибо за помощь.

Hawk
18.03.2005, 11:38
А если CreateRemoteThread(..., LoadLibrary,..) сделать ? Это правда только в XP/2000 будет работать, но как мне кажется позволит без хуков внедриться в процесс и заменить таблицу импортов

Keith
18.03.2005, 15:04
98 является камнем преткновения.

RevYurMIh
30.05.2005, 01:43
В книге Рихтера "Windows для профессионалов" на проблему внедрения длл и перехвата апи ф-й выделяется целая глава, смотри там.