200分征求答案:键盘和SHELL钩子经常引起EXPLORER。EXE和自已的程序非法操作的而关闭。(200分)

J

jingzux

Unregistered / Unconfirmed
GUEST, unregistred user!
这是我从“深度历险”中下载的钩子,在使用中随机引起各种程序其中最多
是EXPLORER。EXE、IE、和自已非法操作并弹出相关程序的“非法操作”窗口而关
闭,有时关闭这个窗口后死机,且是随机的出现,很不稳定。
本人是初学,各位高手:不知那里有问题?原程序:
library Watching;
{
Watching.dll V1.0
This is NOT Freeware: It's PostCardWare. When you use
this component or think it's useful, send me a post-card
to: Florian B鰉ers, Werderstr.31, D - 68165 Mannheim, Germany
And of course, I am very interested in any application
that uses this dll (or any other application you wrote).
If so, mail me (not the program, just an URL or similar) !
(c) 1997 by Florian B鰉ers
(using memory files: seen in c't 07/1997)
send any comments, proposals, enhancements etc. to:
fbomers@erato.unice.fr
(if this addressdo
es not work: boemers@rumms.uni-mannheim.de)
}
uses Windows;
const
MSG_BOME_SHELL_EVENT='BOME_SHELL_EVENT';
MSG_BOME_KEY_EVENT='BOME_KEY_EVENT';
HookMemFileName='BomeHook.DTA';
HookMutexName='BomeHookMutex';
type
TWatchType=( wtSHELL,wtKEYBOARD, //implemented
wtCALLWNDPROC,wtGETMESSAGE, //not yet implemented
wtMOUSE,wtMSGFILTER,wtSYSMSGFILTER);
//not yet implemented
TShared = record
ShellHook:HHook;
ShellCount:Integer;
KeyHook:HHOOK;
KeyCount:Integer;
Receiver:Integer;
AttachCount:Integer;
end;
PShared=^TShared;
var
SHELL_EVENT:Integer;
KEY_EVENT:Integer;
MemFile, HookMutex: THandle;
Shared: PShared;
{------------ Hook procedures ------------------}
// Callback of the Shell Hook
function GetShellHook( Code: Integer;
// hook code
wParam: WPARAM;
// event-specific information
lParam:LPARAM // undefined
): LRESULT;
far stdcall;
begin
if Code>=0 then
begin
// send the Code as lParam
postMessage(Shared^.Receiver,SHELL_EVENT,wParam,Code);
end;
Result := CallNextHookEx(Shared^.ShellHook, Code, wParam, lParam);
end;

// Callback of the Keyboard Hook
function GetKeyHook( Code: Integer;
// hook code
wParam: WPARAM;
// virtual-key code
lParam:LPARAM // keystroke-message information
): LRESULT;
stdcall;
begin
if code=HC_ACTION then
postMessage(Shared^.Receiver,KEY_EVENT,wParam,lParam);
Result := CallNextHookEx(Shared^.KeyHook, Code, wParam, lParam)
end;

{----------------Procedures called by TWatch component----------------}
// starts watching on this type
// For every call there must be a matching StopWatching call
// or at the end a StopAll.
procedure StartWatching(WatchType:TWatchType);
stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with Shared^do
case WatchType of
wtSHELL:
begin
if (ShellCount=0) and (ShellHook=0) then
ShellHook:=SetWindowsHookEx(WH_SHELL, @GetShellHook, HInstance , 0);
inc(ShellCount);
end;
wtKEYBOARD:
begin
if (KeyCount=0) and (KeyHook=0) then
KeyHook:=SetWindowsHookEx(WH_KEYBOARD, @GetKeyHook, HInstance , 0);
inc(KeyCount);
end;
end;
finally
ReleaseMutex(HookMutex);
end;
end;

// stops this type of watch
procedure StopWatching(WatchType:TWatchType);
stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with Shared^do
case WatchType of
wtSHELL:
begin
dec(ShellCount);
if (ShellCount<=0) and (ShellHook<>0) then
begin
UnhookWindowsHookEx(ShellHook);
ShellHook:=0;
ShellCount:=0;
end;
end;
wtKEYBOARD:
begin
dec(KeyCount);
if (KeyCount<=0) and (KeyHook<>0) then
begin
UnhookWindowsHookEx(KeyHook);
KeyHook:=0;
KeyCount:=0;
end;
end;
end;
finally
ReleaseMutex(HookMutex);
end;
end;

// frees all Hooks
procedure StopAll;
stdcall;
var alreadyStopped:Boolean;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with Shared^do
begin
alreadyStopped:=((ShellCount=0) and (KeyCount=0));
ShellCount:=0;
KeyCount:=0;
end;
finally
ReleaseMutex(HookMutex);
end;
if not alreadyStopped then
begin
StopWatching(wtSHELL);
StopWatching(wtKEYBOARD);
end;
end;

// returns, whether any Hooks are installed
function StillWatching:Boolean;
stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
with Shared^do
result:=(ShellCount>0) or (KeyCount>0);
finally
ReleaseMutex(HookMutex);
end;
end;

// sets the Window Handle of the Window that will
// receive the messages
// note: This prevents that this dll is used
// in multiple instances. Only the last
// program that called SetReceiver will
// receive the events.
// TODO: List of receivers...
procedure SetReceiver(R:Integer);
stdcall;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
Shared^.Receiver:=r;
finally
ReleaseMutex(HookMutex);
end;
end;

procedure Intro;
stdcall;
begin
// called everytime when the dll is injected into another context
SHELL_EVENT:=RegisterWindowMessage(PChar(MSG_BOME_SHELL_EVENT));
KEY_EVENT:=RegisterWindowMessage(PChar(MSG_BOME_KEY_EVENT));
HookMutex:=CreateMutex(nil,True,HookMutexName);
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,HookMemFileName);
if MemFile=0 then
MemFile:=CreateFileMapping($FFFFFFFF,nil,
PAGE_READWRITE,0,SizeOf(TShared),HookMemFileName);
Shared:=MapViewOfFile(MemFile,FILE_MAP_WRITE,0,0,0);
if MemFile=0 then
FillChar(Shared^,SizeOf(TShared),0);
inc(Shared^.AttachCount);
ReleaseMutex(HookMutex);
end;

procedure Extro;
stdcall;
var fini:Boolean;
begin
try
WaitForSingleObject(HookMutex,INFINITE);
dec(Shared^.AttachCount);
fini:=(Shared^.AttachCount=0);
finally
ReleaseMutex(HookMutex);
end;
if fini then
begin
StopAll;
UnmapViewOfFile(Shared);
CloseHandle(MemFile);
CloseHandle(HookMutex);
end;
end;

{------------- DLL Entry ----------------}
procedure DLLEntryPoint(reason:integer);
begin
case reason of
0: {DLL_PROCESS_DETACH} Extro;
1: {DLL_PROCESS_ATTACH} Intro;
// 2: {DLL_THREAD_ATTACH}
// 3: {DLL_THREAD_DETACH}
end;
end;
function dsst1:integer;
begin
result:=3;
end;
function zhuce:integer;
begin
result:=3;
end;

exports
zhuce,
dsst1,
StartWatching,
StopWatching,
StopAll,
StillWatching,
SetReceiver;
begin
Intro;
DLLProc:=@DLLEntryPoint;
end.
谢谢!
 
将PostMessage改为SendMessage试试。
(不要问我为什么,我也很奇怪,因为我用PostMessage就是有问题,而
用SendMessage就好了)
 
几天了,没人答,我把分收回了。
 
delphi编写钩子一般都有问题
 
多人接受答案了。
 
顶部