Solved

Keyb Hooks LIST

Posted on 2002-04-23
15
414 Views
Last Modified: 2010-04-04
How can I retrieve a list of keyboard hooks
installed and the respective applications who
called them ?
0
Comment
Question by:bryan7
15 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6964433
create a system debug hook with SetWindowsHookEx with WH_DEBUG

in the DebugProc check if it's a keyboard hook
if wParam = WH_DEBUG then begin
...
check the DEBUGHOOKINFO for idThreadInstaller
that's the thread that installed the hook

getting the application of the thread that installed the hook is another thing
it could even be installed from within a thread created in a dll function which was called from some app :)
about getting the list .. simply add a hook each time you get notified of one
ofcourse check if it's in the list already
I'm assuming you know about system hooks so I won't code it for ya now
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6964435
if wParam = WH_DEBUG then begin

darn .. that should've been
if wParam = WH_KEYBOARD then begin
...
0
 
LVL 3

Author Comment

by:bryan7
ID: 6966760
Hello, thanks for the answer.. however I'm not
that good on hooks ;( I can make a system key hook
in a dll but that's all my knowledge about hooks =(

Can you make the code for me ? I need it to get the list
of all currently set keyboard hooks, I'll add more points
if you wish... I really need this app.

btw, if you know of an already made application that
does that (no need for source) I'll give you the points
too :)

Thanks.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6966981
don't know of such an app
I'll write the code as it's not that much work
when I wake up :)
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 250 total points
ID: 6967468
here's the complete project code
haven't tested it, just compiled it successfully :)
it was a minor change to one of my other hooks so it should work
I'm not shure about the TList being stored in the mmf
if that doesn't work then simply make a static array of cardinal or some record
---------------------------------------------------------

library lnKbdDebugHook;

uses
  Windows, Classes;

{$R *.RES}


const
    WM_USER = $0400;
    WM_lnHOOK = WM_USER + 133;

    errSuccess  = 1;
    errHooked   = 0;
    errUnhooked = 0;
    errCantHook = -1;
    errCantUnHk = -1;

type
  PHookRec = ^THookRec;
  THookRec = packed record
    MainWindow: HWND;
    HookID: HHOOK;
    HookList: TList;
  end;


var
   HookRec: PHookRec = nil;
   hMapObject: THandle = 0;


// hook procedure
function hpWSH(nCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;stdcall;
var lpDHI: PDebugHookInfo;
    I: Integer;
    found: boolean;
begin
     try
        // check if it's a keybd hook and if we should process the message
        if (wParam = WH_KEYBOARD) and (nCode = HC_ACTION) then begin
           lpDHI:=PDebugHookInfo(lParam);
           found:=false;
           // check our list if the threadid exists
           with HookRec^.HookList do begin
             for I:=0 to Count-1 do
                 if Cardinal(Items[I]) = lpDHI^.idThreadInstaller then begin
                    found:=true;
                    break;
                 end;
             // if threadid not found add it to the list
             if not found then
                Add(Pointer(lpDHI^.idThreadInstaller));
           end;

           // notify our main window
           if HookRec^.MainWindow > 0 then
              PostMessage(HookRec^.MainWindow, WM_lnHOOK, wParam, lParam);
        end;
     finally
        Result:=CallNextHookEx(HookRec^.HookID, nCode, wParam, lParam);
     end;
end;

// set the notification window
function SetMainWindow(const hWin: hWND): hWND;stdcall;
begin
     HookRec^.MainWindow:=hWin;
     Result:=hWin;
end;

// start hook
function HookWindoze: Integer;stdcall;
begin
     if HookRec^.HookID = 0 then begin
        HookRec^.HookID:=SetWindowsHookEx(WH_DEBUG, hpWSH, hInstance, 0);
        if HookRec^.HookID = 0 then
           Result:=errCantHook
        else
           Result:=errSuccess;
     end else Result:=errHooked;
end;

// stop hook
function UnhookWindoze: Integer;stdcall;
begin
     if HookRec^.HookID <> 0 then begin
        if UnhookWindowsHookEx(HookRec^.HookID) then
           Result:=errSuccess
        else
           Result:=errCantUnHk;
        HookRec^.HookID:=0;
     end else Result:=errUnhooked;
end;

function GetHookCount: Integer; stdcall;
begin
     try
        Result:=HookRec.HookList.Count;
     except
        Result:=-2;
     end;
end;

function GetHookID(Index: Integer): Cardinal; stdcall;
begin
     try
        Result:=Cardinal(HookRec.HookList.Items[Index]);
     except
        Result:=0;
     end;
end;

procedure EntryPointProc(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin // reserve 4k for the list (cca 1000 entries)
        hMapObject:=CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(THookRec) + 4069, 'ln_kbdList');
        HookRec:=MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0);
        // check if the list already created
        if not Assigned(HookRec^.HookList) then
           HookRec^.HookList:=TList.Create;
      end;

    DLL_PROCESS_DETACH:
      begin
        try
          // clear the list each time a process detaches
          // we could check the threads ids for their validity, but in order to do that
          // we'd need to have their handles but we only have their IDs
          // on win me/2000/xp there's a function called OpenThread
          // with it we could check if the thread id is still valid
          // no support for that function on win 9x systems
          // this should suffice coz with one key press we get all the installed keybd hooks
          // ofcourse if all of them call CallNextHookEx :)
          HookRec^.HookList.Clear;
        finally
          UnMapViewOfFile(HookRec);
          // close the handle to the map object
          // it will not close the handle while there's at least one open View
          CloseHandle(hMapObject);
        end;
      end;
  end;
end;

// ---------- export funkcije
exports
   SetMainWindow,
   HookWindoze,
   UnhookWindoze,
   GetHookCount,
   GetHookID;


begin
     DllProc := @EntryPointProc;
     EntryPointProc(DLL_PROCESS_ATTACH);
end.


hope it works for you :)
0
 
LVL 3

Author Comment

by:bryan7
ID: 6967621
Hello, thanks for the code, I've been
trying to implement the app to get the
list from the dll with no succes :(
would you mind making it for me ? I
can add more points as wished :)

(you'll get A graded)
0
 
LVL 3

Expert Comment

by:smurff
ID: 6967933
listening
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6968524
:)
in my spare time ... today/tomorrow
0
 
LVL 3

Author Comment

by:bryan7
ID: 6968526
:)
0
 
LVL 1

Expert Comment

by:quantum2
ID: 6981383
listening
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6990278
sorry I was away for a "few" days ...
have you got it working ? if not I'll make a sample app to show you how to use that dll
0
 
LVL 3

Author Comment

by:bryan7
ID: 7008349
haven't got it running yet,
would be nice if you could
make that app :)

thanks.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7008745
ok I will :)
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9004097
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from Lee_Nover

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 9097486
humz ..
if anybody needs a List that's shared between processes then check out my TGlobalList ;)
http://www.siwww.net/Delphi/GLTest.zip

just change the TGLItem to fit your needs
it must not contain any pointer type fields !
for strings use a fixed length array of char

it already includes locking mechanisms so it's completely thread/process safe ;)
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now