Хук на HCBT_CREATEWND |
Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.
Хук на HCBT_CREATEWND |
Unconnected |
14.09.2010 21:34
Сообщение
#21
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
У меня почти то же самое было, только это работает)) Я понял, надо было в основной программе сразу писать процедуру из exports, без всяких name 'CBTProc'.. Большое спасибо Всё чаще, когда у меня какой-то затык, я лезу смотреть созданные мною темы..))
Кстати, чтобы не таскать с собой отдельно dll - только извлекать из ресурсов в нужный момент? Прилинковать как-нибудь нельзя? -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
14.09.2010 22:01
Сообщение
#22
|
Гость |
Цитата Прилинковать как-нибудь нельзя? Можно (через Project->Resources->New->User Data, а потом - извлекать через TResourceStream + SaveToFile), но не нужно. Спокойная жизнь надоела? Хочется слышать матюгание антивирусов? |
Unconnected |
15.09.2010 10:49
Сообщение
#23
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Простенький ксор перед добавлением в ресурсы, и после извлечения обратная операция - помогают И потом такая тишина..)
-------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
Unconnected |
15.09.2010 15:43
Сообщение
#24
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Ещё вопрос, относительно "обратной связи". Мне в основной программе нужно узнавать, как там дела у ловушки, что она поймала и т.п. Но т.к. я не нашёл приём экспортирования переменных (наверное, этого вообще нельзя делать), то написал функцию, которая возвращает значение переменной. Так:
Function retb:integer;stdcall Переменная b:integer=0; , описана глобально, когда ловушка что-то ловит - b присваивается число. В основной программе: function retb:byte; stdcall; external mydlname; Регистр названий одинаковый. В главной программе в таймере запрашиваю значение retb (интервал 100мс), но оно почему-то всегда равно 0, даже когда точно известно, что ловушка сработала.. -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
15.09.2010 17:28
Сообщение
#25
|
Гость |
Цитата Переменная b:integer=0; , описана глобально, когда ловушка что-то ловит - b присваивается число. Ага, размечтался Вот здесь посмотри, как возвращать данные из DLL в приложение: http://www.mustangpeak.net/hooks.htm (там внизу прилеплен архив с примером, который работает с MMF - Memory Mapped Files). Сегодня вечером поменяю видеоплату на своем компьютере (уже купил наконец-то ), тогда будет проще, начнется не теоретический разговор, а практический... |
Unconnected |
15.09.2010 17:43
Сообщение
#26
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
офигеть, из-за одной переменной столько кода непонятного! Неужели не предусмотрено что-то попроще? (хотя, гугл намекает, что нет). Может, можно описать во входных параметрах SetHook(var b:integer), а потом, в процедуре, присваивать? (да, так не нужно писать программы))
Вообще, самый элегантный метод - использовать txt в качестве посредника) Сработало - создал, принял - удалил.. -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
15.09.2010 22:22
Сообщение
#27
|
Гость |
Цитата Вообще, самый элегантный метод - использовать txt в качестве посредника) Сработало - создал, принял - удалил.. Угу. Если получилось - удалил, ты имеешь в виду? Можно, конечно, и TXT-файлами пользоваться для обмена информацией. Но ты для начала задачу озвучь, что именно нужно тебе получать? Сколько окон было заблокировано? Сколько раз вообще вызывалась ловушка? Что именно? Может, найдем и более красивое решениеP.S. (Показать/Скрыть)
|
Unconnected |
15.09.2010 22:28
Сообщение
#28
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Цитата Сколько окон было заблокировано? Сколько раз вообще вызывалась ловушка? Устанавливается один раз, в библиотеке массив из 5 элементов с идентефикаторами программ, нужно просто в момент отлова неугодного окна сообщать об этом основной программой, в виде переменной с её (программы) индексом. Со строками, как мне обещали мануалы, проблем нет. По крайней мере, окна нормально определяются по строкам из массива. А вот текстовик что-то не создаётся, а messagebox появляется только наполовину - звуком, само окошко не показывается) По-моему, здесь способ с текстовиком самый оптимальный. Именно потому, что я буду проверять в таймере его существование, а существовать он будет только при срабатывании ловушки. А почему может не получиться удалить? Права? У меня туда манифест вшит, для UAC Сообщение отредактировано: Unconnected - 15.09.2010 22:30 -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
15.09.2010 22:54
Сообщение
#29
|
Гость |
Если нужно просто возвращать индекс заблокированного окна, вот тебе еще один способ, навскидку (не тестировал, но явных причин не работать - не вижу, да и получше будет, чем с txt-файлами). У тебя ж хендл твоего окна не меняется после того, как ты хук установил? Вот в SetHook передавай хендл своего окна (главного окна приложения, либо какой-то формы, я не знаю, что там у тебя), а при блокировке приложения ловушкой - PostMessage этому окну, "так мол и так - заблокировано приложение <и информация о нем>", а в оконной функции своего приложения лови эти сообщения и обрабатывай как нужно. Лучше будет, чем с текстовыми файлами, да еще по таймеру заморачиваться. К таймеру бы вообще привязываться не надо.
|
Unconnected |
15.09.2010 23:39
Сообщение
#30
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Вот так шлю:
const wm_user=$0400; //в библиотеке эта константа почему-то была undeclared, юнит windows есть Ловлю: function TForm1.KOLFormMessage(var Msg: tagMSG; Так надо? В KOL, кстати, очень удобная система работы с сообщениями, всё в одном обработчике. -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
15.09.2010 23:58
Сообщение
#31
|
Гость |
Цитата +50000 взял, чтоб наверняка попасть в [0xC000 ; 0xFFFF]. Это еще зачем? MSDN явно говорит:Цитата Message numbers in the fourth range (0xC000 through 0xFFFF) are defined at run time when an application calls the RegisterWindowMessage function to retrieve a message number for a string. All applications that register the same string can use the associated message number for exchanging messages. The actual message number, however, is not a constant and cannot be assumed to be the same between different sessions. Ты регистрировал сообщения через RegisterWindowMessage?Я б на твоем месте все-таки использовал интервал WM_USER .. 0x7FFF, ты же фактически из своей библиотеки посылаешь сообщение своему же приложению, то есть, никаких разночтений возникнуть не должно. Вот если будешь посылать чужому приложению - тогда да, надо договариваться, что это сообщение означает... Посылай postmessage(whan, WM_USER + 1, i, 0); |
Unconnected |
16.09.2010 15:02
Сообщение
#32
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Очевидное-невероятное, блин! Передаю в sethook хэндл:
procedure SetTheHook(h:hwnd); stdcall; Смотрю в этой процедуре h - всё верно, совпадает с хэндлом формы, параметр был передан. whan (whan:hwnd, описана глобально), соответственно, присвоено значение h. Это если смотреть сразу после присваивания, в Sethook (я смотрел путём вывода в текстовик). Но в процедуре CBTProc почему-то whan всегда равна нулю!!! На локализацию этой фигни я угрохал полдня )) (зато теперь знаю, что прототип функции действительно лучше не менять)). И вот сейчас сижу и думаю, почему глобальная переменная в одном месте нормальная, а в другом - нулевая.. Значение whan в библиотеке ТОЧНО нигде не трогается, уже всё обсмотрел.. Сообщение отредактировано: Unconnected - 16.09.2010 15:16 -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
16.09.2010 15:31
Сообщение
#33
|
Гость |
В общем, если не хочешь потерять еще три дня, и потом все-таки вернуться к тому, что я тебе написал в сообщении №25 - вернись сейчас. ТОЛЬКО MMF гарантируют тебе работу. Память должна быть общей (shared memory). Вот тебе еще один пример: Сайт из гуглокэша (начиная со слов "this is real working example". Проверено, действительно работает). Больше прописные истины повторять не буду. Хочешь экспериментировать - экспериментируй. Как надоест - скажешь.
|
Unconnected |
16.09.2010 17:06
Сообщение
#34
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Короче на данный момент я остановился на текстовике. Логика программы предполагает, что если она вообще работает, то текстовик хватит прав создать... Просто из-за одной переменной добавлять (и разбирать) кода столько, сколько наверное во всей программе нет - нерационально как-то, что ли.. Наверное, я ещё вернусь к этой теме, когда будет "рациональней"..
volvo, ещё раз спасибо за советы, без них я бы тут далеко не уехал И всё же как-то странно, зачем нужна возможность создания глобальных переменных в dll, если такие дела с ними.. Сообщение отредактировано: Unconnected - 16.09.2010 17:07 -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
16.09.2010 17:21
Сообщение
#35
|
Гость |
Цитата Просто из-за одной переменной добавлять (и разбирать) кода столько, сколько наверное во всей программе нет - нерационально как-то, что ли.. Смотри, как выглядит DLL с расшаренной памятью:library myhook;Сколько кода добавлено? 10 строк? Если что - вот VCL-ный проект, который ставит хук и получает сообщение о том, что окно было заблокировано (проект с DLL-кой тоже вложен): hook_test.zip ( 73.85 килобайт ) Кол-во скачиваний: 397 |
Unconnected |
17.09.2010 15:15
Сообщение
#36
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Кажется понял, в библиотеке просто делается указатель на одну общую структуру, и какие-то пассы при инициализации)
Спасибо, сделал по-человечески) Только такой способ кажется не подходит для динамической подгрузки DLL? Делаю так:
, и хэндлы внутри библиотеки опять обращаются в нули... Сообщение отредактировано: Unconnected - 17.09.2010 15:15 -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
17.09.2010 15:34
Сообщение
#37
|
Гость |
Цитата Только такой способ кажется не подходит для динамической подгрузки DLL? Вообще-то DLL-ке все равно, как ее подгружают, хоть загрузкой процесса, хоть LoadLibrary - в любом случае работает ветка DLL_PROCESS_ATTACH. А вот чего ты творишь в программе - непонятно. Ты DLL отключаешь (FreeLibrary) ГДЕ? Сразу после того, как адреса процедур получил? Ну-ну... Добавлено через 5 мин. P.S. Только что подключил через LoadLibrary: Procedure loadlib;Работает, зараза |
volvo |
17.09.2010 18:34
Сообщение
#38
|
Гость |
Все-таки решил добавить. Интересная и познавательная информация о написании своих DLL:
Несколько причин, чтобы не делать ничего страшного в своей DllMain , и по ссылкам оттуда: DllMain и жизнь до родов DllMain - страшилка на ночь Ещё причины, почему не надо делать ничего страшного в DllMain: случайная блокировка |
Unconnected |
17.09.2010 19:22
Сообщение
#39
|
mea culpa Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: 24 |
Цитата Ты DLL отключаешь (FreeLibrary) ГДЕ? Блин, ковырялся с дллами - и заснул) И как я её только не отключаю (-ал) Насколько понимаю, после FreeLibrary библиотека должна исчезнуть из памяти, чтобы предоставить возможность удалить саму dll. Но она что-то такой возможности не представляет, даже после завершения программы. Более того, происходит такая странная вещь - dll даёт себя удалить где-то через минуту.. Я сначала думал, что это связано с использованием string, позаменял все string на shortstring (длиннее 255 символов строк нет там), - не помогло. Читаю Гансмокера. Кажется, затянется - в каждой статье куча перекрестных ссылок) Говорит, использование хуков при блокировке загрузчика ОС приведёт к катастрофе) -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
volvo |
17.09.2010 20:37
Сообщение
#40
|
Гость |
Цитата Насколько понимаю, после FreeLibrary библиотека должна исчезнуть из памяти, чтобы предоставить возможность удалить саму dll. Но она что-то такой возможности не представляет, даже после завершения программы. Вот ты будешь смеяться, но:Unit1.pas ( 1.88 килобайт ) Кол-во скачиваний: 353 прекрасно удаляет ту самую DLL-ку, которая была в прошлом проекте, только теперь она запихана в ресурсы и появляется в папке только при старте программы. После завершения - исчезает (нет, нет, не через минуту - я б столько не прождал ). Что-то у тебя DLL не то делает, или ты мудришь с ее загрузкой. Откуда там взялись уже строки? Цитата И как я её только не отключаю (-ал) А не надо ее "как только не отключать". Надо помнить, что каждый LoadLibrary или статическое подключение - это (+1) к счетчику ссылок, а каждое завершение процесса (при статическом подключении) или FreeLibrary - это (-1). До тех пор, пока счетчик этот не станет = 0, DLL выгружена не будет. |
Текстовая версия | 25.09.2024 18:48 |