tag
Гость
|
|
« : 25-11-2005 08:34 » |
|
Создаю хук для собирания всех сообщений мыши и клавиатуры. Работает! Но есть проблема, что вдруг все данные в хуковой DLL обнуляются, а через некоторое время вновь восстанавливается. Интуитивно я понимаю, что происходит новый вызов DLL и данные обнуляются, т.к. это другая копия, и что можно создать расшаренные данные разных DLL (#pragma data_seg). Но проблема в том, почему и когда происходит вызов новой DLL??? Помогите разобраться
|
|
« Последнее редактирование: 08-07-2007 17:02 от Алексей1153++ »
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #1 : 25-11-2005 10:23 » |
|
Вдруг ? это как понять? она у тя собирает данные, пишет в файл, (как я понимаю), и затем буфер (тот который расшарен) заполняется снова и снова и снова. Как он может обнулится "случайно" я понять не могу... Если это обнуление вызвано выгрузкой ДЛЛ, то держи её всегда открытой в некой программе. Или сделай её системной ДЛЛ, она тогда будет подгружаться вместе с виндой и выгружаться тоже.
Вызов новой ДЛЛ ?? не твоей чтоли? тогда причём тут твоя ДЛЛ? Если ты имеешь ввиду когда некий процесс обращается к твоей ДЛЛ (при хуке происходит частенько) то это можно отловить DLL_PROCESS_ATTACH и DLL_PROCESS_DETACH (соотв) в DllEntry функции. Код и данные ДЛЛ подгружаются заново только тогда этой ДЛЛ нету физически в памяти.
|
|
« Последнее редактирование: 25-11-2005 10:28 от acc15 »
|
Записан
|
|
|
|
tag
Гость
|
|
« Ответ #2 : 25-11-2005 11:36 » |
|
В том-то и дело, что расшаренных данных нет - не предполагается, что ДЛЛ будет вызываться вновь. А получается, что что-то ее вызывает: или моя программа (не должна - ставил блокиратор, проверял - не запускает) или что-то иное ее подгружает? Вопрос: при использовании такой ДЛЛ предполагается вообще доступ к ней других процессов? Может это норма, а я парю себя и всех! И второе, ДЛЛ делается в MFC. Может быть тут тоже грабли?
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #3 : 25-11-2005 12:01 » |
|
Вопрос: при использовании такой ДЛЛ предполагается вообще доступ к ней других процессов? Может это норма, а я парю себя и всех! При использовании хука именно он и предполагается... Ибо вызов идёт от процесса которому поступило сообщение (любое, мышиное, клавиатурное, системное... любое) К примеру когда у тя открыт блокнот ты жмёшь там кнопку, сообщение о нажатой кнопке идёт процессу. потом этот процесс (блокнот) вызывает хуковую процедуру ИЗ ТВОЕЙ ДЛЛ. и хуковая процедура уже решает что собственно делать с этим сообщением. вернуть процессу на обработку или сделать нечто подлое )) Именно поэтому глобальный хук должен быть в длл, а не в екзешнике. Кстати про расшаренные данные, там прикол один есть, пробовал сделать короче расшареную структуру примерно такого содержания typedef union { struct { WORD a:5; WORD b:5; WORD c:6; }; WORD x; } XXX; странно как-то но они никак не делились, каждый процесс обращавшийся к этим данным имел собственную копию сей структуры. Когда сделал просто расшаренное слово (WORD) тогда всё заработало... Я к тому что учти это тоже, т.к. мало ли. }
|
|
« Последнее редактирование: 25-11-2005 12:11 от acc15 »
|
Записан
|
|
|
|
tag
Гость
|
|
« Ответ #4 : 25-11-2005 12:39 » |
|
Спасибо, учту! Но все же, равзе не один только процесс может вызвать хуковую процедуру, HWND окна которого мы передаем в SetWindowHookEx
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #5 : 25-11-2005 16:22 » |
|
какой хэндл окна? HHOOK SetWindowsHookEx( int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId ); где ты тут увидел хэндл окна??? равзе не один только процесс может вызвать хуковую процедуру длл-ные функции могут быть вызваны когда угодно и кем угодно
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #6 : 25-11-2005 18:27 » |
|
При возникновении хукового события в каком либо процессе он подгружает хуковую dll в адресное пространство своего процесса. Поэтому данные, которые вы передаете своей dll действуют только в адресном пространстве своего приложения, в другом процессе будет происходить инициализация dll и естественно обнуление данных. Как вариант - для передачи данных между вашим приложением и экземплярами dll подгруженных в другие процессы использовать файловое отображение в память (маппинг).
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #7 : 26-11-2005 06:17 » |
|
Нет. Подгружаются только данные и то только тогда когда они не расшарены, код загружается только один раз.
|
|
|
Записан
|
|
|
|
tag
Гость
|
|
« Ответ #8 : 26-11-2005 10:45 » |
|
MSDN рядом нет поэтому вопрос: DWORD dwThreadId - чего его нулем нужно задавать? А то в примерах так пишут, интуитивно понимаю из-за того, что хук глобальный и не принадлежит какому-то конкретному процессу???
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #9 : 26-11-2005 10:58 » |
|
dwThreadId
Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
tag
Гость
|
|
« Ответ #10 : 26-11-2005 11:16 » |
|
Какой я догадливый В принципе ошибка понятна, почему сбрасывались данные - какой-то поток вызвал ДЛЛ заново, данные не были расшарены и обнулялись. В момент возврата к исходному потоку данные возвращались. Решение одно - расшаривать данные!
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #11 : 27-11-2005 18:34 » |
|
Данные не обнулялись они просто не были расшарены. Каждый процесс имел свой экземпляр данных...
|
|
|
Записан
|
|
|
|
tag
Гость
|
|
« Ответ #12 : 29-11-2005 11:06 » |
|
Появилась другая проблема - надо расшарить массив, а расшаривается только место под указатель. Как быть?
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #13 : 29-11-2005 19:40 » |
|
Если ты хочешь расшаренный динамический массив в этом случае используйтолько File Mapping... http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dngenlib/html/msdn_manamemo.aspсам я в этом не силен... потому что никогда не доводилось использовать,т.к. обходные пути всегда есть... можешь вместо динамического массива использовать обычный...расшарь 100 кб сразу и вот тебе динамический массив )))... и не забывай один важный момент. Расшаренные данные должны ОБЯЗАТЕЛЬНО быть проинициализированны... если всё равно не делятся то сделай статический массив (static DWORD xyz[1000]={0}; )
|
|
« Последнее редактирование: 29-11-2005 19:57 от acc15 »
|
Записан
|
|
|
|
tag
Гость
|
|
« Ответ #14 : 30-11-2005 13:56 » |
|
с инициализацией получается, но зачем делать локальные массивы, которые не будут делиться, статическими?
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #15 : 30-11-2005 14:01 » |
|
статическая переменная или массив инициализируются только один раз в момент загрузки программы... т.е. если ты сделаешь статический локальный массив он будет работать как глобальный... ограничение лишь составит поле видимости этого массива...
пример: DWORD calltest() { static DWORD callcount=0; return ++callcount; }
данная функция будет считать сколько раз она была вызвана... т.е. callcount проинициализируется только 1 раз. память под эту переменную будет выделена только 1 раз. тоже самое и с массивами... таким путем можно избегать использование глобальных переменных...
|
|
« Последнее редактирование: 30-11-2005 14:09 от acc15 »
|
Записан
|
|
|
|
tag
Гость
|
|
« Ответ #16 : 30-11-2005 14:23 » |
|
А, ну, это понятно . В этом смысле static влияет на сохраняемость данных. Главное, что это не влияет на работу хука. Без этого можно в принципе обойтись. В общем пока все работает, но тему пока закрывать не буду - вдруг появятся вопросы!
|
|
|
Записан
|
|
|
|
|