Dr. Joseph M. Newcomer "Хуки и DLL"
От: Lexey (перевод) Россия  
Дата: 22.10.01 02:01
Оценка: 121 (5)
Статья :
Хуки и DLL
Автор(ы): Dr. Joseph M. Newcomer
Дата: 25.04.2001
Статья посвящена реализации глобальных хуков. В ней рассматриваются типичные проблемы, связанные
с различием виртуальных адресов перехватывающей DLL в адресных пространствах различных процессов, описывается
способ создания разделяемого сегмента данных, приводится пример DLL, реализующей глобальный хук.


Авторы :
Lexey (перевод)

Аннотация :
Статья посвящена реализации глобальных хуков. В ней рассматриваются типичные проблемы, связанные
с различием виртуальных адресов перехватывающей DLL в адресных пространствах различных процессов, описывается
способ создания разделяемого сегмента данных, приводится пример DLL, реализующей глобальный хук.
Момент выгрузки хуковой библиотеки
От: Leonid Troyanovsky  
Дата: 19.09.02 05:36
Оценка: 9 (2)
После UnhookWindowsHookEx загруженная в чужой процесс
на WH_GETMESSAGE библиотека останется там даже если ее счетчик ее загрузок обнулится.
Реально она будет выгружаться только после обработки
очередного сообщения, посланного Post*Message.
Т.е., чтобы гарантировать выгрузку, после Unhook
следует послать потоку любое сообщение (обычно это WM_NULL).

Аналогичным поведением обладают и многие другие типы хуков.
--
С уважением, LVT
Re: Статья хорошая, но кое чего не хватает
От: Leonid Troyanovsky  
Дата: 19.09.02 05:06
Оценка: +1
Если ресурсы в библиотеке, проблем нет:
ее hinstance можно узнать в dllmain,
а, например, в Дельфи есть такая глобальная
переменная.
Ну, и при желании можно получить свой базовый
адрес из адреса любой экспортируемой функции.
--
С уважением, LVT
благодарю
От: Аноним  
Дата: 23.10.01 02:01
Оценка:
Спасибо за перевод ребята. оч помогли разобраться с Х.
с уважением ^k|/|/\/\eP
Спасибо и пара идей
От: Trip0ut  
Дата: 26.11.01 03:55
Оценка:
Отличная статья.
Хочется добавить что через memory mapped file поддержать единые данные тоже можно.
По поводу коммуникации в рамках одного ДЛЛ, но в разных адресных пространствах. Если стоят хуки на сообщения и они завязаны на определённые threads можно между хуками (threadами соответственно) перебрасываться registred messages. После получения и перехвата оных в любом thread по желанию совершать operations.
Not tested yet, but seems to be working.
Статья хорошая, но кое чего не хватает
От: frobenius Россия http://frobenius.maza.ru/codeart
Дата: 30.01.02 23:25
Оценка:
Одна большая проблема состоит в том, что очень часто при юзаньи хуков приходится использовать ресурсы(менюшки, диалоги, etc.), а ведь наша DLL находится в ЧУЖОМ адресном пространстве !
И при использовании GetModuleHandle мы НЕ ПОЛУЧИМ дескриптор DLL !!!
Это будет дескриптор ЧУЖОГО процесса... :)
И LoadMenu(GetModuleHandle(NULL), IMD_DLLMENU, ......) даст нам (если даст) ЧУЖОЕ меню !!!
Поэтому единственный путь здесь — это отлавливать в DllMain момент загрузки DLL и сохранять значение DLLhinst...
Передача пары параметров хуковой процедуре
От: Leonid Troyanovsky  
Дата: 19.09.02 05:23
Оценка:
При использовании WH_GETMESSAGE, как и некоторых
других типов хуков, можно передать хуковой процедуре
пару параметров, например,hook и хендл окна, получающего ответные сообщения.
Для WH_GETMESSAGE это wParam, lParam в отправляемом
для установки хука сообщении.
Для многих случаев это позволяет обойтись без
разделяемых секций (создавать которые, например, с
помощью Дельфи затруднительно) или memory mapped file.
--
С уважением, LVT
Установка хука на единичное сообщение
От: Leonid Troyanovsky  
Дата: 19.09.02 05:57
Оценка:
Иногда бывает полезен следующий прием:
хук устанавливается на обработку единичного
сообщения после обработки которого сразу же
снимается. Заметим, что в этом случае нет нужды в обработке цепочки хуков, т.е. CallNextHookEx.

Вот пример (Дельфи) для получения имени исполнимого файла по хендлу окна.

procedure QryName(threadID: DWord; Caller: HWND); external 'lib0.dll';

procedure TForm1.WMCopydata(var msg: TMessage); // message WM_COPYDATA;
begin
Caption := PChar(PCopyDataStruct(Pointer(msg.LParam)).lpData);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ahwnd: THandle;
begin
{Ищем по заголовку}
ahwnd := FindWindow(nil, PChar(Edit1.Text));
if ahwnd <> 0 then
QryName(GetWindowThreadProcessID(ahwnd, nil), Handle);
end;

--- lib0.dpr ---

library lib0;

uses
Messages,
Windows;

function Answer( nCode: Integer; wprm: WParam; lprm: LParam): LResult;
stdcall;
type
PMsg = ^TMsg;
var
buffer : array [0..MAX_PATH] of Char;
cd : TCopyDataStruct;
msg : PMsg;
Caller : HWND;
AHook: HHook;
begin
Result := 0;
msg := PMsg(lprm);
if (msg.Message = 0) and (msg.LParam <> 0) then
begin
AHook := msg.lParam;
Caller := msg.wParam;
cd.cbData := GetModuleFileName(0, buffer, SizeOf(buffer))+1;
cd.lpData := @buffer;
cd.dwData := GetCurrentThreadID;
SendMessage(Caller, WM_COPYDATA, 0, LParam(@cd));
UnHookWindowsHookEx(AHook);
PostThreadMessage(GetCurrentThreadID, 0, 0, 0);
end;
end;

procedure QryName(tid: DWord; Caller: HWND);
var
AHook : Hhook;
begin
AHook := SetWindowsHookEx(WH_GETMESSAGE, Answer, Hinstance, tid);
if AHook <> 0 then
PostThreadMessage(tid, 0, Caller, AHook);
end;

exports
QryName;

begin
end.
--
С уважением, LVT
Re: Dr. Joseph M. Newcomer "Хуки и DLL"
От: YVR  
Дата: 12.09.03 10:03
Оценка:
Фрагмент кода из статьи:
static LRESULT CALLBACK msghook(int nCode, WPARAM wParam, LPARAM lParam)
   {
    // If the value of nCode is < 0, just pass it on and return 0
    // this is required by the specification of hook handlers
    // Если значение nCode < 0, просто передаем его дальше и возвращаем 0
    // этого требует спецификация обработчиков хуков
    if(nCode < 0)
      { /* передаем дальше */
       CallNextHookEx(hook, nCode,
                   wParam, lParam);
       return 0;
      } /* передаем дальше */

     // <...>

    // Передаем сообщение следующему хуку
    return CallNextHookEx(hook, nCode, 
                       wParam, lParam);
   } // msghook

В соответствии со документацией
для CallWndProc, CallWndRetProc, ForegroundIdleProc, GetMsgProc:

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

для CBTProc, DebugProc, JournalPlaybackProc, JournalRecordProc, KeyboardProc, LowLevelKeyboardProc, LowLevelMouseProc, MessageProc, MouseProc, ShellProc, SysMsgProc:

If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

Таким образом:
static LRESULT CALLBACK msghook(int nCode, WPARAM wParam, LPARAM lParam)
   {
    if(nCode < 0)
       return CallNextHookEx(hook, nCode,
                   wParam, lParam);

     // <...>
   } // msghook

Народ пользуется текстом статьи, не сверяясь с документацией.
Надо бы поправить
Re[2]: Dr. Joseph M. Newcomer "Хуки и DLL"
От: AntiFriz  
Дата: 02.03.04 23:56
Оценка:
Хотел бы отметить, что все ссылки не рабочие.
Он успел переехать сюда http://www.flounder.com/hooks.htm (спасибо гуглю )
Re[2]: Dr. Joseph M. Newcomer "Хуки и DLL"
От: Lexey Россия  
Дата: 09.03.04 14:40
Оценка:
Здравствуйте, YVR, Вы писали:

YVR>Народ пользуется текстом статьи, не сверяясь с документацией.

YVR>Надо бы поправить

Это к автору. Я за что купил, за то и продаю. AFAIR, эта ошибка, кстати, там не единственная.
... << RSDN@Home 1.1.3 stable >>
Re: Dr. Joseph M. Newcomer "Хуки и DLL"
От: DmitriyGolovin  
Дата: 07.07.06 08:01
Оценка:
Здравствуйте, Lexey (перевод), Вы писали:

LП>Статья :

LП>Хуки и DLL
Автор(ы): Dr. Joseph M. Newcomer
Дата: 25.04.2001
Статья посвящена реализации глобальных хуков. В ней рассматриваются типичные проблемы, связанные
с различием виртуальных адресов перехватывающей DLL в адресных пространствах различных процессов, описывается
способ создания разделяемого сегмента данных, приводится пример DLL, реализующей глобальный хук.


LП>Авторы :

LП>Lexey (перевод)

LП>Аннотация :

LП>Статья посвящена реализации глобальных хуков. В ней рассматриваются типичные проблемы, связанные
LП>с различием виртуальных адресов перехватывающей DLL в адресных пространствах различных процессов, описывается
LП>способ создания разделяемого сегмента данных, приводится пример DLL, реализующей глобальный хук.

А подскажите, пожалуйста, есть ли возможность повесить хук на приложение запущенное под другим пользователем?
Re: Dr. Joseph M. Newcomer "Хуки и DLL"
От: Serjio Россия  
Дата: 20.10.06 07:19
Оценка:
>приводится пример DLL, реализующей глобальный хук

а что это переменная HHOOK hook; не зашарена ?
как же он передает ее значение в DllMain/clearMyHook/UnhookWindowsHookEx и msghook/CallNextHookEx
эти вызовы же выполняются в иных адресных пространствах
Только на РСДН помимо ответа на вопрос, можно получить еще список орфографических ошибок и узнать что-то новое из грамматики английского языка (c) http://www.rsdn.ru/forum/cpp/4720035.1.aspx
Автор: ZOI4
Дата: 28.04.12
Re[2]: Dr. Joseph M. Newcomer "Хуки и DLL"
От: Andrew S Россия http://alchemy-lab.com
Дата: 20.10.06 09:18
Оценка:
>>приводится пример DLL, реализующей глобальный хук

S>а что это переменная HHOOK hook; не зашарена ?

S>как же он передает ее значение в DllMain/clearMyHook/UnhookWindowsHookEx и msghook/CallNextHookEx
S>эти вызовы же выполняются в иных адресных пространствах

Я про это уже писал, народ никак не реагирует .
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Dr. Joseph M. Newcomer "Хуки и DLL"
От: Conr Россия  
Дата: 20.10.06 10:24
Оценка:
Здравствуйте, Andrew S, Вы писали:

>>>приводится пример DLL, реализующей глобальный хук


AS>Я про это уже писал, народ никак не реагирует .

А он уже сам давно накололся и запомнил, что так низзя Кстати у Рихтера, насколько я помню, тоже этот недочет есть.
Re[4]: Dr. Joseph M. Newcomer "Хуки и DLL"
От: Andrew S Россия http://alchemy-lab.com
Дата: 20.10.06 10:54
Оценка:
>>>>приводится пример DLL, реализующей глобальный хук

AS>>Я про это уже писал, народ никак не реагирует .

C>А он уже сам давно накололся и запомнил, что так низзя Кстати у Рихтера, насколько я помню, тоже этот недочет есть.

Имеется в виду команда rsdn. У Рихтера — все нормально.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.