Хуки
Если одно приложение, которое калично обрабатывает клик средней кнопки мыши. Я хочу что б мидл клик не доходил до этой программы, а вместо этого хочу выполнять свое действие. Я так понимаю, для этого нужно что б в памяти висел процесс, который будет за этим следить, и нужно использовать функцию SetWindowsHookEx(...). Вот только как не знаю. Помогите ламеру.
Это нужно если делать системный хук, правильно? Мне нужен хук только для одной проги, значит сойдет один екзещник. Есть у кого-то простой пример такого кода?
Потому что если это системный хук, то при перехвате сообщения это сообщение может находиться в другом процессе, надо чтобы обработчик находился в памяти этого процесса, а как загрузить в этот процесс обработчик, самый простой медот это дллка, когда ты ставишь хук (глобальный), то твоя дллка грузится во все процессы системы
Повторяю, нужен хук только для одного процесса. Не нужно грузить его во все процессы системы. Я нашел пример работы с хуками через dll, не мне это не нужно. Нужен пример, когда хук находится в exe-шнике.
Ну так без dll работает тока в твоем процессе. Ты можешь проверять тот ли это процесс, но тебе в любом случае придется ставить глобальный хук.
[quote=@pixo $oft]А то,что exe'шники могут экспортировать функции,вы,видимо,забыли?[/quote]
Да, только придется писать чтото вроде импорта из себя....
А помойму лучше юзать DLL.
int idHook, // type of hook to install
HOOKPROC lpfn, // address of hook procedure
HINSTANCE hMod, // handle of application instance
DWORD dwThreadId // identity of thread to install hook for
);
hMod
Identifies the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
И чтоже надо запихивать в стек в 3-м параметре???
invoke SetWindowsHookEx,WH_CALLWNDPROCRET,eax,?????,0h
А если обработчик в DLL'ке, то тогда чей адрес во втором параметре???
4-й параметр должен быть = NULL - все процессы!
С Новым Годом!!!
.model flat, stdcall
option casemap :none
include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\user32.inc
include E:\masm32\include\advapi32.inc
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\advapi32.lib
.const
my_title db "My DLL",0
mes db "It is a message from my first DLL!!!",0
.data?
hInstance dd ?
.code
LibMain proc instance:DWORD,reason:DWORD,unused:DWORD
mov al,1
ret 12
LibMain endp
MesBoxy proc
comment @
push MB_OK
push offset my_title
push offset mes
push 0
call MessageBox
@
ret
MesBoxy endp
end LibMain
Dll'ка очень простая!
Вот код exe'шника со всеми комментариями:
.model flat, stdcall
option casemap :none
include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\user32.inc
include E:\masm32\include\advapi32.inc
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\advapi32.lib
includelib dll.lib
extrn _imp__MesBoxy@0:dword
MesBoxy equ _imp__MesBoxy@0
.data
class_name db 'window',0
window_name db 'win32 application',0
dll_way db "dll.dll",0
wc WNDCLASSEX <4*12,CS_HREDRAW or CS_VREDRAW,offset win_proc,0,0,?,?,?,COLOR_WINDOW+1,0,offset class_name,0>
.data?
msg_ MSG <>
hook_handle db 4h dup(?)
.code
_start:
jmp over
my_hook proc
;call MesBoxy
ret
my_hook endp
over:
;call MesBoxy
invoke LoadLibrary,offset dll_way
comment @
cmp eax,0h
je go
invoke MessageBox,0h,offset class_name,offset window_name,MB_OK
go:
@
invoke SetWindowsHookEx,WH_CALLWNDPROCRET,offset my_hook,eax,0h
;invoke SetWindowsHookEx,WH_CALLWNDPROCRET,offset MesBoxy,eax,0h
comment @
;mov eax,0h
cmp eax,0h
jne gogogo
invoke MessageBox,0h,offset class_name,offset window_name,MB_OK
jmp gogogo2
gogogo:
;mov esi,offset hook_handle
;mov dword ptr ds:[esi],eax
;invoke UnhookWindowsHookEx,eax
gogogo2:
@
xor ebx,ebx
push ebx
call GetModuleHandle
mov esi,eax
mov dword ptr wc.hInstance,eax
push IDI_APPLICATION
push ebx
call LoadIcon
mov wc.hIcon,eax
push IDC_ARROW
push ebx
call LoadCursor
mov wc.hCursor,eax
push offset wc
call RegisterClassEx
mov ecx,CW_USEDEFAULT
push ebx
push esi
push ebx
push ebx
push ecx
push ecx
push ecx
push ecx
push WS_OVERLAPPEDWINDOW
push offset window_name
push offset class_name
push ebx
call CreateWindowEx
push eax
;push SW_HIDE
push SW_SHOW
push eax
call ShowWindow
call UpdateWindow
mov edi,offset msg_
message_loop:
push ebx
push ebx
push ebx
push edi
call GetMessage
test eax,eax
jz exit_msg_loop
push edi
call TranslateMessage
push edi
call DispatchMessage
jmp short message_loop
exit_msg_loop:
push ebx
call ExitProcess
win_proc proc
push ebp
mov ebp,esp
wp_hWnd equ dword ptr [ebp+08h]
wp_uMsg equ dword ptr [ebp+0Ch]
wp_wParam equ dword ptr [ebp+10h]
wp_lParam equ dword ptr [ebp+14h]
cmp wp_uMsg,WM_DESTROY
jne not_wm_destroy
push 0
call PostQuitMessage
jmp short end_wm_check
not_wm_destroy:
leave
jmp DefWindowProc
end_wm_check:
leave
ret 16
win_proc endp
comment @
my_hook proc
eeee:
ret
my_hook endp
@
end _start
В чём суть проблемы:
Функция в dll'ке грузится:
call MesBoxy
работает!
HOOK даже ставится!
invoke SetWindowsHookEx,WH_CALLWNDPROCRET,offset MesBoxy,eax,0h
Вопрос:
Каким должен быть второй параметр!?
И почему в данном случае комп виснет просто от всего этого!?
и загружать свою либу лучше через LoadLibrary (париться в Lib файлами просто геморрой!)
Могу вызвать:
call MesBoxy
Просто для обработки внешних событий это не прокатывает!
invoke LoadLibrary,offset dll_way
invoke SetWindowsHookEx,WH_CALLWNDPROCRET,offset MesBoxy,eax,0h
Комп виснет от этого!
проверяй значение eax, если равно нулю, то дллка не загрузилась
.model flat, stdcall
option casemap :none
include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\user32.inc
include E:\masm32\include\advapi32.inc
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\advapi32.lib
includelib dll.lib
extrn _imp__MesBoxy@0:dword
MesBoxy equ _imp__MesBoxy@0
.data
dll_way db "dll.dll",0
.data?
msg_ MSG <>
hook_handle db 4h dup(?)
hook_proc_handle db 4h dup(?)
.code
_start:
invoke Beep,300h,20h
;call MesBoxy Можно её вызвать - работает так!
;invoke ExitProcess,0h
invoke LoadLibrary,offset dll_way
mov esi,offset hook_handle
mov dword ptr ds:[esi],eax ; Проверял - возвращает не ноль!
invoke SetWindowsHookEx,WH_KEYBOARD,offset MesBoxy,offset hook_handle,0h
mov esi,offset hook_proc_handle
mov dword ptr ds:[esi],eax ; Тоже проверял - тоже возвращает не ноль!
;?????????????? Что делать? Не работает! Ни на что не реагирует!
hook_loop:
invoke GetMessage,offset msg_,0h,0h,0h
cmp eax,0h
je exit_hook_loop
cmp eax,WM_KEYUP
jne gogo
call MesBoxy
gogo:
invoke Beep,300h,20h
jmp hook_loop
exit_hook_loop:
invoke ExitProcess,0h
end _start
Окон я в этот раз создавать не стал. А смысл? Ведь обработчик глобальный!
иы передаёшь хендл либы загруженной во второй раз и функцию передаёшь и первой либы, тебе надо получить адрес твоей функции из второй либы через GetProcAddress
int idHook, // type of hook to install
HOOKPROC lpfn, // address of hook procedure
HINSTANCE hMod, // handle of application instance
DWORD dwThreadId // identity of thread to install hook for
);
hMod - это handle DLL'ки.
lpfn - это GetProcAddress определяет!
Спасибо! Попробую! Напишу как получится!
иы передаёшь хендл либы загруженной во второй раз и функцию передаёшь и первой либы, тебе надо получить адрес твоей функции из второй либы через GetProcAddress
У меня 1-на DLL'ка, которая динамически какбы присоединяется к исполняемому exe'шнику! В каком смясле я её гружу 2 раза?
P.S.
Спасибо за идею с GetProcAddress!
Так изначально так и надо было - а иначе начисто отпадает необходимость использовать LoadLibrary
У меня 1-на DLL'ка, которая динамически какбы присоединяется к исполняемому exe'шнику! В каком смясле я её гружу 2 раза?
первый раз её грузит PE загрузчик а во второй раз ты её сам грузишь через LoadLibrary в памяти будет две копии твоей длл
Две копии ее не будет - винда не грузит заново dll даже в разных приложениях. Просто меняются виртуальные адреса.
Наверное, WM_KEY_UP и WM_KEY_DOWN!
.model flat, stdcall
option casemap :none
include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\user32.inc
include E:\masm32\include\advapi32.inc
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\advapi32.lib
includelib dll.lib
extrn _imp__MesBoxy@0:dword
MesBoxy equ _imp__MesBoxy@0
.data
_1_ db "1",0
_2_ db "2",0
_3_ db "3",0
dll_way db "dll.dll",0
function_name db "MesBoxy",0
.data?
msg_ MSG <>
hook_handle db 4h dup(?)
hook_proc_handle db 4h dup(?)
.code
_start:
invoke Beep,300h,20h
;call MesBoxy
;invoke ExitProcess,0h
invoke LoadLibrary,offset dll_way
cmp eax,0h
jne gg
invoke MessageBox,0h,offset _1_,offset dll_way,MB_OK
gg:
mov esi,offset hook_handle
mov dword ptr ds:[esi],eax
invoke GetProcAddress,eax,offset function_name
cmp eax,0h
jne gog
invoke MessageBox,0h,offset _2_,offset dll_way,MB_OK
gog:
mov edx,dword ptr ds:[esi]
;invoke SetWindowsHookEx,WH_KEYBOARD,eax,offset hook_handle,0h
invoke SetWindowsHookEx,WH_KEYBOARD,eax,edx,0h
cmp eax,0h
jne goog
invoke MessageBox,0h,offset _3_,offset dll_way,MB_OK
goog:
mov esi,offset hook_proc_handle
mov dword ptr ds:[esi],eax
hook_loop:
invoke GetMessage,offset msg_,0h,0h,0h
cmp eax,0h
je exit_hook_loop
cmp eax,WM_KEYUP
jne gogo
call MesBoxy
gogo:
invoke Beep,300h,20h
jmp hook_loop
exit_hook_loop:
invoke ExitProcess,0h
end _start
DLL'ка:
.model flat, stdcall
option casemap :none
include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\user32.inc
include E:\masm32\include\advapi32.inc
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\advapi32.lib
.const
my_title db "My DLL",0
mes db "It is a message from my first DLL!!!",0
.data?
hInstance dd ?
.code
LibMain proc instance:DWORD,reason:DWORD,unused:DWORD
mov al,1
ret 12
LibMain endp
MesBoxy proc
push MB_OK
push offset my_title
push offset mes
push 0
call MessageBox
ret
MesBoxy endp
end LibMain
dll.def
EXPORTS MesBoxy