Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 113, МАЙ 2008 г.

Реальная помощь домохозяйкам

Александр Эккерт (aleksandr-ehkkert@rambler.ru)

Хакер, номер #113, стр. 113-100-1

Учимся кодить модули поддержки обозревателя

Полезная вещь – BHO. Большое количество коммерческих программ – от менеджеров закачки до словарей-переводчиков – так или иначе требующих доступ к браузеру, встраивают своих помощников в Internet Explorer. В статье мы расскажем, как средствами C# и Microsoft Visual Studio создать собственный модуль. Естественно, с немного хакерскими функциями.

COM – Component Object Model

Спектр возможного применения BHO огромен – от простого шпионского модуля, который отслеживает вводимые данные, до подмены содержимого веб-страниц и перенаправления запросов пользователя. Ему позволено практически все! Но сначала – теория.

Технология СОМ разрабатывалась, чтобы сделать приложения более гибкими и настраиваемыми. Первоначальной целью была поддержка концепции, известной как связывание и внедрение объектов (object linking and embedding). Реализация, созданная в Microsoft, получила название OLE. Первая версия OLE для связи между клиентом и компонентом использовала динамический обмен данными (dynamic data exchange – DDE). В OLE 1 не было СОМ, DDE был построен на основе архитектуры передачи сообщений Windows. Лучшее, что можно сказать об OLE 1, это то, что он все же работает – более или менее. Во-первых, DDE медлителен. Во-вторых, написать корректно работающий код DDE сложно. Вдобавок, DDE не отличается надежностью и гибкостью. Другими словами, рано или поздно должны были изобрести что-нибудь получше.

Решением стала СОМ – меньше, быстрее, гибче, надежнее, чем DDE. Вторая версия OLE была переписана с использованием СОМ, и именно СОМ стала новым фундаментом, на котором выстроены конструкции OLE. Однако OLE – первая система на основе СОМ, и как любой первый блин, представляет собой не лучший пример использования его возможностей. По ряду причин OLE заслужил репутацию сложного, медленного и трудного для программирования аппарата. Впрочем, это, скорее, недостатки реализации, а не СОМ.

СОМ – больше, чем просто спецификация. В СОМ есть API; это библиотека, предоставляющая сервисы управления компонентами. Если ты разрабатываешь компоненты в стиле СОМ не для Windows, то большинство функций этого API несложно реализовать самостоятельно. Библиотека СОМ создана, чтобы гарантировать единообразное выполнение всеми компонентами наиболее важных операций. Она экономит время разработчикам, создающим собственные компоненты и клиенты. Большая часть кода в библиотеке СОМ служит для поддержки распределенных или сетевых компонентов. Реализация распределенной СОМ (Distributed COM, DCOM) в системах Windows предоставляет код, необходимый для обмена информацией с компонентами по сети. Это избавляет нас не только от необходимости писать такой код, но и от необходимости знать, как это делать!

Самое главное в СОМ – это интерфейсы. Через них клиент взаимодействует с компонентом. Они похожи на элементы каркаса сборного дома – каркас задает структуру, без которой крыша и стены не защитят жителей. Если мы не трогаем каркас, дом остается «структурно» тем же самым. Замена стен влияет только на внешний вид. Аналогично этому, замена компонентов может изменить поведение приложения, но не его архитектуру.

Одно из самых больших преимуществ компонентной модели – возможность повторного использования архитектуры приложения. Просто разрешив заменять некоторые ключевые компоненты, мы добиваемся того, что одна и та же архитектура может поддерживать несколько различных приложений.

«Причем тут BHO?», спросишь ты. Дело в том, что BHO, который мы хотим написать, и есть СОМ-объект, реализующий интерфейс IObjectWithSite и подключающийся к Internet Explorer. Наш продукт будет воспринимать Intrenet Explorer всего лишь как набор интерфейсов, которые и нужно реализовать в нашей программе.

Что такое BHO?

Если в двух словах, то объект BHO является компактным расширением в виде DLL-библиотеки, дополняющим обозреватель Internet Explorer пользовательскими функциями (менее распространен случай, когда их добавляют к оболочке Windows Shell).

Как правило, объекты BHO не имеют собственного пользовательского интерфейса и существуют в виде простой библиотеки, которую IE подгружает при старте. BHO работают в бэкграунде, реагируя на события обозревателя и действия пользователя. Например, могут блокировать всплывающие окна, автоматически заполнять формы или реагировать на движения мыши. Типичным является заблуждение, что объекты BHO требуются для создания расширений панели инструментов (тулбаров). Тем не менее, в сочетании с тулбарами ВНО может предоставить пользователю расширенные возможности.

Объекты BHO удобны и для разработчиков – время жизни объекта BHO совпадает со временем жизни экземпляра обозревателя, с которым этот объект взаимодействует. В Internet Explorer 6 и более ранних версиях это означает создание нового объекта BHO (и его уничтожение) для каждого окна верхнего уровня, а в Internet Explorer 7 – для каждой вкладки. Объекты BHO не загружаются другими приложениями, которые используют элемент управления WebBrowser, или окнами, использующими HTML (например, диалоговыми окнами).

Итак, поехали...

Создаем BHO

Основное требование к объекту BHO – наличие реализации интерфейса IObjectWithSite. Этот интерфейс предоставляет метод SetSite, который обеспечивает первоначальный обмен информацией с Internet Explorer и уведомляет объект BHO о подготовке к освобождению (free). Создав простое расширение для обозревателя с помощью этого интерфейса, мы добавим идентификатор CLSID объекта BHO в реестр.

Для начала создадим новый проект Class Library в VS. Не забудь добавить к проекту ссылки на две внешние библиотеки – SHDocVw и MSHTML ( SHDocVw – путем добавления библиотеки shdocvw.dll, которая лежит в папке %systemroot%/system32). Кроме этого нужно подключить дополнительное пространство имен System.Runtime.InteropServices и Microsoft.Win32.

Наш BHO будет состоять из двух раздельных классов – первый (bugaga) содержит в себе определение интерфейса IObjectWithSite (в свою очередь, включает прототипы двух функций – GetSite и SetSite) и второй (functional), который будет реализовывать всю необходимую функциональность.

В нашем проекте, кроме определений методов GetSite и SetSite, нужно предусмотреть реализацию метода OnDocumentComplete. Эта функция является частью класса CDHtmlDialog и вызывается при завершении загрузки страницы (подробности смотри на http://msdn2.microsoft.com). Также добавим две переменные – WebBrowser и HTMLDocument. Они позволят получить доступ к содержимому веб-страницы.

Теперь очень важный шаг – чтобы получить возможность аттачиться к IE, нужно указать ссылку на GUID интерфейса IObjectWithSite – FC4801A3-2BA9-11CF-A229-00AA003D7352. Обычно он прописывается в этих двух ветках реестра:

HKEY_CLASSES_ROOTInterface{FC4801A3-2BA9-11CF-A229-00AA003D7352}

HKEY_LOCAL_MACHINESOFTWAREClassesInterface{FC4801A3-2BA9-11CF-A229-00AA003D7352}.

И это же надо сделать при описании интерфейса IObjectWithSite путем добавления атрибута [ComVisible(true)].

Добавив GUID к описанию нашего интерфейса, добавим то же самое, но уже в код самого BHO. Затем описываем функциональность методов GetSite и SetSite. Реализация этих методов проста:

Метод GetSite

public int GetSite(ref Guid guid, out IntPtr ppvSite)

{

IntPtr pointer =

Marshal.GetIUnknownForObject(webBrowser);

int face =

Marshal.QueryInterface(pointer, ref guid, out ppvSite);

Marshal.Release(pointer);

return face;

}

В приведенной выше функции GetIUnknownForObject мы получаем описатель интерфейса IUnknown для нашего браузера. Осталось только добавить идентификатор CLSID объекта BHO в реестр. Эта запись описывает библиотеку DLL как объект модуля поддержки обозревателя и заставляет обозреватель IE загружать объект BHO при запуске. Среда Visual Studio может зарегистрировать идентификатор CLSID во время сборки проекта. Запомни: все BHO для Internet Explorer регистрируются вот в этой ветке реестра:

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerBrowser Helper Objects.

Делаем это так: добавляем еще одну функцию register для регистрации BHO и перед ней ставим атрибут [ComRegisterFunction]. Далее запускаем утилиту RegAsm.exe с ключом /codebase. Она зарегистрирует нашу сборку и –вуаля! – в вышеуказанном ключе реестра появляется строка с CLSID. Это и есть наш BHO!

Маленькое лирическое отступление: если ты собираешься использовать BHO для своих грязных целей, имей в виду, все антивири и файры постоянно отслеживают запись в указанную ветку реестра. Поэтому регистрация BHO в системе – вещь крайне шумная и неудобная.

Тырим пароли...

Для более полного контроля за действиями пользователя необходимо будет реализовать обработку событий класса WebBrowser, например события onBeforNavigate2.

Код, который будет собирать пароли с форм веб-страниц, может выглядеть так:

public void OnBeforNavigate2

(ref object TargetFrameName, ref object PostData, ref object Headers,

ref bool Cancel)

{

document = (mshtml.HTMLDocument)webBrowser.Document;

foreach(mshtml.IHTMLInputElement el

in document.getElementsByTagName("input"))

{

if(el.type.ToLower() == "password")

//шлем пароль мне...

}

}

Вот и все! Созданный нами BHO невелик в размере, но вполне работоспособен. В принципе, в создании BHO нет ничего сложного, главное – иметь представление о работе COM-компонентов.

Заключение

Логично предположить, что BHO популярны как среди добрых и честных разработчиков, которым требуется расширение функциональности обозревателя, так и среди недобрых дяденек хакеров, которые пытаются поставить под контроль твои действия в интернете. На диске ищи готовый код BHO, который, проявив смекалку, можешь без проблем расширить под свои замыслы. Enjoy!

DVD

На диске ты найдешь написанный на C# вариант реализации BHO.

WWW

Тема создания BHO широко обсуждается на форумах realcoding.net, gotdotnet.ru и, конечно же, MSDN.

INFO

Программирование BHO советую начать с изучения COM – знания о компонентном программировании обязательно пригодятся! Например, рекомендую ознакомиться с книгой Дейла Роджерсона «Основы COM». Скачать ее можно отсюда: www.podgoretsky.com/classics.html.

Содержание
ttfb: 499.9258518219 ms