![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите с hook'ом клавиатуры. [D6, Win2k]
axx © (2005-04-14 11:51:00)Проблема в следующем цепляю библиотеку (см. ниже) к своей программе стоит минуту а потом вылетает (Память не может быть рид. и тд и тп). Отцепляю библиотеку все нормально работает.
Не вижу я тут ошибки - может плохо смотрю ????
Если кто видит ткните плиз пальцем :-) а то уже второй день сижу над этим.
--------------------------------
library KeyLHook;
uses Windows,Messages;
{$R *.res}
const MMFName:PChar='KeyMMF';
type
PGlobalDLLData=^TGlobalDLLData;
TGlobalDLLData=packed record
SysHook:HWND;
MyAppWnd:HWND;
end;
var
GlobalData:PGlobalDLLData;
MMFHandle:THandle;
function KeyboardProc(code:integer; wParam:word; lParam:longint):longint;stdcall;
var
CtrlDown:Boolean;
State:TKeyboardState;
begin
if (Code<0) or (wParam=PM_NOREMOVE) then
begin
Result:=CallNextHookEx(GlobalData^.SysHook,Code,wParam,дParam);
exit;
end;
GetKeyboardState(State);
CtrlDown:=((State[vk_Control] and 128)<>0);
if (TMsg(Pointer(lParam)^).hwnd=VK_LWIN) or
(TMsg(Pointer(lParam)^).hwnd=VK_RWIN) or
(TMsg(Pointer(lParam)^).hwnd=VK_MENU) or
((TMsg(Pointer(lParam)^).hwnd=VK_ESCAPE) and (CtrlDown)) or
((TMsg(Pointer(lParam)^).hwnd=VK_ESCAPE) and ((KF_ALTDOWN and TMsg(Pointer(lParam)^).wParam)=0)) or
((TMsg(Pointer(lParam)^).hwnd=VK_TAB) and ((KF_ALTDOWN and TMsg(Pointer(lParam)^).wParam)=0) )
then
begin
if (wParam=WM_SYSKEYDOWN) or (wParam=WM_KEYDOWN) then
begin
MessageBeep(0);
Result:=1;
lParam);
end else result:=CallNextHookEx(GlobalData^.SysHook,Code,wParam,lParam);
end else result:=CallNextHookEx(GlobalData^.SysHook,Code,wParam,lParam);
end;
procedure hook(switch:Boolean; hMainProg:HWND)export;stdcall;
begin
if switch=true then
begin
GlobalData^.SysHook:=SetWindowsHookEx(13,@KeyboardProc,HInstance,0);
GlobalData^.MyAppWnd:=hMainProg;
end else UnhookWindowsHookEx(GlobalData^.SysHook);
end;
procedure OpenGlobalData();
begin
MMFHandle:=CreateFileMapping(INVALID_HANDLE_VALUE,nil,PAGE_READWRITE,0,SizeOf(TGlobalDLLData),MMFName);
if MMFHandle=0 then Exit;
GlobalData:=MapViewOfFile(MMFHandle,FILE_MAP_ALL_ACCESS,0,0,SizeOf(TGlobalDLLData));
if GlobalData = nil then CloseHandle(MMFHandle);
end;
procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;
procedure DLLEntryPoint(dwReason: DWord); stdcall;
begin
case dwReason of
DLL_PROCESS_ATTACH:OpenGlobalData;
DLL_PROCESS_DETACH:CloseGlobalData;
end;
end;
exports hook;
begin
DLLProc:=@DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
mgcr (2005-04-14 18:37:00) [1]alpet © (14.04.05 18:31) [28]
Хук - это принадлежность Desktop'а. Если такого флага не установлено, то глобальные хуки могут создавать только процессы с той же учетной записью, что и процесс, создавший Desktop.
Если флаг установлен, то хуки могут создавать процессы, у которых тот же десктоп, но учетная запись отлична от учетной записи создателя десктопа. Например, десктоп Default с таким флагом создает Winlogon, чтобы пользовательские процессы моги устанавливать хуки.
alpet (2005-04-14 18:31:00) [2]2 mgcr
У функции CreateDesktop есть параметр dwFlags, передавая в который DF_ALLOWOTHERACCOUNTHOOK можно получить:
"Enables processes running in other accounts on the desktop to set hooks in this process."
Я не совсем понимаю - для какого процесса можно будет устанавливать ловушки - создавшего десктоп или все запускаемые в этом десктопе.
mgcr (2005-04-14 16:58:00) [3]Digitman © (14.04.05 16:52) [26]
Термин "Глобальный хук" используется в MSDN, для противопоставления его Thread-scope хуку. На самом деле, хуков, как мы с тобой знаем, всего два типа - активных в рамках потока (на что есть соответствующая структура у потока) и у рабочего стола (на что тоже есть соответствующая структура).
То есть, с точки зрения доступа из сервисов, например, глобальность тут же пропадает, так как десктоп у них совсем другой.
Это я не тебе, конечно, рассказываю, а народу, который еще не знает.
Впрочем, о чем тут, собственно, говорить, если есть не совсем грамотный код в нулевом посте и ссылки на не совсем грамотную статью :)
Digitman (2005-04-14 16:52:00) [4]
> не являются глобальными хуками
и действительно - хотя бы в станд.справке от Борланда нет никаких "глобальных" хуков ... есть system-scope, есть thread-scope, есть system-or-thread-scope хуки .. а "глобальных" нет и в помине.
Eraser (2005-04-14 16:49:00) [5]mgcr ©
Куда ты внедряться собрался при помощи этих хуков, в Win32k.sys ?
Не! Вндряться я никуда не собираюсь, времени нету ))
Digitman (2005-04-14 16:47:00) [6]
> mgcr © (14.04.05 16:36) [21]
вполне логично.
И., ты бы не мне - ты бы это автору втолковал, ибо у негопроблемы ... ч.н., "на огурцах") ..
mgcr (2005-04-14 16:46:00) [7]Eraser © (14.04.05 16:42) [22]
>
> Иными словами внедрение по Рихтеру, такими хуками не сделаешь?
Нет конечно. Куда ты внедряться собрался при помощи этих хуков, в Win32k.sys ? Ну, удачи тебе.
Eraser (2005-04-14 16:42:00) [8]mgcr ©
This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.
Иными словами внедрение по Рихтеру, такими хуками не сделаешь?
mgcr (2005-04-14 16:36:00) [9]GuAV © (14.04.05 15:22) [13]
Digitman © (14.04.05 15:25) [14]
Все очень просто - WH_JOURNAL и _LL хуки не являются глобальными хуками. Они все работают с RawInputThread, поэтому им нет необходимости быть в контексте разных процессов.
Eraser (2005-04-14 16:20:00) [10]Блин... сам себе сообщение отправил...
[19] ->> axx
Eraser (2005-04-14 16:19:00) [11]Eraser
A global hook monitors messages for all threads in the same desktop as the calling thread. A thread-specific hook monitors messages for only an individual thread. A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate dynamic-link library (DLL) module. A thread-specific hook procedure is called only in the context of the associated thread. If an application installs a hook procedure for one of its own threads, the hook procedure can be in either the same module as the rest of the application's code or in a DLL. If the application installs a hook procedure for a thread of a different application, the procedure must be in a DLL.
А в описании процедуры хука смотришь это global hook или thread-specific hook.
ANB (2005-04-14 16:16:00) [12]
> Digitman © (14.04.05 15:05) [12]
а я ведь тоже с этой статьи пример брал и нарвался на такую же ошибку.
Модераторы - уберите ее.
ANB (2005-04-14 16:15:00) [13]В RSDN ищешь по WH_JOURNALRECORD - и самой первой вылезает статья про хуки. Там четко расписано, какие в DLL, какие можно в приложении.
Digitman (2005-04-14 15:49:00) [14]
> GuAV © (14.04.05 15:40) [15]
> В MSDN не нашел списка
ЩАС тебе мелкомягкие список выложат !) ... вот ты раскатал) ..
> В том какой хук требует расположения в DLL разобратся сложно
сложно, но можно.
берешь конкретный тип хука и изучаешь ВСЮ доступную док-цию, прежде чем делать какие-то умозаключения ... уж не говоря о бездумном сдирании сомнительного рода "примеров"
GuAV (2005-04-14 15:40:00) [15]Я спрашиваю про другие неточности.
В том какой хук требует расположения в DLL разобратся сложно. В MSDN не нашел списка, более того в справке по SetWindowsHookEx (msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/setwindow shookex.asp) написано:
...
HHOOK SetWindowsHookEx( int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
...
lpfn
[in] Pointer to the hook procedure. If the dwThreadId parameter is zeroor specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL).Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
Digitman (2005-04-14 15:25:00) [16]
> спасибо, а ещё ?
тот же самый - текущий - сабж...
т.е. WH_KEYBOARD_LL ..
сюда же смело можешь добавить WH_MOUSE_LL
GuAV (2005-04-14 15:22:00) [17]Digitman © (14.04.05 15:05) [13]
нашёл:
Systemwide filter functions must reside in a DLL. ... The journal hooks, WH_JOURNALRECORD and WH_JOURNALPLAYBACK, are exceptions to this rule. ...
спасибо, а ещё ?
Digitman (2005-04-14 15:05:00) [18]
> Lin7 (14.04.05 14:30) [10]
> что в этой статье не так?
хотя бы вот это :
Подчеркну это обстоятельство ещё раз: глобальные ловушки могут располагаться только в DLL, но никак не в EXE файлах !
это - вранье, снабженное самоуверенным воскл.знаком.
system-wide-хук system-wide-хуку - рознь.
автор не удосужился изучить и опробовать в реальном коде материал, касающийся system-wide-хуков как таковых, а уже делает безапелляционные рекомендации.
> GuAV © (14.04.05 14:43) [11]
> где враньё в самой статье ?
см.выше.
GuAV (2005-04-14 14:43:00) [19]Digitman © (14.04.05 12:19) [6]
вранья в этой статье предостаточно
Код к статье не очень хороший - это правда, а вот где враньё в самой статье ?
Lin7 (2005-04-14 14:30:00) [20]
> Digitman © (14.04.05 12:19) [6]
>
> вранья в этой статье предостаточно
Вранья или мелких опечяток?
Я начинал изучать хуки по этой статье и они работали. Можно для общего развития узнать, что в этой статье не так?