Hooks

Now, it is time to consider a powerful tool most frequently used for debugging programs. This is the hooks (sometimes called traps) mechanism. The idea of this mechanism is that the programmer can trace the messages both within a single application and within the framework of the entire system by introducing filters. Filters are classified as global (in force within the entire system) or local (in force only within the framework of a single process). Working with filters, it is necessary to bear in mind that they can considerably slow down the operation of the entire system. This is especially true for global filters. From the programming point of view, this mechanism defines a function called by the system if a specific event occurs. It is also possible to describe messages that arrive to the filter function.

Consider some tools for working with filters. The main types of filter messages are as follows :

  • WH_CALLWNDPROC The filter is triggered when the SendMessage function is called.

  • WH_CALLWNDPROCRET The filter is triggered when the SendMessage function returns control.

  • WH_CBT The message arrives when something happens to the window.

  • WH_DEBUG This message is sent before a message is sent to some other filter.

  • WH_GETMESAGE This filter is triggered when the GetMessage function receives some message from the queue.

  • WH_JOURNALRECORD This message arrives to the filter procedure when the system deletes a message from the queue.

  • WH_JOURNALPLAYBACK This message is sent after the arrival of the WH_JOURNALRECORD message.

  • WH_KEYBOARD This message arrives when keyboard events occur.

  • WH_MOUSE This is similar to the previous message but relates to mouse events.

  • WH_MSGFILTER This message arrives if user input events have occurred to a dialog box, menu, or scroll bar before these events were handled within this process.

  • WH_SHELL This filter is triggered when something happens to the Windows shell.

  • WH_SYSMSGFILTER This is similar to the WH_MSGFILTER message but relates to the entire system.

The filter is set using the SetWindowsHookEx function. Consider the parameters accepted by this function:

  • First parameterThis is the filter type. It can take one of the previously listed values.

  • Second parameterThis is the address of the filter procedure. If you specify a global filter, this procedure must be located in a DLL. The only exceptions are two types of filters: WH_JOURNALRECORD and WH_JOURNALPLAYBACK .

  • Third parameterThis is the DLL handle, provided that the filter is intended for the entire system. The only exceptions are the two previously mentioned filter types.

  • Fourth parameterThis is the thread identifier if you need to trace one of the threads. If the value of this parameter is zero, then a global filter intended for the entire system will be created. In general, the thread can relate to your process or to any other process running in the system.

The SetWindowsHookEx function returns the filter descriptor.

The filter function receives three parameters. The first parameter determines the type of event depending on the filter type. The next two parameters are the pointer to the hook procedure and the handle to the DLL containing that procedure. Because there are several types of events for every hook type, I won't list them here. They can be found in Microsoft's documentation.

After completing the operation, the hook must be closed using the UnhookWindcwsHookEx function, whose only parameter is the handle to the hook that needs to be removed.

In general, a hook is only part of the chain of system calls. Therefore, the programmer must call the callNextHookEx function from the hook procedure. That function will pass the required information along the chain. The first parameter of this function is the handle to the hook. The second, third, and fourth parameters correspond exactly to the three parameters passed to the hook procedure.

Listing 19.2 demonstrates an example of a simple hook that traps all events related to pressing the space bar within the entire system. Note that if the hook is global, the hook procedure must be placed into a DLL.

Listing 19.2: The global hook procedure
image from book
 // The DIAL.RC file for the DLLE.ASM program // Definitions of constants #define WS_SYSMENU       0x00080000L #define WS_MINIMIZEBOX   0x00020000L #define WS_MAXIMIZEBOX   0x000l0000L // Dialog box definition DIAL1 DIALOG 0, 0, 240, 120 STYLE WS_SYSMENU  WS_MINIMIZEBOX  WS_MAXIMIZEBOX CAPTION "An example of program with a hook" FONT 8, "Arial" { } ; The main module - DLLE.ASM, ; which sets a hook in a DLL .586P ; Flat memory model .MODEL FLAT, stdcall ; Constants ; This message arrives when the window is closed WM_CLOSE        equ 10h WM_INITDIALOG   equ 110h WH_KEYBOARD     equ 2 ; Message structure MSGSTRUCT STRUC         MSHWND      DD ?         MSMESSAGE   DD ?         MSWPARAM    DD ?         MSLPARAM    DD ?         MSTIME      DD ?         MSPT        DD ? MSGSTRUCT ENDS ; Prototypes of external procedures IFDEF MASM ; MASM         EXTERN      UnhookWindowsHookEx@4:NEAR         EXTERN      SetWindowsHookExA@16:NEAR         EXTERN      EndDialog@8:NEAR         EXTERN      DialogBoxParamA@20:NEAR         EXTERN      GetProcAddress@8:NEAR         EXTERN      LoadLibraryA@ 4:NEAR         EXTERN      FreeLibrary@4:NEAR         EXTERN      ExitProcess@4:NEAR         EXTERN      MessageBoxA@16:NEAR ; INCLUDELIB directives for the linker         includelib c:\masm32\lib\user32.lib         includelib c:\masm32\lib\kernel32.lib ELSE         EXTERN      UnhookWindowsHookEx:NEAR         EXTERN      SetWindowsHookExA:NEAER         EXTERN      EndDialog:NEAR         EXTERN      DialogBoxParamA:NEAR         EXTERN      GetProcAddress:NEAR         EXTERN      LoadLibraryA:NEAR         EXTERN      FreeLibrary:NEAR         EXTERN      ExitProcess:NEAR         EXTERN      MessageBoxA:NEAR         UnhookWindowsHookEx@4 = UnhookWindowsHookEx         SetWindowsHookExA@16 = SetWindowsHookExA         EndDialog@8 = EndDialog         DialogBoxParamA@20 = DialogBoxParamA         GetProcAddress@8 = GetProcAddress         LoadLibraryA@4 = LoadLibraryA         FreeLibrary@4 = FreeLibrary         ExitProcess@4 = ExitProcess         MessageBoxA@16 = MessageBoxA ; INCLUDELIB directives for the linker         includelib c:\tasm32\lib\import32.lib ENDIF ;------------------------------------------------- ; Data segment _DATA SEGMENT         MSG       MSGSTRUCT <?>         HINST     DD 0 ; Application descriptor         PA        DB "DIAL1", 0         LIBR      DB 'DLL2.DLL', 0         HLIB      DD ?         APROC     DD ?         HH        DD ?         ATOH      DD ? IFDEF MASM         NAMEPROC  DB' _HOOK@0', 0         NAMEPROC1 DB' _TOH@0', 0 ELSE         NAMEPROC1 DB '_TOH', 0         NAMEPROC  DB 'HOOK', 0 ENDIF _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Load the DLL         PUSH  OFFSET LIBR         CALL  LoadLibraryA@4         CMP   EAX, 0         JE   _EXIT         MOV   HLIB, EAX ; Get the address of the hook procedure         PUSH  OFFSET NAMEPROC         PUSH  HLIB         CALL  GetProcAddress@8         CMP   EAX, 0         JE    _EXIT         MOV   APROC, EAX ; Get the address of the auxiliary procedure         PUSH  OFFSET NAMEPROC1         PUSH  HLIB         CALL  GetProcAddress@8         CMP   EAX, 0         JE    _EXIT         MOV   ATOH, EAX ; Install the hook         PUSH  0         PUSH  HLIB         PUSH  APROC         PUSH  WH_KEYBOARD         CALL  SetWindowsHookExA@16         MOV   HH, EAX ; Store the hook and pass it to the library         MOV   EAX, ATOH         PUSH  HH         CALL  ATOH ; Open the dialog         PUSH  0         PUSH  OFFSET WNDPROC         PUSH  0         PUSH  OFFSET PA         PUSH  [HINST]         CALL  DialogBoxParamA@20 ; Remove the hook         PUSH  HH         CALL  UnhookWindowsHookEx@4 ; Close the library ; The library will close automatically ; when exiting the program         PUSH  OFFSET NAMEPROC         PUSH  HLIB         CALL  FreeLibrary@4 ; Exit _EXIT:         PUSH  0         CALL  ExitProcess@4 ; Window procedure ; Position of parameters in the stack ; [BP+014H]  ; LPARAM ; [BP+10H]   ; WAPARAM ; [BP+0CH]   ; MES ; [BP+8]     ; HWND WNDPROC   PROC         PUSH  EBP         MOV   EBP, ESP         PUSH  EBX         PUSH  ESI         PUSH  EDI ;-----------------         CMP   DWORD PTR [EBP+0CH], WM_CLOSE         JNE   L1         PUSH  0         PUSH  DWORD PTR [EBP+08H]         CALL  EndDialog@8         JMP   FINISH L1:         CMP   DWORD PTR [EBP+0CH], WM_INITDIALOG         JNE   FINISH FINISH:         POP   EDI         POP   ESI         POP   EBX         POP   EBP         MOV   EAX, 0         RET   16 WNDPROC    ENDP _TEXT ENDS END START ; The DLL2.ASM DLL ; containing the hook procedure .586P ; Flat memory model IFDEF MASM    .MODEL FLAT stdcall ELSE    .MODEL FLAT ENDIF PUBLIC HOOK, TOH ; Constants ; These messages arrive when ; the DLL is opened DLL_PROCESS_DETACH    equ 0 DLL_PROCESS_ATTACH    equ 1 DLL_THREAD_ATTACH     equ 2 DLL_THREAD_DETACH     equ 3 IFDEF MASM ; MASM ; Prototypes of external procedures         EXTERN      CallNextHookEx@16:NEAR         EXTERN      MessageBoxA@16:NEAR ; INCLUDELIB directives for the linker         includelib c:\masm32\lib\user32.lib         includelib c: \masm32\lib\kernel32.lib ELSE ; TASM         EXTERN      CallNextHookEx:NEAR         EXTERN      MessageBoxA:NEAR         CallNextHookEx@16 = CallNextHookEx         MessageBoxA@16 = MessageBoxA         includelib c:\tasm32\lib\import32.lib ENDIF ;----------------------------------------------- ; Data segment _DATA SEGMENT         HDL   DD ?         HHOOK DD ?         CAP   DB "Hook message", 0         MES   DB "Blank key is pressed", 0 _DATA ENDS ; Code segment _TEXT SEGMENT ; [EBP+10H],  ; Reserved parameter ; [EBP+0CH]   ; Cause of call ; [EBP+8]     ; DLL identifier DLLENTRY:         MOV   EAX, DWORD PTR [EBP+0CH]         CMP   EAX, 0         JNE   D1 ; Close the library         JMP   _EXIT D1:         CMP   EAX, 1         JNE   _EXIT ; Open the library ; Store the DLL identifier         MOV   EDX, DWORD PTR [EBP+08H]         MOV   HDL, EDX _EXIT:         MOV   EAX, 1         RET   12 ;------------------- TOH PROC EXPORT         PUSH  EBP         MOV   EBP, ESP         MOV   EAX, DWORD PTR [EBP+08H]         MOV   HHOOK, EAX         POP   EBP         RET TOH ENDP ; Hook procedure HOOK PROC EXPORT         PUSH  EBP         MOV   EBP, ESP ; Send the message along the chain         PUSH  DWORD PTR [EBP+010H]         PUSH  DWORD PTR [EBP+0CH]         PUSH  DWORD PTR [EBP+08H]         PUSH  HHOOK         CALL  CallNextHookEx@16 ; Check whether the space bar has been pressed         CMP   DWORD PTR [EBP+0CH], 32         JNE   _EX ; If yes, then display the message         PUSH  0 ; MB_OK         PUSH  OFFSET CAP         PUSH  OFFSET MES         PUSH  0 ; In the window         CALL  MessageBoxA@16 _EX:         POP   EBP         RET HOOK ENDP _TEXT ENDS END DLLENTRY 
image from book
 

To translate the program in Listing 19.2, issue the following commands for MASM32:

  • DLL

     ml /c /coff /DMASM dll2.asm     link /subsystem:windows /DLL dll2.obj 
  • Main program

     ml /c /coff /DMMSM dllex.asm     rc dial.rc     link /subsystem:windows dllex.obj dial.res 

    Issue the following commands for TASM32:

  • DLL

     TASM32 /ml dll2.asm     Tlink32 /subsystem:windows -aa -Tpd dll2.obj 
  • Main program

     TASM32 /ml dllex.asm     Brcc32 dial.re     Tlink32 -aa dllex.obj,,,,,dial.res 

When considering the program presented in Listing 19.2, note the role of the TOH procedure. Also note that the second and the third parameters of the hook procedure exactly correspond the values of similar parameters of the WM_KEYDOWN message. By the way, I hope that you understand why two messages are sent when the space bar is pressedone for pressing the button and one for releasing it.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net