library Hook;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
//SysUtils,
//Classes,
windows;
{$R *.RES}
const
MSG_MOUSE_EVENT='MOUSE_EVENT';
MSG_SHELL_EVENT1='SHELL_EVENT1';//respond to HSHELL_ACTIVATESHELLWINDOW,HSHELL_TASKMAN,HSHELL_LANGUAGE
MSG_SHELL_EVENT2='SHELL_EVENT2';//HSHELL_GETMINRECT
MSG_SHELL_EVENT3='SHELL_EVENT3';//HSHELL_REDRAW
MSG_SHELL_EVENT4='SHELL_EVENT4';//HSHELL_WINDOWACTIVATED
MSG_SHELL_EVENT5='SHELL_EVENT5';//HSHELL_WINDOWCREATED,HSHELL_WINDOWDESTROYED
MSG_KEY_EVENT='KEY_EVENT';
HookMemFileName='Hook.DAT';
HookMutexName='HookMutex';
type
THookType=(htCALLWNDPROC,htCALLWNDPROCRET,htCBT,htDEBUG,htGETMESSAGE,
htJOURNALPLAYBACK,htJOURNALRECORD,htKEYBOARD,htMOUSE,htMSGFILTER,
htSHELL,htSYSMSGFILTER);
//SetWindowsHookEx
THookRec = record
CallHook:HHook;
CallCount:integer;
CallRetHook:HHook;
CallRetCount:integer;
CBTHook:HHook;
CBTCount:integer;
DebugHook:HHook;
DebugCount:integer;
GetMsgHook:HHook;
GetMsgCount:integer;
PlayHook:HHook;
PlayCount:integer;
RecordHook:HHook;
RecordCount:integer;
KeyHook:HHOOK;
KeyCount:Integer;
MouseHook:HHook;
MouseCount:integer;
FilterHook:HHook;
FilterCount:integer;
ShellHook:HHook;
ShellCount:integer;
SysFilterHook:HHook;
SysFilterCount:integer;
Receiver:Integer;
AttachCount:Integer;
MouseInfo:TMouseHookStruct;
end;
PHookRec=^THookRec;
var
Call_Event,CallRet_Event,CBT_Event,Debug_Event,GetMsg_Event,Play_Event,
Record_Event,KEY_EVENT,Mouse_Event,Filter_Event,Shell_Event1,Shell_event2,
Shell_Event3,Shell_event4,Shell_event5,SysFilter_Event:Integer;
MemFile, HookMutex: THandle;
HookRec: PHookRec;
{------------ Hook procedures ------------------}
// Callback of the Keyboard Hook
function MouseHookProc(Code:integer;// hook code
wParam:WPARAM;// message identifier
lParam:LPARAM// mouse coordinates
):LRESULT;stdcall;
var
x,y:integer;
begin
if code=HC_ACTION then
begin
HookRec^.MouseInfo:=pMouseHookStruct(lparam)^;
PostMessage(HookRec^.Receiver,MOUSE_EVENT,wParam,lParam);//postmessage may be lost message
end;
//HC_NoREmove need not process
Result := CallNextHookEx(HookRec^.MouseHook, Code, wParam, lParam);
end;
function KeyHookProc( Code: Integer; // hook code
wParam: WPARAM; // virtual-key code
lParam:LPARAM // keystroke-message information
): LRESULT; stdcall;
begin
if code=HC_ACTION then
PostMessage(HookRec^.Receiver,KEY_EVENT,wParam,lParam);
Result := CallNextHookEx(HookRec^.KeyHook, Code, wParam, lParam);
end;
// Callback of the Shell Hook
function ShellHookProc( Code: Integer; // hook code
wParam: WPARAM; // event-specific information
lParam:LPARAM // undefined
): LRESULT; stdcall;
begin
case Code of
HSHELL_ACTIVATESHELLWINDOW,HSHELL_TASKMAN,HSHELL_LANGUAGE:// send the Code as wParam
PostMessage(HookRec^.Receiver,SHELL_EVENT1,Code,0);
HSHELL_GETMINRECT:
PostMessage(HookRec^.Receiver,Shell_event2,wparam,lparam);
HSHELL_REDRAW:
PostMessage(HookRec^.Receiver,Shell_event3,wparam,lparam);
HSHELL_WINDOWACTIVATED:
PostMessage(HookRec^.Receiver,Shell_event4,wparam,lparam);
HSHELL_WINDOWCREATED,HSHELL_WINDOWDESTROYED:
PostMessage(HookRec^.Receiver,Shell_event5,wparam,Code);
end;
Result := CallNextHookEx(HookRec^.ShellHook, Code, wParam, lParam);
end;
{----------------Procedures called by TCXHook component----------------}
procedure InstallHook(HookType:THookType); stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
case HookType of
htKEYBOARD:
begin
if (KeyCount=0) and (KeyHook=0) then
KeyHook:=SetWindowsHookEx(WH_KEYBOARD, @KeyHookProc, HInstance , 0);
inc(KeyCount);
end;
htMOUSE:
begin
if (MouseCount=0)and (MouseHook=0) then
MouseHook:=SetWindowsHookEx(WH_MOUSE,@MouseHookProc,HInstance, 0);
inc(MouseCount);
end;
htSHELL:
begin
if (ShellCount=0) and (ShellHook=0) then
ShellHook:=SetWindowsHookEx(WH_SHELL, @ShellHookProc, HInstance , 0);
inc(ShellCount);
end;
end;
finally
ReleaseMutex(HookMutex);
end;
end;
//UnInstallHook
procedure UnHook(HookType:THookType); stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
case HookType of
htKEYBOARD:
begin
dec(KeyCount);
if (KeyCount<=0) and (KeyHook<>0) then
begin
UnhookWindowsHookEx(KeyHook);
KeyHook:=0;
KeyCount:=0;
end;
end;
htMouse:
begin
dec(mouseCount);
if (MouseCount<=0)and (MouseHook<>0) then
begin
UnhookWindowsHookEx(MouseHook);
MouseHook:=0;
MouseCount:=0;
end;
end;
htSHELL:
begin
dec(ShellCount);
if (ShellCount<=0) and (ShellHook<>0) then
begin
UnhookWindowsHookEx(ShellHook);
ShellHook:=0;
ShellCount:=0;
end;
end;
end;
finally
ReleaseMutex(HookMutex);
end;
end;
// frees all Hooks
procedure UnHookAll; stdcall;
var AlreadyUnHooked:Boolean;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
begin
AlreadyUnHooked:=((ShellCount=0) and (KeyCount=0)and (MouseCount=0));
ShellCount:=0;
KeyCount:=0;
MouseCount:=0;
end;
finally
ReleaseMutex(HookMutex);
end;
if not AlreadyUnHooked then
begin
UnHook(htSHELL);
UnHook(htKEYBOARD);
UnHook(htMouse);
end;
end;
// returns, whether any Hooks are installed
function IsHooked:Boolean; stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with HookRec^ do
result:=(ShellCount>0) or (KeyCount>0) or (MouseCount>0);
finally
ReleaseMutex(HookMutex);
end;
end;
procedure SetReceiver(R:Integer); stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
HookRec^.Receiver:=r;
finally
ReleaseMutex(HookMutex);
end;
end;
procedure IntoDll; stdcall;
begin
// called everytime when the dll is injected into another context
MOUSE_EVENT:=RegisterWindowMessage(PChar(MSG_MOUSE_EVENT));
KEY_EVENT:=RegisterWindowMessage(PChar(MSG_KEY_EVENT));
SHELL_EVENT1:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT1));
SHELL_EVENT2:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT2));
SHELL_EVENT3:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT3));
SHELL_EVENT4:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT4));
SHELL_EVENT5:=RegisterWindowMessage(PChar(MSG_SHELL_EVENT5));
HookMutex:=CreateMutex(nil,True,HookMutexName);
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,HookMemFileName);
if MemFile=0 then
MemFile:=CreateFileMapping($FFFFFFFF,nil,
PAGE_READWRITE,0,SizeOf(THookRec),HookMemFileName);
HookRec:=MapViewOfFile(MemFile,FILE_MAP_WRITE,0,0,0);
if MemFile=0 then
FillChar(HookRec^,SizeOf(THookRec),0);
inc(HookRec^.AttachCount);
ReleaseMutex(HookMutex);
end;
procedure ExitDll; stdcall;
var finish:Boolean;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
dec(HookRec^.AttachCount);
finish:=(HookRec^.AttachCount=0);
finally
ReleaseMutex(HookMutex);
end;
if finish then
begin
UnHookAll;
UnmapViewOfFile(HookRec);
CloseHandle(MemFile);
CloseHandle(HookMutex);
end;
end;
{------------- DLL Entry ----------------}
procedure DLLEntryPoint(reason:integer);
begin
case reason of
0: {DLL_PROCESS_DETACH} ExitDll;
1: {DLL_PROCESS_ATTACH} IntoDll;
// 2: {DLL_THREAD_ATTACH}
// 3: {DLL_THREAD_DETACH}
end;
end;
function GetMouseInfo:TMouseHookStruct;stdcall
begin
try
WaitForSingleObject(HookMutex,INFINITE);
Result:=HookRec^.MouseInfo;
finally
ReleaseMutex(HookMutex);
end;
end;
exports
InstallHook,
UnHook,
UnHookAll,
IsHooked,
SetReceiver,
GetMouseInfo;
begin
Intodll;
DLLProc:=@DLLEntryPoint;
end.
BTW:
CXLIB.ZIP里的hook.dpr就是dll的原代码。你没注意到吗