![image](http://habrastorage.org/getpro/habr/post_images/ad3/802/710/ad3802710ec84a344d96f0996768959c.jpg)
Некоторое время назад я писал вводную статью о хуках (что это, зачем нужно, Hello world). Статья задумывалась простой, минималистичной и, вроде бы, такой и получилась. Единственный упрёк, который я услышал в комментариях — «Зачем же брать библиотеку Microsoft Detours, которая для коммерческого использования стоит 10 000$ ?». Замечание справедливое. В этой статье я приведу тот же пример с использованием другой библиотеки ценой примерно в 20 раз меньше (что уже вполне себе в рамках разумного) — madCodeHook.
Для лучшего понимания данной статьи рекомендуется сначала прочитать первую часть.
madCodeHook
Библиотека с богатым прошлым. Первая её версия вышла в далёком 2000-ом году, предназначалась для использования под Delphi и мало что умела. Тем ни менее за последующие годы автор весьма неплохо её развивал: сделал SDK для С++, внедрил поддержку 64-битных систем, всех версий Windows от 9х до Win 8.1, реализовал драйвер для внедрения хуков во все новосозданные процессы, ну и вообще достаточно активно работал над проектом (апдейты и сейчас выходят регулярно). По ходу дела из-из нежелания быть подмогой вирусописателям библиотека потеряла бесплатную версию, однако цены, начинающиеся от 349 евро делают её реальной альтернативой и нереально дорогой Microsoft Detours, и малоудобной mhook, и нестабильной (по моему опыту) EasyHook.
Ограничения evaluation-версии
- Нет исходников
- Нет возможности статической линковки
- Должно быть вручную запущено входящее в комплект приложение mchEvaluation.exe
- Библиотека madCHook.dll должна быть предварительно скопирована в System32
В общем, для изучения — ничего критически мешающего. Для коммерческого продукта в любом случае нужно покупать лицензию.
Вспоминаем нашу задачу
В первой части статьи мы использовали хуки для того, чтобы заставить браузер Mozilla Firefox при заходе на Хабр писать в своём заголовке «Привет, Хабр!». Во-первых, мне лень придумывать новую задачу, а во-вторых даже правильнее будет реализовать снова тоже самое на базе другой библиотеки — можно сравнить скорость разработки, объём и сложность кода. Кроме того, в первой части мы уже разобрались куда и какие хуки нужно вешать, так что сэкономим на этом немного времени.
Практика
1. Качаем последнюю версию madCodeHook, устанавливаем.
2. Создаём в Visual Studio (я использую VS 2010, но вы можете взять и другую) solution c двумя проектами. Первый — библиотека с кодом хука, которую мы будем инжектить в процесс браузера. Второй — приложение инжектора, его задача — забросить библиотеку в адресное пространство браузера.
- Для создания первого проекта: File->New->Project. Тип Visual C++ -> Win32 -> Win32 Project. В диалоге создания проекта указываем тип «Dll»
- Для создания второго проекта: File->Add->New Project. Тип Visual C++ -> Win32 -> Win32 Console Application.
4. Подкидываем в наши проекты заголовочный файл и lib-файл из SDK madCodeHook. При установке библиотеки по-умолчанию они находятся по адресу C:\Program Files (x86)\madCollection\madCodeHook\Dll. В evaluation-версии нам доступна только динамическая линковка, так что забираем файлы madCHook — dynamic.h и madCHook — dynamic — microsoft.lib, можно их для краткости переименовать в madCHook.h и madCHook.lib.
5. Пишем код. Ключевые моменты:
#include "stdafx.h" #include <conio.h> #include "windows.h" #include "madCHook.h" #include <tlhelp32.h> HANDLE GetProcessByName(PCWSTR name) { DWORD pid = 0; HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 process; ZeroMemory(&process, sizeof(process)); process.dwSize = sizeof(process); if (Process32First(snapshot, &process)) { do { if (_wcsicmp(process.szExeFile, name) == 0) { pid = process.th32ProcessID; break; } } while(Process32Next(snapshot, &process)); } CloseHandle(snapshot); if (pid != 0) return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); return NULL; } int _tmain(int argc, _TCHAR* argv[]) { InjectLibraryW((DWORD)GetProcessByName(L"firefox.exe"), L"HookLib.dll"); _getch(); UninjectLibraryW((DWORD)GetProcessByName(L"firefox.exe"), L"HookLib.dll"); }
#include "stdafx.h" #include "madCHook.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"Хабрахабр"NULL) return TrueSendMessageW(hWnd, Msg, wParam, (LPARAM)L"Привет, Хабр!"); return TrueSendMessageW(hWnd, Msg, wParam, lParam); } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: HookAPI("User32.dll", "SendMessageW", MySendMessageW, (PVOID*) &TrueSendMessageW); } return TRUE; }
6. Компилируем, запускаем Firefox, запускаем mchEvaluation.exe, запускаем инжектор, в браузере переходим на Хабр. Результат:
Выводы
В плане удобства работы с evaluation-версией madCodeHook немного проигрывает Microsoft Detours, полнофункциональные версии в этом плане примерно равны. Кода писать madCodeHook требует даже меньше. В составе madCodeHook есть драйвер для внедрения библиотек на общесистемном уровне (во все существующие и новые процессы), в Detours эту задачу нужно решать собственным сервисом или драйвером. По скорости и стабильности библиотеки показались мне аналогичными. madCodeHook не вызывает ощущения «энтерпрайзности», как продукт Microsoft, что одновременно и хорошо и плохо: автора легко можно поймать на форуме (что хорошо), но там же написано «я могу уйти в отпуск на 6 недель в любое время года» (что плохо). Сообщество madCodeHook сосредоточено на их форуме, сообщество Microsoft Detours как-то раскидано по Stackoverflow, wasm.ru, форумам MSDN и ощущения целостности не создаёт.
В общем, библиотека madCodeHook оставляет хорошее впечатление, можно пользоваться.
ссылка на оригинал статьи http://habrahabr.ru/post/213309/
Добавить комментарий