...

Листинг 10.25.

Функция-ловушка

function WndProcHook(code: Integer; wparam: WPARAM;

lparam: LPARAM): LRESULT stdcall;

var

hook_data: ^TCWPStruct;

begin

//Получим доступ к проекции файла

if not GetFileMapping() then

begin

//Не удалось получить доступ к проекции файла. Ценой потери

//сообщений не дадим возникнуть ошибкам доступа к памяти

WndProcHook := 0;

Exit;

end;

if code < 0 then

begin

WndProcHook := CallNextHookEx(hook_info^.hook_handle, code,

wParam, lParam);

//Освободим проекцию файла

ReleaseFileMapping();

Exit;

end;

//Можно обрабатывать сообщение

hook_data := Pointer(lParam);

//Обрабатываем только сообщения нужного окна

if hook_data^.hwnd = hook_info^.wnd then

begin

//Заполняем поля структуры в общей области памяти и посылаем

//сообщение окну-шпиону

hook_info^.mess := hook_data^.message;

hook_info^.wParam := hook_data^.wParam;

hook_info^.lParam := hook_data^.lParam;

PostMessage(hook_info^.spy_wnd, WM_SPY_NOTIFY, 0, 0);

end;

//Передаем сообщение для дальнейшей обработки

WndProcHook := CallNextHookEx(hook_info^.hook_handle, code,

wParam, lParam);

//Освободим проекцию файла

ReleaseFileMapping();

end;

Код функции WndProc достаточно прост, поэтому не будем подробно его описывать. Поясним лишь, для чего все-таки GetFileMapping и ReleaseFileMapping вызываются при обработке каждого перехваченного сообщения.

Дело в том, что загрузка DLL в адресное пространство другого процесса отличается от штатной загрузки библиотеки, например, при помощи функции LoadLibrary: не вызывается код инициализации. Следовательно, мы не можем, например, обнулить указатель hookinf о или установить еще какой-либо признак того, была ли открыта проекция файла. Велика вероятность того, что без отсутствия ручной инициализации указатель hookinf о не будет равен нулю. Как тогда определить, связан ли этот указатель с областью памяти, куда спроецирован файл?

Можно было бы, конечно, завести 64-битную или более переменную, которой присваивалось бы «магическое» число при первой инициализации указателя hookinf о. Но в таком случае работоспособность нашей программы носила бы вероятностный характер.

Речь не идет о том, что в приведенном примере ловушка реализована самым оптимальным образом, просто альтернатива cGetFileMapping HReleaseFileMapping при написании программы показалась наиболее простой и легко поддающейся объяснению.

Загрузка...