Бокс – это один из самых популярных видов единоборств в мире. Сам по себе бокс ограничен рядом правил: удары только кулаками и обязательно в перчатках, наносить удары можно только в переднюю часть туловища до пояса или в голову. Вследствие данной ограниченности техника и тактика бокса постоянно прогрессирует.
Очень много элементов из других восточных единоборств, например, муай тай, кудо, уже позаимствовано боксом. Бокс можно разделить на два лагеря – техника защиты и нападения. В данной статье мы с вами узнаем название основных ударов в боксе и рассмотрим более подробно технику нападения – постановки ударов, которая используется в классической школе профессионального бокса.
Основные виды ударов в боксе
Хук
Хук (крюк) – это короткий боковой удар, который наносится правой или левой согнутой в локте на 90 или 100 градусов рукой. Более эффективен хук на средних и ближних дистанциях, при этом удары направляются в голову или корпус соперника. Хук не считается скоростным ударом, поскольку имеет большую траекторию, но этот недостаток компенсируется мощностью нанесения удара.
Сила удара в основном формируется за счет поворота корпуса и переноса центра тяжести. Основной задачей данной техники – одержать победу досрочно. Одиночные хуки будут малоэффективны без грамотной комбинации ударов. Сам по себе хук – очень опасный и нокаутирующий удар, но технически очень сложный, так как требует от боксера особой точности и своевременности нанесения.
Джеб
Джеб – это левый прямой удар в голову или туловище, при этом рука должна полностью разгибаться. Джеб не является самым сильным ударов в боксе, но считается одним из самых основных ударов в арсенале боксера. Он является скоростным ударом, поскольку траектория из всех ударов в боксе у него самая короткая. Джеб направлен на выполнение функции «разведка» — в поиске уязвимого места соперника. Кроме того, он помогает держать дистанцию, измерить расстояние для выхода на удобное для себя положение, чтобы подготовиться к атаке и нанести тяжелые и акцентированные удары.
Таким образом, этот удар помогает держать соперника постоянно в напряжении, некая дезориентация под «градом» несильных, но частых и молниеносных атак. Джеб также хорошо помогает в качестве защитного действия, так как он замедляет продвижение соперника вперед.
Апперкот
Апперкот наносится снизу вверх согнутой рукой. Апперкот бывает классический, длинный и боди-апперкот. Классический апперкот используется на ближней дистанции передней рукой, а на средней и дальней дистанции более уместен длинный апперкот дальней рукой. При классическом апперкоте на момент удара предплечье должно быть расположено вертикально. При длинном апперкоте удар наносится «от пола», что делает этот удар непредсказуемым.
Боди-апперкот – при ударе ладонная часть кулака развернута вверх. По силе и эффективности апперкот уступает только боковым ударам, а по скорости и траектории сопоставим со свингом. Все виды апперкота очень эффективны для атак и контратак.
Кросс
Кросс – это правый прямой удар в голову или туловище, является одним из самых сильных ударов в боксе. Этот удар имеет длинную траекторию полета руки, чем и обусловлена его мощь. Кросс – это основное оружие боксера-накаутера. Удар наносится очень резко с одновременным толчком задней ноги и движением туловища вперед, при этом весь вес переносится на переднюю ногу. Исполняют кросс, как правило, в голову, как завершающий в серии. Эффективность этого удара напрямую связано с целым комплексом «ложных» ударов – джебами и передней руки.
Необходимо отметить, что победу в боксе приносит не самый сильный или быстрый удар, а своевременный и правильный. Одной техники в этом виде спорта мало, необходима еще стратегия и тактика ведения боя. Поэтому каждому приему свое время, когда он будет уместен.
avtor: Максим Шевин, для сайта super-mens.ru
super-mens.ru
Хуки — это технология перехвата вызовов функций в чужих процессах. Хуки, как и любая достаточно мощная технология, могут быть использованы как в благих целях (снифферы, аудиовидеограбберы, расширения функционала закрытого ПО, логирование, багфиксинг) так и со злым умыслом (трояны, кряки, кейлоггеры). О хуках уже не раз писали и на Хабре и не на Хабре. Но вот в чём беда — почему-то каждая статья о хуках буквально со второго абзаца начинает рассказывать о «таблице виртуальных функций», «архитектуре памяти» и предлагает к изучению огромные блоки ассемблерного кода. Известно, что каждая формула в тексте снижает количество читателей вдвое, а уж такие вещи — так и вовсе вчетверо. Поэтому нужна статья, которая расскажет о хуках просто. Под катом нет ассемблера, нет сложных терминов и буквально два десятка строк очень простого кода на С++. Если вы давно хотели изучить хуки, но не знали с чего начать — начните с этой статьи.
Реальная задача
Для лучшего понимания того, что мы делаем — поставим себе какую-нибудь реальную задачу. Давайте, например сделаем так, чтобы браузер Firefox при заходе на Хабр писал в своём заголовке «Привет, Хабр!» вместо того, что там пишется сейчас (а сейчас там пришется "*** / Хабрахабр — Mozilla Firefox", где *** — меняется в зависимости от раздела). Да, я знаю, что это можно сделать правкой исходников Firefox, браузерными плагинами, юзерскриптами и еще десятком способов. Но мы в учебных целях сделаем это хуками.
Совсем чуть-чуть теории
Когда Вы запускаете любое приложение — операционная система создаёт его процесс. Грубо говоря, exe-файл копируется в память, далее определяется какие именно библиотеки (dll-файлы) ему нужны для работы (эта информация записана в начале каждого exe-файла), эти библиотеки ищутся (в папке с программой и в системных папках) и загружаются в память процесса. Потом определяется, какие именно функции библиотек использует программа и где они находятся (в какой библиотеке и где именно в этой библиотеке). Строится табличка вида «функция SomeFunction1() — библиотека SomeLibrary1.dll — %адрес_функции_SomeFunction1()%». Когда программе понадобиться вызвать эту функцию — она найдет в своей памяти нужную библиотеку, отсчитает нужный адрес и передаст туда управление.

Суть хукинга — заставить программу поверить, что нужная ей функция находится в другом месте.
Делается это таким образом — мы пишем свою библиотеку SomeLibrary2.dll, в которой будет находится наша функция SomeFunction2(). Далее мы загружаем эту библиотеку в память чужого процесса (в ОС Windows есть специальная функция для этого) и изменяем ту самую табличку, о которой я писал чуть выше, так, чтобы теперь она содержала запись «функция SomeFunction1() — библиотека SomeLibrary2.dll — %адрес_нашей_функции_SomeFunction2()%». Для того, чтобы понять, как вручную сделать всё описанное в этом абзаце, нужно знать весьма прилично всего — как устроена память в Windows, как вызываются функции, как им передаются аргументы и т.д. Это сложно. Ну на самом деле не очень, просто можно обойтись и без этого. Если вам это нужно — почитайте какую-нибудь продвинутую статью (а хоть бы из тех, что указаны в начале). Мы пойдем другим путем — используем готовую библиотеку Microsoft Detours, которая сделает всю грязную работу за нас.
Пару слов о Microsoft Detours
Проста в изучении и использовании
Весьма эффективна





Закрыта
Стоит приличных денег для коммерческого использования или х64-архитектуры
В целом, я бы посоветовал начинать изучение хуков именно с Detours — если это будет всего лишь вашим разовым развлечением, то этого вполне хватит, у вас быстро всё получится и вам понравится. Если же хуки понадобятся в серьёзном проекте — вы легко переключитесь на бесплатные и открытые (но чуть более сложные) библиотеки типа mhook, купите Detours или напишете свой велосипед (для последних двух решений нужны весьма веские причины).
О том где взять и как собрать Detours я писал вот тут.
Хитрый план
- Понять, на какую функцию ставить хук.
- Сделать свою библиотеку с функцией, которая будет заменять исходную и делать нужные нам вещи.
- Установить хук (загрузить библиотеку в память нужного процесса и переставить указатель на нужную нам функцию).
- PROFIT!
Куда ставить хук
MSDN весьма ясно намекает нам, что заголовок окна можно установить функцией SendMessage — при этом вторым параметром должно быть передано WM_SETTEXT, а последним — сам текст. Но тут могут быть нюансы:
- Вместо SendMessage может использоваться PostMessage или что-то еще
- SendMessage может быть вообще не функцией, а макросом, ссылающимся на другую функцию (в дальнейшем мы увидим, что так оно и есть)
- Firefox, как некоторые кроссплатформенные приложения, может вообще не использовать функции Windows для рисования стандартных элементов окна, используя вместо этого какие-то собственные кросплатформенные элементы GUI (к счастью, это не так — но вдруг!)
Так что нужно всё хорошенько проверить. Нам поможет прекрасная бесплатная программа API Monitor. Она позволяет присоединиться к определенному процессу и подсмотреть, какие именно функции он вызывает и с какими параметрами. Вы, может быть, уже догадались — делает она это тоже с помощью хуков. Итак запускаем Firefox и API Monitor. Первым делом в API Monitor нужно указать фильтр — какую именно группу функций мы хотим мониторить. Если выберем вообще всё — исследуемая программа будет работать очень медленно (а может даже зависнет), выберем слишком мало — упустим нужное. Поэтому тут придётся думать и выбрать лишь ту группу, где потенциально могут находится функции работы с элементами GUI Windows. Давайте выберем группы Graphics и Windows Application UI Development а в панели Running Processes дважды кликнем по нашему Firefox. Начиная с этого момента API Monitor в панели справа будет показывать вызовы всех API-функций и их параметры.
Переходим в Firefox, открываем Хабр, дожидаемся изменения заголовка на нужный и возвращаемся в Api Monitor чтобы остановить мониторинг. Скорее всего, вы будете удивлены количеством вызванных функций — их могут быть сотни тысяч буквально за несколько секунд мониторинга. А мы ведь еще и следим далеко не за всем. Да-да, это всё реально происходит внутри безобидного открытия всего одного сайта в браузере! А вы еще жалуетесь, что эта пара секунд — слишком долго. 🙂
Найти нужную нам функцию поможет поиск по вкладке с результатами мониторинга. Вбиваем в поиск «WM_SETTEXT» и убеждаемся, что действительно имеются вызовы функции SendMessageW с этим параметром — с высокой вероятностью это и есть установка заголовка окна. Обратите внимание на «W» в конце названия функции — оно означает, что используется её юникодная версия. Для установки хуков важно знать точное имя подменяемой функции и теперь мы его знаем.
Делаем свою библиотеку
1. Запускаем Visual Studio.
2. Создаём новый проект: File->New->Project. Тип Visual C++ -> Win32 -> Win32 Project. В диалоге создания проекта указываем тип «Dll».
3. Открываем файл dllmain.cpp и пишем туда вот такой код:
#include <windows.h> #include "C:Program FilesMicrosoft ResearchDetours Express 3.0srcdetours.h" LRESULT (WINAPI * TrueSendMessageW)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) = SendMessageW; __declspec(dllexport) LRESULT WINAPI MySendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { if (Msg == WM_SETTEXT && wcsstr((LPCTSTR)lParam, L"/ Хабрахабр - Mozilla Firefox") != NULL) return TrueSendMessageW(hWnd, Msg, wParam, (LPARAM)L"Привет, Хабр!"); return TrueSendMessageW(hWnd, Msg, wParam, lParam); } BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) { if (dwReason == DLL_PROCESS_ATTACH) { DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)TrueSendMessageW, MySendMessageW); DetourTransactionCommit(); } else if (dwReason == DLL_PROCESS_DETACH) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)TrueSendMessageW, MySendMessageW); DetourTransactionCommit(); } return TRUE; }
4. Открываем свойства проекта и на вкладке настроек линкера добавляем в поле Additional Dependencies значение «C:Program FilesMicrosoft ResearchDetours Express 3.0lib.X86detours.lib». Внимание, у вас путь может быть другой — смотря куда установили библиотеку Detours.

5. Компилируем проект: Build -> Build Solution. На выходе получаем длл-ку (пусть будет называться hooktest.dll)
Давайте разберем исходник. В начале мы подключаем заголовочные файлы Windows (чтобы пользоваться функцией SendMessageW) и Detours (чтобы иметь возможность ставитьснимать хуки).
В сложной на первый взгляд строке №3 мы всего лишь сохраняем реальный указатель на функцию SendMessageW в переменную TrueSendMessageW. Это нам понадобиться для двух целей:
- Для вызова настоящей функции SendMessageW из нашей «подделки».
- Для восстановления указателя на реальную функцию в момент, когда мы захотим снять хук.
Далее идет наша поддельная функция MySendMessageW. Она предельно проста. Если попалось сообщение WM_SETTEXT и в его тексте есть упоминание Хабра — заменяем его на своё. Иначе — работаем как прозрачный прокси. Обратите внимание на префикс __declspec(dllexport) — он нужен чтобы этой функцией смогли воспользоваться другие процессы.
Функция DllMain вызывается операционной системой в определенных случаях — например, в моменты аттачадетача библиотеки к процессу. Тут тоже всё просто. В момент аттача нам нужно установить хуки, в момент детача — снять. Библиотека Detour требует делать это транзакциями, и в этом есть смысл — представьте себе что будет, если сразу несколько желающих захотят поставить хуки в один процесс. Самое важное в этом коде это строка
DetourAttach(&(PVOID&)TrueSendMessageW, MySendMessageW);
Именно она заставляет процесс «поверить» что теперь вместо настоящей функции SendMessageW нужно вызывать нашу MySendMessageW. Ради этой строки всё и затевалось. Если кому интересно, однажды я писал аналог этой функции вручную. С учетом всех возможных комбинаций типов функций и архитектур это заняло у меня несколько недель. Вы вот только что их сэкономили — поздравляю.
Устанавливаем хук
Microsoft Detours предлагает разные варианты установки хуков — мы воспользуемся самым простым. В комплекте примеров, которые идут с библиотекой, есть программа withdll.exe — она принимает в качестве параметров путь к приложению и библиотеку, которую нужно подгрузить в память этого приложения после его запуска. Запускаем всё это как-то вот так:
withdll.exe -d:hooktest.dll "C:Program FilesMozilla Firefoxfirefox.exe"
habr.com
Много программистов-новичков, только начинающие работать с Друпал, не понимают сути самого понятия хук и большинство из них думает: “работает, значит не трогай”. Но давайте мы разберемся, что это такое и почему он важен, для работы с Друпалом.
Данный пост тяжело назвать статьей, это скорее всего заметка. Но, все же, мы уверены, что она будет полезна тем, кто хочет понять что такое хук в Друпале.
Значение слова
Для начала, давайте разберемся что такое hook. В переводе с английского слово hook значит «крючок» (имя существительное) или же подцепить (глагол). Конечно же, такое название ему дано не зря, если вдуматься в это понятие, то оно как раз подходит по своей сути тому, что оно делает.
Пример “на пальцах”
Давайте представим что у нас есть машина:
Что же она из себя представляет? В ней нет ни стекол, нет фар, все стандартное, практически без вкуса, даже в салоне ничего нет. Грубо говоря, именно такой машиной можно считать только что установленный Друпал. Вроде бы все что нужно есть, машина поедет (если еще будет все необходимое для этого), но нет никаких плюшек.
Смотрим на следующее фото. Эту машину уже можно ассоциировать с Друпал-сайтом, на котором стоят специальные модули:
Обратите внимание на вторую машину, в ней есть фары, есть бампер, отличные тонированные стекла и зеркала бокового вида. Всего этого не было в первой машине. Вопрос идет в следующем, за счет чего мы ее улучшили? Если присмотреться к первой машине, оказывается все просто. В ней были оставлены специальные места, так называемые заготовки, для того чтоб можно было вставить все нужные детали, подточенные («кастомизированные») специально под ее владельца. Таким образом эти заготовки, помогли нам сделать машину лучше.
Что мы имеем в Друпале?
В Друпале аналогичная система, то есть в нем есть специальные места, которые позволяют внедриться в его систему (ядро) практически любые изменения в работе сайта.
Пример хуков Друпал
Каждый хук идет как событие. К примеру hook_user_insert вызывается тогда, когда в системе создается новый пользователь. То есть у нас есть событие: создание пользователя. hook_init запускается всегда перед началом инициализации страницы, а вот hook_menu запускается каждый раз при очистки кеша и с его помощью можно внедрить в Друпал свои страницы.
Выводы
Хук — это «крючок», который разрешает внести изменения в работу ядра Друпала. Имейте ввиду, что изменять сам код ядра Друпал запрещено. Это влечет за собой изменение целостности системы, что не только утрудняет работу с сайтом в будущем, усложняет ее масштабирование, но и грозит вам багами, на которые вы будете убивать свое драгоценное время и, конечно же, вы уже больше никогда не сможете сделать нормальное обновление ядра.
Весь список хуков ядра можно увидеть здесь.
Создание блоков в Друпал 7 (работа с хуками hook_block_info и hook_block_view)
Пишем модуль Drupal 7, hook_menu
drupalguide.ru
При разработки масштабируемых приложений часто применяют хуки в PHP. Кому-то хуки нравятся, кому-то нет, но так или иначе с ними приходится иметь дело и проблема в том, что не все понимают, как это работает.
В данной статье я расскажу принцип – как работают хуки в PHP. Использовать хуки можно в любом веб-приложении, например тот, кто работает с WordPress постоянно с ними сталкивается. Использование хуков дает гибкость приложению и позволяет сторонним разработчикам расширять функционал без вмешательства в основной код.
Рассмотрим простой пример
Есть HTML шаблон и он уже заверстан. Предположим, что по каким-то причинам нельзя вмешиваться в код шаблона и что-либо менять, но при этом есть необходимость дополнить его данными.
Чаще всего возникает необходимость дополнить HTML шаблон мета-тегами, стилями, скриптами в шапке или в подвале.
Пусть существует следующий шаблон страницы:
Чтобы дать возможность добавлять мета-теги, стили и скрипты, разработчику необходимо снабдить шаблон хуками и добавить функции обработки. По сути, хуки – это крючки, за которые можно зацепиться, то есть идентифицировать то место, в котором необходимо произвести какое-либо дополнительное действие.
Код приобретет следующий вид:
Далее рассмотрим, что из себя представляет функция do_action
.
Как do_action узнает какие функции нужно выполнить
В действительности все названия функций, которые должны быть выполнены на определенном хуке хранятся в массиве. Переменная, содержащая этот массив, является глобальной и доступна во всем приложении, следовательно мы можем дописывать данные в эту переменную.
Пусть массив имеет следующий вид:
Получается, что есть списки, которые складываются в один большой список, где hook_name_x
– это название какого-то хука, index_x_x
– индекс(порядковый номер) функции function_name_x_x
в списке указанного хука.
При этом порядковый номер функции в списке можно использовать для определения последовательности выполнения функций – чем больше значение индекса, тем ниже эта функция будет в списке, а значит тем позже она будет выполнена.
Все это можно объяснить на примере: представьте себе человека, который спускается на лифте и у него в руках тетрадь, каждая страница которой соответствует какому-либо этажу, на котором останавливается лифт, на каждой странице имеется список задач, которые следует выполнить на соответствующем этаже. В данном примере названия этажей являются хуками, а элементы списка(задачи) на каждой странице, являются функциями, привязанными к конкретному хуку. Очередность выполнения задач определяется их положением в списке, сверху вниз.
Привязка функции к хуку
Для того, чтобы указать по какому хуку следует выполнить функцию, необходимо добавить название функции в соответствующий список. При этом должна быть возможность указать приоритет выполнения функции.
$tag
– имя хука, $callback
– название функции, которая будет выполнена по данному хуку, $priority
– приоритет выполнения, с указанным значением по умолчанию.
Внутри функции говорится, что необходимо переменную $hooks
воспринимать, как глобальную. Следующим шагом будет нахождение не занятого индекса в списке функций, привязанных к указанному хуку, по средствам функции find_next_priority
. После того, как не занятый индекс найден, функция добавляется в список под найденным индексом. Список сортируется в соответствии с порядковым номером – индексом.
Выполнение функций по хуку
Поскольку в PHP выполнение программы последовательное, обработчик будет добираться до каждого хука по мере его нахождения, как только хук будет найден, будут выполнены все функции, которые есть в соответствующем списке.
Добавление хуков внутри приложения происходило путем простановки функций do_action( $name )
в нужных местах шаблона, где $name
– это имя конкретного хука.
Если функция, найденная в списке указанного хука существует, она выполняется.
Хуки в PHP – итог
Таким образом, если в приложении расставлены хуки, можно выполнять какие-либо действия, например вывод данных, без необходимости редактирования основного кода.
Это позволит расширить функционал приложения, не нанеся ему вред. По такому принципу работают, например, плагины в WordPress, они расширяют функционал, без фактического изменения кода системы.
Приведенный пример является упрощенной моделью системы хуков, описывающий принцип их работы.
По данной теме я провел вебинар, который может быть полезен:
Ссылка на исходники: php-hooks.zip
Данный вебинар на GeekBrains: Хуки в приложении на PHP
oiplug.com
RTFM
Что такое хук (hook — крючок, англ.)? Это механизм, позволяющий отследить некое событие в операционной системе. Было оно разработано дяденьками из Microsoft с самыми благими намерениями — позволить программисту более эффективно решать свои задачи путем установки контроля над событиями клавиатуры, мыши и многого другого. Реализовался он при помощи всем известных функций: SetWindowsHook(Ex), UnhookWindowsHook(Ex) и CallNextHook(Ex).
Хук служит для перехвата неких событий до того, как они дойдут до приложения. Эта функция может реагировать на события и, в некоторых случаях, изменять или отменять их. Функции, получающие уведомления о событиях, называются «фильтрующими функ циями» и различаются по типам перехватываемых ими событий. Пример — фильтру ющая функция для перехвата всех событий мыши или клавиатуры. Чтобы Windows смогла вызывать функцию-фильтр, эта функция должна быть установлена, то есть, прикреплена к хуку (например, к клавиатурному). Прикрепление одной или нескольких фильтрующих функций к какомунибудь хуку называется установкой хука. Если к одному хуку прикреплено несколько фильтрующих функций, Windows реализует очередь функций, причем функция, прикрепленная последней, оказывается в начале очереди, а самая первая функция — в ее конце.
Со временем благородное понятие хука извратилось, причиной чего стали действия вирусописателей и малварщиков. Первые вирусы были, как бы это сказать… наивными, наверное. Они представляли собой отдельный exe-файл, напрямую вызывающий нужные функции системы. Шло время и антивирусы, которые появились чуть позже и вдруг стали коммерческими, довольно быстро научились ловить вирусы по сигнатурам путем простого сканирования оперативной памяти или дискового пространства.
И вот тут-то, в пылу извечной борьбы между писателями вирусов и их «ловцами» встал один-единственный вопрос, который стоит на повестке дня до сих пор и будет стоять в ближайшем необозримом будущем — это вопрос выживания в операционной системе. Причем он также актуален и для антивирусов, ведь для хорошего системного программиста, пишущего вирусы/ руткиты, вынести процесс антивируса из системы — не слишком сложная задача.
Поэтому можно смело утверждать, что одна из задач антивирусов — это умение сохранить свой процесс в целостности и сохранности от злонамеренных действий вируса. В общем, на сегодняшний день под хуками следует понимать установку контроля над основными системными функциями операционной системы, от которых зависит жизнеспособность любой программы — речь идет, как правило, о функциях работы с процессами, потоками, сетью и интернетом и т.д.
«А как же SetWindowsHook?» — спросишь ты меня. «Прошлый век», — отвечу я. Использовать их давно уже не кошерно.
Что имеем?
Проще всего установить хук в системе путем создания так называемой прокси-функции. Иначе говоря, тебе надо определиться, какую функцию ты перехватываешь, и найти адрес ее вызова. Для этого обычно используется функция GetProcAddress примерно вот так: GetProcAddress(GetModuleHandle("ntdll.dll"), "CsrNewThread").
Однако просвещенные знают, что она практически всегда перехватывается аверами, и для нахождения адреса функции используют парсинг таблицы импорта той или иной библиотеки, обычно ntdll.dll, kernel32.dll (kernelbase.dll в Windows7) или advapi32.dll.
Далее тебе нужно создать свою прокси-функцию, точь-в-точь повторяющую вызываемую примерно вот таким образом:
int MyNewFunction(void *param1,
int param2, bool param3)
{
return OriginalFunction(param1,
param2, param3);
}
После этого следует перезаписать адрес вызова OriginalFunction на свой — то есть, на MyNewFunction.
Теперь, если кто-либо захочет вызвать для исполнения OriginalFunction, сначала будет вызвана твоя прокси-функция MyNewFunction, которая уже потом передаст управление на оригинальный адрес. Вот таким вот нехитрым образом действуют, наверное, 8 хуков из 10. Этот способ удобен лишь своей простотой, но при этом представляет собой ужасное палево для аверов. Как? Поразмысли сам — все, что аверу нужно, это сравнить прежний, «законный», адрес функции с тем, что есть на самом деле. Если они отличаются — бьем тревогу. Кстати, встает и следующий вопрос: откуда взять этот самый адрес оригинальной функции? Тут особо гадать не надо — его считывают с нужного файла на диске. Этот подход основывается на том предположении, что вирус не будет патчить таблицу экспорта файла, лежащего на диске, ограничившись патчем виртуальной памяти.
Итак, едем дальше. Как я уже говорил, использование хука в виде прокси-функции хоть и удобная вещь, но, во-первых, палевная, а во-вторых, подходит лишь для начинающих. То есть не для тебя :). Самый распространенный вид хука — это сплайсинг. Уверен, ты не раз слышал это слово. В нашем случае это запись на начало функции пятибайтовой последовательности, которая представляет собой команду jmp по адресу обработчика перехвата. Здесь первый байт — опкод jmp, оставшиеся четыре байта — адрес твоей функции.
Если необходимо вызывать перехватываемую функцию, то перед заменой необходимо сохранить ее начальные байты и перед вызовом восстанавливать их. Недостаток данного метода состоит в следующем: если после восстановления начала функции произошло переключение контекста на другой поток приложения, то он сможет вызвать функцию, минуя перехватчик. Этот недостаток можно устранить, останавливая все побочные потоки приложения перед вызовом, и запуская после вызова. Ну и конечно, сплайсинг, как и прокси-функции, тоже легко выявляется методом сканирования памяти, так как сразу будет видно, что вызов функции идет куда-то в другое место.
Вообще, забегая вперед, должен донести до широкой общественности, что почти все методы перехвата вызова функций так или иначе детектятся сканированием памяти. За исключением двух методов, но об этом читай ниже.
IAT, EAT и другие звери
Возникает вопрос: а на что и, самое главное, где можно ставить свои хуки? Первое, что приходит на ум — конечно же, поставить перехват на Import Address Table (IAT). Когда приложение использует функцию из библиотеки, приложение должно импортировать адрес функции. Каждая DLL, используемая приложением, описана в структуре, называемой IMAGE_IMPORT_DESCRIPTOR. Эта структура содержит имя DLL, чьи функции импортированы приложе нием, и два указателя на два массива структур IMAGE_IMPORT_BY_ NAME. Структура IMAGE_IMPORT_BY_NAME содержит имена импортированных функций, используемых приложением.
Когда операционная система загружает приложение в память, читается структура IMAGE_IMPORT_DESCRIPTOR и каждая требуемая DLL загружается в память приложения.
Как только DLL отображена (mapped), операционная система располагает каждую импортированную функцию в памяти и записывает поверх одного из массивов IMAGE_IMPORT_BY_ NAME с исполнительным адресом функции.
Как только hook-функция появляется в адресном пространстве приложения, твой вирус сможет прочесть формат PE целевого приложения в памяти и заменить целевой адрес функции в IAT адресом hook-функции. Тогда, когда перехватываемая функция будет вызвана, твоя hook-функция будет выполнена вместо первоначальной функции. Чуть более редкий вариант, встречающий в природе, реализованный по приниципу «Если гора не идет к Магомеду…» — перехват Export Address Table (EAT), когда патчится, наоборот, таблица экспорта Dll, которая экспортирует целевую функцию.
STELTH-хуки: поймай меня, если сможешь
Как я уже писал выше, главный недостаток вышеуказанных методов перехвата — это вынужденная модификация памяти, что неизбежно ведет к ее детекту со стороны аверов. Есть ли выход? Как ни странно, есть. Даже два. Первый из них — это зарегистрировать свой обработчик исключений, затем добиться, чтобы он получил управление. Это можно сделать, например, потерев какой-либо участок памяти. Второй способ представляет собой несколько видоизмененный первый. То есть, ты, как и раньше, регистрируешь обработчик исключений, но для их генерирования ты используешь прием, известный среди дебаггеров. Как ты знаешь, дебагрегистры процессора используются для отладки приложений и доступны, как правило, из кернелмода. Однако их можно устанавливать и из юзермодных приложений путем использования функций GetThreadContext/ SetThreadContext. Используются дебаг-регистры для установки точек останова (Breakpoints) на доступе к участку памяти или исполнении.
Всего имеется восемь регистров, их назначение следующее:
- DR0 — DR3 — Каждый из этих регистров содержит линейный адрес одной из четырех контрольных точек. Если подкачка страниц разрешена, то их значения транслируются в физические адреса по общему алгоритму;
- DR4 — DR5 — Регистры зарезервированы и в процессоре i486 не используются;
- DR6 — Отладочный регистр состояния. Он сообщает об условиях, выявленных во время генерирования отладочного исключения (номер 1). Биты регистра устанавливаются аппаратно, а сбрасываются программно;
- DR7 — Регистр задает вид доступа к памяти, связанный с каждой контрольной точкой.
Итак, все, что тебе нужно сделать — это установить хардварный бряк (hardware breakpoint, он же int 1) на начало функции, чтобы процессор сгенерировал так называемое «одношаговое исключение» (single step exception) и затем, путем установки своего обработчика исключения: AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_ HANDLER)DebugHookHandler), перехватить этот самый EXCEPTION_SINGLE_STEP.
При его генерации твой обработчик получит управление желанной функцией. Несомненное достоинство такого метода в том, что он абсолютно невыявляем путем сканирования памяти, поскольку ее модификация здесь не происходит.
int SetDebugBreak(FARPROC address)
{
int status = -1;
HANDLE thSnap = CreateToolhelp32Snapshot(
TH32CS_SNAPTHREAD, NULL);
THREADENTRY32 te;
te.dwSize = sizeof(THREADENTRY32);
Thread32First(thSnap, &te);
do
{
if(te.th32OwnerProcessID != GetCurrentProcessId())
continue;
HANDLE hThread = OpenThread(
THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
GetThreadContext(hThread, &ctx);
if(!ctx.Dr 0)
{
ctx.Dr0 = MakePtr( ULONG, address, 0);
ctx.Dr7 |= 0x00000001;
status = 0;
}
else if(!ctx.Dr1)
{
ctx.Dr1 = MakePtr( ULONG, address, 0);
ctx.Dr7 |= 0x00000004;
status = 1;
}
else if(!ctx.Dr2)
{
ctx.Dr2 = MakePtr( ULONG, address, 0);
ctx.Dr7 |= 0x00000010;
status = 2;
}
else if(!ctx.Dr3)
{
ctx.Dr3 = MakePtr( ULONG, address, 0);
ctx.Dr7 |= 0x00000040;
status = 3;
}
else
status = -1;
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
SetThreadContext(hThread, &ctx);
CloseHandle(hThread);
}
while(Thread32Next(thSnap, &te));
return status;
}
Заключение
Как ты видишь, даже в самых сложных ситуациях можно найти возможность исполнить свой код. Уверен, что при этом твой код нацелен исключительно на решение задач по защите твоей системы. Удачи тебе и удачного компилирования!
Links
http://vx.netlux.org — своеобразный музей вирусов, вирусных движков и прочей интересной ерунды. Must visit, одним словом.
xakep.ru
Примеры употребления слова хук в литературе.
Вообще Кеша значительно скорее сошелся с Хуком Образиной и даже с АрманомЖофруа дёр Крузербильд Дзухмантовским, в просторечии, Крузей.
Наступило мгновение, когда лица у всех собравшихся стали одинаковыми — и у Ивана, и у Гута Хлодрика, беглого каторжника и вожака развалившейся банды, и у спившихся героев Дальнего Космоса Хука Образины и Армана-Жофруа дёр Крузербильд Дзухмантовского, и у ветерана жестокой аранайской войны Иннокентия Булыгина, и у преуспевающего Дила Бронкса.
У него и боковой, и хук, и кистевой, и скользящий, и прямой, который чуть не пробил мне ладонь!
Сразу после удара Попова в серебряный таз, заменявший гонг на этих соревнованиях, Ваня отличным хуком отправил Посейдона в нокаут на более длительный срок, чем это смог сделать Гефест в бою против Вакха.
А Хук Образина, которого лет двадцать назад звали Хуком Красавчиком, бесшабашный и удачливый космодесантник-смертник, списанный, спившийся, уже похороненный в помойном баке, но возродившийся и прошедший с боями половину земного шара и пол-Вселенной, выплясывал какой-то варварский танец, бил себя кулаками в грудь и хохотал.
Хук подошел к бару, налил себе рюмку, не предложив ничего Лейжу, и, пока цедил крепкий напиток, видел в зеркале, как изменилось красивое лицо молодого биохимика, как дрогнул уголок рта, чуть сощурились и потемнели его глаза.
Хук не понимал, куда подевались три бригадных все-пространственных боевых звездолета, он ничего не видел, кроме бойни, страшной бойни в трюмах.
На тренировочной базе есть боулинг, сауна и библиотека, — сказал Хуке.
Растет напряжение в Сент-Энтони-Филд, Ларри Горман в нокдауне в конце третьего раунда, сбитый с ног невероятно быстрым хуком Рэндольфа, сейчас надо понять, сможет ли он продолжать встречу, необычное для него положение, в первый раз за свою карьеру в боксе он был отправлен на ковер, невероятно быстрый хук Рэндольфа оказался для него неожиданностью, НАЧАЛО ЧЕТВЕРТОГО РАУНДА, яростный натиск Рэндольфа, РЭНДОЛЬФ, РЭНДОЛЬФ, ГОРМАН ПРИЖАТ К КАНАТАМ, плохое начало для воспитанника Мондини, Рэндольф будто с цепи сорвался, АППЕРКОТ, СНОВА АППЕРКОТ, Горман принимает более закрытую стойку, уходит слева, тяжело дышит, РЭНДОЛЬФ ВОЗОБНОВЛЯЕТ ПОПЫТКУ, тактика не самая отлаженная, но она дает результаты, Горман вновь вынужден отступать, ноги плохо его слушаются, ДЖЭБ РЭНДОЛЬФА, ПРЯМОЕ ПОПАДАНИЕ, СНОВА ДЖЭБ И ХУК ПРАВОЙ, ГОРМАН ШАТАЕТСЯ, ПРЯМОЙ УДАР ПРАВОЙ РЭНДОЛЬФА, МИМО, РЭНДОЛЬФ ПРЕСЛЕДУЕТ ГОРМАНА, ГОРМАН ОПЯТЬ ПРИЖАТ К КАНАТАМ, ВСЕ ЗРИТЕЛИ ВСТАЮТ.
Левым кулаком Рыжий молниеносно ткнул Джина в солнечное сплетение, а правым хуком съездил по уху.
Она как-то неуверенно засмеялась и с лихорадочным нетерпением смотрела на Хука, дожидаясь ответа.
Тот хук справа тоже был прекрасной работой, — Медисон опустился в кресло, на котором только что сидел таракан Перкинс, и я подумал, что его придется дезинфицировать в два раза тщательнее.
Но давнишний знакомец по гадрианским болотам Хук Образина, затащил его в одну-единственную на Эрте гостиную.
Иван замешкался, стал обдумывать, как бы потолковее все разъяснить Хуку, а потом вдруг решил, что ничего разъяснять не надо, и выпалил: — Я, Образина, на дело иду, понимаешь?
Хук Образина отбил-таки атаку оборотней, и из Центра сразу же пришел приказ оставаться до зимы на своих позициях.
Источник: библиотека Максима Мошкова
поискслов.рф