cmbStart.Caption := \'Начать слежение\
end;
end;
Как можно увидеть, вся сложность на стороне приложения-шпиона состоит в создании/удалении проекции файла и в вызове двух экспортируемых из библиотеки hook, dll функций. Они подключаются следующим объявлением:
...
function InstallHook(wnd: HWND; spy: HWND): Boolean stdcall;
external \'hook\hook.dll\' name \'InstallHook\
function RemoveHook(): Boolean stdcall;
external \'hook\hook.dll\' name \'RemoveHook\
Для обработки сообщения WM_SPY_NOTIFY, посылаемого ловушкой, переопределена оконная процедура формы f rmMessages (листинг 10.19).
...
Листинг 10.19.
Обработка сообщения WM_SPY_NOTIFY
procedure TfrmMessages.WndProc(var Message: TMessage);
var
item: TListItem;
i: Integer;
begin
if (Message.Msg = WM_SPY_NOTIFY) and (hook_info <> nil) then
begin
//Обрабатываем уведомление о приходе сообщения в наблюдае-
мое окно
for i := mess_first to mess_last do
if (messages_list[i].value = hook_info^.mess) and
messages_list[i].used then
begin
//Сообщение выбрано в фильтре – добавим запись в список
item := lvwMessages.Items.Add();
item.Caption := messages_list[i].name;
item.SubItems.Add(IntToStr(hook_info^.wParam));
item.SubItems.Add(IntToStr(hook_info^.lParam));
end;
end
else
inherited WndProc(Message);
end;
Ловушка
Теперь обратимся к реализации самой ловушки. По рассмотренным ранее причинам ловушка размещена в отдельной DLL (hook\hook.dll на прилагаемом к книге диске в папке с номером главы). На случай, если вы не знакомы с созданием DLL средствами Delphi, приведем краткие сведения.
Среда программирования Delphi замечательна тем, что позволяет просто делать довольно сложные вещи. Хотя и при использовании сред разработки, скрывающих меньшее количество сложных деталей, например Visual C++, создание DLL не является очень сложной задачей. Итак, для создания DLL в простейшем, то есть нашем, случае достаточно выполнить следующие действия.
1. Создать соответствующий проект (с помощью команды меню FiLe → New → Other,тип проекта – DLL Wizard)(рис. 10.6).
2. В DPR-файле получившегося проекта реализуем функции, которые предполагается экспортировать.
3. Объявляем, какие функции нужно экспортировать с помощью ключевого слова exports (листинг 10.20).
Рис. 10.6. Создание проекта DLL
Структура DLL ловушки, реализованной в нашем примере, приведена в листинге 10.20.
...
Листинг 10.20.
DLL ловушки без реализации функций
library hook;
uses
Windows,
HookData;
//****************************************************
//Экспортируемые функции
function InstallHook(wnd: HWND; spy: HWND): Boolean stdcall;
forward;
function RemoveHook(): Boolean stdcall; forward;
exports
InstallHook,
RemoveHook;
//****************************************************
…
begin
hook_info := nil;
hFile := 0;
end.
Код после begin является кодом инициализации библиотеки (выполняется при загрузке DLL в память процесса). Правда, как показали многочисленные эксперименты, проведенные во время написания и отладки ловушки, код этот не выполняется при загрузке DLL ловушки в адресное пространство другого процесса.
Теперь обратимся к реализации экспортируемых функций InstallHook, а также RemoveHook. Как вы помните, только эти две функции вызываются из программы-шпиона. Начнем с функции установки ловушки (листинг 10.21).
...
Листинг 10.21.
Установка (создание) ловушки
function InstallHook(wnd: HWND; spy: HWND): Boolean stdcall;
begin
//Открываем проекцию файла (области файла подкачки)
if not GetFileMapping() then
begin
//Не удалось спроецировать файл в память
InstallHook := False;
Exit;
end;
//Сохраняем данные, необходимые для работы ловушки
hook_info^.wnd := wnd;
hook_info^.spy_wnd := spy;
//Создаем ловушку
if (GetWindowThreadProcessId(wnd) <> 0)
then
hook_info^.hook_handle :=
SetWindowsHookEx(WH_CALLWNDPROC, WndProcHook,
hInstance, GetWindowThreadProcessId(wnd))
else
//Создание ловушки для потоков нашего приложения
//было бы фатальным
hook_info^.hook_handle := 0;
InstallHook := hook_info^.hook_handle <> 0;
//Освободим проекцию файла
ReleaseFileMapping();
end;
Функция InstallHook использует глобальную переменную-указатель hook_inf о, которая объявлена в модуле HookData. Функция GetFileMapping, также используемая в листинге 10.21, связывает указатель hookinf о с областью памяти, на которую проецируется файл. Соответственно, процедура ReleaseFileMapping отменяет проецирование файла в память (после этого использовать указатель hookinf о нельзя).
Читать дальше
Конец ознакомительного отрывка
Купить книгу