Comments 61
Никогда еще так не издевались над хуками, как в этом рассказе, обозвав их «крюки»…
Да ладно вам, вы когда слово «hook» читаете оно у вас как внутри переводится? Hook — это крюк и есть.
Да, но есть термины, которые лучше не переводить (а то получится 1С). А читая статью, постоянно в голове было не WinAPI, а чье-то лицо.
Вы так говорите, как будто 1С это что-то плохое
Вы не поверите, но самый изысканный мат я слышал от двух человек: от прораба на стройке за окном, когда у них кран упал, и от знакомого одинэсника при переходе с семерки на восьмерку.
Сам с 1С хоть и не работал почти (за исключением небольшого курса в колледже), но от «Битрикса» в шоке до сих пор.
Сам с 1С хоть и не работал почти (за исключением небольшого курса в колледже), но от «Битрикса» в шоке до сих пор.
И это всё потому что в 1С операторы русскими буквами называются? Я в Экселе формулы по-русски пишу и никто не умер.
Вот кстати единственная вещь которая меня крайне раздражает в экселе так это русские слова в формулах. Например долго думал как майкрософт конкатенцию обозвали, перепробовал все возможные вариации, а нет же… оказалось сцепить.
1с и битрикс имеют между собой общего только компанию 1с, которая купила компанию битрикс. А переход с семерки на восьмерку — это как переход с винапи на дотнет, и мат вашего товарища характеризует его не лучшим образом.
Применительно к IT, слово «hook», скорее, следует понимать как «ловушка», а еще лучше — как «хук» (а ля — не переводить).
Значит «ловушка», но я никогда не пойму зачем ссать и не использовать русские слова, вместо английских.
Почему «поэтому»? Вам непривычно видеть язык программирования на родном языке, потому что вы никогда с таким много не работали? Ну и что? Я в Советском Союзе родился и изучал программирование в том числе по программам на «Рапире», которые в «Науке и Жизни» печатали.
Наши специалисты, мешающие английские и русские слова звучат примерно как татары или башкиры, мешающие свой родной язык с русскими вкраплениями. Вот, послушайте пример (и мульфильм посмотрите, он стоит того, по-моему): www.youtube.com/watch?v=vTooxATVw9o
Наши специалисты, мешающие английские и русские слова звучат примерно как татары или башкиры, мешающие свой родной язык с русскими вкраплениями. Вот, послушайте пример (и мульфильм посмотрите, он стоит того, по-моему): www.youtube.com/watch?v=vTooxATVw9o
Английским языком владеет гораздо больше технически подкованных людей, чем русским. Большая часть документации пишется тоже на английском. Некоторые термины сложно перевести на русский (long double — «длинное двойное»?), а некоторые имеют несколько переводов, с которыми может возникать путаница (например, thread переводят и как «нить», но чаще как «поток», но stream — тоже «поток»).
Вдобавок у большинства современных языков программирования схожий синтаксис, и зная один, можно быстрее освоить другой. Но вот незадача — синтаксис практически у всех языков англоязычный. Русскоязычный синтаксис мало того, что придется осваивать заново, так на нем меньше людей будут писать просто потому, что они не знают русских букв. А значит, меньше людей будет работать с этим языком, меньше информации по нему в сети, выше порог вхождения.
Когда английский язык уже давно стандарт де-факто в программировании, языки программирования с иными национальными алфавитами просто не нужны.
Вдобавок у большинства современных языков программирования схожий синтаксис, и зная один, можно быстрее освоить другой. Но вот незадача — синтаксис практически у всех языков англоязычный. Русскоязычный синтаксис мало того, что придется осваивать заново, так на нем меньше людей будут писать просто потому, что они не знают русских букв. А значит, меньше людей будет работать с этим языком, меньше информации по нему в сети, выше порог вхождения.
Когда английский язык уже давно стандарт де-факто в программировании, языки программирования с иными национальными алфавитами просто не нужны.
long double — «длинное двойное»?В чём проблема? Почему нет?
Вы много букв написали, но я так и не понял почему лучше говорить на смеси русского и плохого английского, чем на русском? Всё равно эту смесь никто из англоговорящих не поймёт.
Я и не призываю переводить языки на русский, я просто не вижу в этом ничего страшного или странного.
Нет, позвольте. Если уж писать программы на русском, то давайте не забывать про спряжения, склонения и падежи. Мне искренне жаль англичан, язык которых так безобразно коверкают программы на всяких Паскалях и Бейсиках
Единственным правильным ответом на вопрос «почему нужно писать правильно, грамотно и не коверкая слова языка, на котором пишешь?» является тот факт, что такой правильно написанный текст является гораздо более удобным для восприятия другими людьми. Это единственный правильный ответ, больше нет. Все остальные ответы несколько идиотски выглядят. Самый любимый мною вариант «потому что есть правила» — чушь же. Ну какой смысл соблюдать правила того языка, который был образован благодаря многократному нарушению правил другого языка?
Так вот, фраза «поставить хук» понятна даже для меня, который в этой теме вообще не разбирается, а просто зашел топик почитать. А фраза «поставить крюк» приводит в когнитивный диссонанс.
Вон, выше был пример с железнодорожной станцией и словами «сцепить»/«конкатенировать». В отношении вагонов человеку привычно слово «сцепить». В отношении слов «конкатенировать» (это уж если мы начинаем переводить название функции на русский), в тексте же можно просто написать что-то типа «объединить», «сложить» — в общем, зависит от фантазии. Тут важно чувства контекста — интуитивное понимание, будет ли ваш перевод понятен вашей целевой аудитории.
И если переведенный кусочек текста (слово, словосочетание, может даже предложение) становится менее понятным для вашей целевой аудитории, нежели до перевода — может, ну его нахер, этот перевод? Не человек для языка, а язык для человека.
Так вот, фраза «поставить хук» понятна даже для меня, который в этой теме вообще не разбирается, а просто зашел топик почитать. А фраза «поставить крюк» приводит в когнитивный диссонанс.
Вон, выше был пример с железнодорожной станцией и словами «сцепить»/«конкатенировать». В отношении вагонов человеку привычно слово «сцепить». В отношении слов «конкатенировать» (это уж если мы начинаем переводить название функции на русский), в тексте же можно просто написать что-то типа «объединить», «сложить» — в общем, зависит от фантазии. Тут важно чувства контекста — интуитивное понимание, будет ли ваш перевод понятен вашей целевой аудитории.
И если переведенный кусочек текста (слово, словосочетание, может даже предложение) становится менее понятным для вашей целевой аудитории, нежели до перевода — может, ну его нахер, этот перевод? Не человек для языка, а язык для человека.
По-моему, хабр не место для подобного изложения информации.
UFO just landed and posted this here
А вот мне понравилось, основную мысль можно было конечно уместить в три строчки и копипаст кода. Но этот диалог я лично прочитал с удовольствием, и вынес для себя нечто полезное.
И мне понравилось. Даже представил, как советские Ватсон и Холмс обсуждают WinAPI сидя в своих огромных креслах.
Если бы хуки, не обозвали крюками, то вполне хорошо, но крюки конечно рвут шаблон.
В: Шерлок, здесь кто-то пытается объяснить, как должен выглядеть Хабр.
Ш: Школота, Ватсон, школота…
Ш: Школота, Ватсон, школота…
А мне понравился стиль изложения, и суть статьи решает конкретную техническую проблему. Если бы еще каждый раз, натыкаясь на слово «оконный крюк», подсознание не выдавало мне ассоциацию с «невозбранно жмякнуть мышою»…
А как же заключительная часть диалога:
В: Холмс, а что вы курите, раз у вас возникают такие вопросы вместо простого использования SendMessage?
Х: Ватсон, а не выкурить ли нам еще по рюмочке редмонтовского чаю?
В: Холмс, вы же знаете, что я как доктор, выступаю за здоровый кодинг.
В: Холмс, а что вы курите, раз у вас возникают такие вопросы вместо простого использования SendMessage?
Х: Ватсон, а не выкурить ли нам еще по рюмочке редмонтовского чаю?
В: Холмс, вы же знаете, что я как доктор, выступаю за здоровый кодинг.
создаст в специальном временном файле
Пайпы для этого придумали.
Да и вообще, мне кажется, можно в главном приложении локнуть какой-нибудь именованный семафор, во внедряемой либе — сразу после установки хука стартануть поток, который попытается локнуть тот же семафор, а после этого — сразу сделать UnloadLibrary. В итоге, когда нам понадобится снять хук и выгрузить либу — просто освобождаем семафор, поток в хукнутом процессе проходит заблокированную секцию кода и выгружает либу. Никаких тебе временных файлов.
Нельзя делать UnloadLibrary для той библиотеки, которую ты не загружал
Главное приложение читает через пайпу иды закрюкованных нитей и хранит их в памяти. Затем пользователь убивает его зачем-нибудь и запускает вновь. Новый экземпляр не имеет права ставить крюк, пока не убедится, что DLL выгружен из всех процессов. Как он это сделает?
Запускать чуждую нить в каждом UI-процессе на рабочем столе? Опасно. Есть шансы, пусть и небольшие, получить побочный эффект, редкий и трудноуловимый. Но это ерунда. Вы выгрузили DLL, а User32 думает, что она загружена, и вызывает её код.
Запускать чуждую нить в каждом UI-процессе на рабочем столе? Опасно. Есть шансы, пусть и небольшие, получить побочный эффект, редкий и трудноуловимый. Но это ерунда. Вы выгрузили DLL, а User32 думает, что она загружена, и вызывает её код.
Если вопрос только в том, как организовать межпроцессное взаимодействие — так для этого 150 тыщ библиотек есть. В одном вон только бусте наверное способов 5 реализовано. И всё там прекрасно разруливается и с упавшими клиентами в том числе.
Запускать чужую нить в каждом UI-процессе опасно? Ну да. А вешать хуки в каждый UI-процесс — типа нет?
Вот по поводу того, что User32 из-за своих багов будет продолжать думать, что она загружена — тут да, возразить нечего.
Запускать чужую нить в каждом UI-процессе опасно? Ну да. А вешать хуки в каждый UI-процесс — типа нет?
Вот по поводу того, что User32 из-за своих багов будет продолжать думать, что она загружена — тут да, возразить нечего.
читает через пайпу
Через трубу. Будьте последовательны.
Спасибо, я уже думал, что на мой вопрос никто не ответит. А почему SendMessage не всегда срабатывает? (По крайней мере я не смог им выгрузить библиотеку.)
Если б не Ваш вопрос, этой заметки не было бы.
SendMessage( HWND_BROADCAST)
посылает сообщения во все окна верхнего уровня. Могут существовать нити, имеющие очередь сообщений, но не имеющие окон верхнего уровня.Х. Вообразите, что наше приложение обновило себя через Интернет и перезапускается. После перезапуска окажется, что в некоторые процессы загружена старая версия DLL, а в некоторые новая. И в данном случае старая версия не выгрузится и тогда, когда через очереди пройдут сообщения.
Вот в это верится с трудом. Этож разные инстансы. Должно быть 2 хука. А что если я с одного процесса хочу 2 хука установить?
Позвольте ещё раз и подробнее:
Old.dll остался загруженным во многие процессы, My.dll загружается во вновь запускаемые процессы. Если адрес крюковой функции различается, то все процессы с Old.dll вскоре повалятся.
User32 для каждого DLL, загруженного в некоторый процесс, запоминает полный путь, который DLL имел в момент загрузки. Для Old.dll и для My.dll таковой путь одинаков
- Ставим крюк на My.dll.
- Переименовываем My.dll в Old.dll, под именем My.dll сохраняем другой DLL.
- Снимаем крюк и сразу ставим снова (не важно, перезапускаем EXE или нет). Новый крюк нацелен на новый My.dll.
Old.dll остался загруженным во многие процессы, My.dll загружается во вновь запускаемые процессы. Если адрес крюковой функции различается, то все процессы с Old.dll вскоре повалятся.
User32 для каждого DLL, загруженного в некоторый процесс, запоминает полный путь, который DLL имел в момент загрузки. Для Old.dll и для My.dll таковой путь одинаков
Спасибо за разъяснения, я не подумал про переименование уже загруженного модуля. Разве такая операция на всех файловых системах и более старых ОС возможна? Раньше же вроде нельзя было переименовать загруженный модуль… а сейчас попробовал, можно. Во всяком случае загруженные модули я даже и не думал переименовывать… как то это неправильно что ли.
Речь, конечно, о тех DLL, которые User32 загружает сам – в ответ на вызов SetWindowsHookEx.
Если установить два крюка, нацеленные на My.dll, то в «старых» процессах оба будут нацелены на Old.dll.
Экземпляры User32, работающие в «старых» процессах, думают, что уже загруженный Old.dll это и есть My.dll.
Если установить два крюка, нацеленные на My.dll, то в «старых» процессах оба будут нацелены на Old.dll.
Экземпляры User32, работающие в «старых» процессах, думают, что уже загруженный Old.dll это и есть My.dll.
Замечание по поводу разных команд, которые писали user32 и kernel32, не совсем корректное. Очевидно же, что механизм оконных хуков уходит корнями глубоко в недра ядра, а точнее win32k.sys. Я писал об этом очень давно ещё на wasm'е. Сейчас он, правда, в дауне, но копия статьи сохранилась: http://last-soft.ucoz.ru/publ/10-1-0-7
Так же замечу, что библиотеки с хуками не только не сразу выгружаются из всех процессов, но и не сразу подгружаются. Все эти действия происходят во время выполнения CallNextHookEx() или DispatchMessage(). Такова уж архитектура Windows, тут нечего пенять на криворукость разработчиков. Если нужно обновить библиотеку, содержащую обработчик хука, то самым корректным и рекомендованным способом будет перезагрузка системы. Вы же не пытаетесь изобрести подобные костыли, когда дело касается обновления драйверов?
Так же замечу, что библиотеки с хуками не только не сразу выгружаются из всех процессов, но и не сразу подгружаются. Все эти действия происходят во время выполнения CallNextHookEx() или DispatchMessage(). Такова уж архитектура Windows, тут нечего пенять на криворукость разработчиков. Если нужно обновить библиотеку, содержащую обработчик хука, то самым корректным и рекомендованным способом будет перезагрузка системы. Вы же не пытаетесь изобрести подобные костыли, когда дело касается обновления драйверов?
Пакеты обновления устанавливаются без перезагрузки (как правило) для: MS SQL, MS Office, Visual Studio,… Все веб-браузеры обновляются без перезагрузки. Даже и для некоторых драйверов новые версии устанавливаются без перезагрузки.
На этом фоне наша маленькая утилита потребовала перезагрузки машины. Что о нас подумал пользователь?
На этом фоне наша маленькая утилита потребовала перезагрузки машины. Что о нас подумал пользователь?
Я писал об этом очень давно ещё на wasm'е.
Холмс. Конечно читал, сэр! И утилитой Hooks пользуюсь. Кстати, — как повезло, что я Вас встретил, — нельзя ли реализовать сортировку по столбцам? Простите уж, недосуг осваивать Дельфи самому.
И утилитой Hooks пользуюсь.
А можно линк на утилиту в студию? Спасибо.
Все линки мёртвые, судя по всему. Если дома остались сорцы, то выложу куда-нибудь.
Сортировку по столбцам может быть реализую, но не обещаю, т.к. на Делфи уже давно ничего не писал и она на Линуксе не установлена.
Сортировку по столбцам может быть реализую, но не обещаю, т.к. на Делфи уже давно ничего не писал и она на Линуксе не установлена.
Вот, пожалуйста, утилита и сорцы: hooks_inside.zip.
То что они подгружаются не сразу — это очень разумно, пользователь не замечает этой подгрузки, а стартуй они все сразу — мб система подвисала бы на некоторое время.
Sign up to leave a comment.
Разрегистрация оконного крюка