Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #71, НОЯБРЬ 2004 г.

Паразит для IE

Николай GorluM

Хакер, номер #071, стр. 071-110-2


Что нам стоит BHO построить?

Загружай студию, будем писать собственный Browser Object Helper. В менюшке вместо обычного win32 application выбирай ATL COM, а в визарде оставь все как было, чтобы получить дефолтовый ATL COM-сервер. Смело дави мышкой в меню на «Add ATL Object» и добавляй «Internet Explorer Object». Думаешь, все? Больше ничего делать не надо? Ошибаешься. Все только начинается, и можно разминать пальцы для кодинга.

Залезай в хидер, создавшийся после добавления объекта, и найди там описание класса нашего BHO. У меня оно начинается так:

class ATL_NO_VTABLE CBHO:

public CComObjectRootEx<CComSingleThreadModel> ,

public CComCoClass<CBHO, &CLSID_BHO> ,

public IObjectWithSiteImpl<CBHO> ,

public IDispatchImpl<IBHO, &IID_IBHO, &LIBID_IEPLUGINLib>

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

public:

STDMETHOD(SetSite)(IUnknown *pUnkSite);

STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);

private:

STDMETHOD(Connect)(void);

CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> m_spWebBrowser2;

CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> m_spCPC;

DWORD m_dwCookie;

Посредством функций SetSite и Connect мы инициализируем наш Browser Helper Object и перехватываем указатель на IWebBrowser2, при взаимодействии с которым и будет реализовываться любой контроль или слежка за пользователем. Указатель записываем в переменную-член m_spWebBrowser2 (на исходный код этой и других функций ты можешь посмотреть на диске или на сайте www.xakep.ru).

Функция же Invoke понадобится нам для реагирования на события, возникающие в процессе работы браузера. Событий масса: от завершения скачивания сайта до начала даунлоада какого-нибудь файла. Все ID этих событий, активно использующихся в реализации этой функции, хранятся в хидере <ExDispID.h> , который, кстати, нужно будет добавить в программу, а само значение ID текущего события содержится в аргументе dispidMember.

Итак, все необходимое у нас есть, осталось только придумать цель нашего тотального контроля. После длительных поисков в Яндексе меня посетила безумно могучая идея - а что если научить наш BHO при заходе на www.ya.ru громко ругаться MessageBox’ом и отправлять браузер на www.google.com? Не проблема.

Для этого в функции Invoke надо обрабатывать событие DISPID_DOCUMENTCOMPLETE, возникающее при очередной загрузке документа, и сравнивать URL текущей паги с заданным. Получение URL’а – наше первое использование объектной модели браузера. Осуществляется оно с помощью метода get_LocationURL вот так:

Назад на стр. 071-110-1  Содержание  Вперед на стр. 071-110-3