hook WH_CALLWNDPROCRET explorer.exe(winLogon.exe)出错 ( 积分: 100 )

  • 主题发起人 主题发起人 Supermay
  • 开始时间 开始时间
S

Supermay

Unregistered / Unconfirmed
GUEST, unregistred user!
使用wh_CallWNDPROCRET钩子,Unhook时导致explorer出错重启,甚至有时会令Winlogon出错,电脑重启,我在Unhook时,已用sendMessage广播消息,以便所有被HOOK的程序Unhook,
谢谢
 
钩子没有用好啊
 
Hook中什么也没有做都出错,是脱钩时出错
 
调用的Form
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TEnableHook = function(): BOOL;
TDisableHook = function(): BOOL;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Button3: TButton;
Button4: TButton;
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
FLibHandle: THandle;
FEnableHook: TEnableHook;
FDisableHook: TDisableHook;
FHookStarted: Boolean;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if @FEnableHook <> nil then
FHookStarted := FEnableHook;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if @FDisableHook <> nil then
FHookStarted :=Not FDisableHook;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
//装载Hook.dll,并取EnableHook,DisableHook的地址
try
FLibHandle := LoadLibrary('hook.dll');
if FLibHandle > 0 then
begin
@FEnableHook := GetProcAddress(FLibHandle, 'EnableHook');
@FDisableHook := GetProcAddress(FLibHandle, 'DisableHook');
end;
except
//
end;

end;

procedure TForm1.Button4Click(Sender: TObject);
begin
//释放Hook.dll
if (not FHookStarted)then
begin
if FLibHandle > 0 then
begin
FreeLibrary(FLibHandle);
FLibHandle := 0;
@FEnableHook := nil;
@FDisableHook := nil;
end;
end;
end;

end.

Hook处理
unit hookProc;

interface
uses
Windows, Classes, Messages, SysUtils, psapi, tlhelp32;

var
hNextHookProc: HHook = 0;

//挂钩
function EnableHook: Boolean; export; stdcall;
//脱钩
function DisableHook: Boolean; export; stdcall;

implementation

uses uCommon;

procedure saveLog(const AppName, ATitle, AUrl: string);
const
C_REC = '%s'#9'%s'#9'%s'#9'%s'#9'%s'#9'%s';
var
F: TextFile;
logFileName: string;
sName: string;
sHost: string;
sTime: string;
begin
logFileName := getWindowDir() + '/' + C_CLIENT_LOG_FILE;
sName := getUserName();
sHost := getHostName();
sTime := DateTimeToStr(now);

try
AssignFile(F, logFileName);
try
if not FileExists(logFileName) then
Rewrite(F)
else
Append(F);

Writeln(F, Format(C_REC, [sHost, sName, AppName, ATitle, AUrl, sTime]));
finally
Close(F);
end;
except

end;

end;

{枚举IE子窗口时的回调函数}

function EnumChildWindowsProc(hwnd: Integer; Iparam: Longint): Boolean; stdcall;
var
buffer: array[0..255] of char;
begin
result := true;
GetClassName(Hwnd, buffer, 256); //子窗口类名
if StrPas(Buffer) = 'Edit' then //IE地址栏类名是Edit
begin
SendMessage(Hwnd, WM_GETTEXT, 256, Iparam);
//取出IE地址栏内容存入Iparam指向的内存
result := False;
end;
end;

//取应用程序名
// nt/2000版本的函数:

function get_proc_name_nt(pid: DWORD): string;
var
hp, hmod, need: DWORD;
name: array[0..MAX_PATH] of char;
begin
Result := '未知';
try
hp := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, false, pid);
try
EnumProcessModules(hp, @hmod, 4, need);
GetModuleFileNameEx(hp, hmod, name, MAX_PATH);
Result := name;
finally
CloseHandle(hp);
end;
except
RaiseLastWin32Error();
end;
end;

//取应用程序名
//win9x版本的函数:

function get_proc_name_9x(pid: DWORD): string;
var
snapshot: DWORD;
pe: TProcessEntry32;
begin
Result := '未知';
try
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
try

pe.dwSize := sizeof(pe);
if Process32First(snapshot, pe) then
repeat
if pe.th32ProcessID = pid then
begin
Result := pe.szExeFile;
break;
end;
until not Process32Next(snapshot, pe);

finally
CloseHandle(snapshot);
end;
except
RaiseLastWin32Error();
end;

end;

//钩子处理函数

function hookCallBack(iCode: Integer; wParam: wParam;
lParam: lParam): LRESULT; stdcall;
var
cwp: CWPRETSTRUCT;
hwndWin: HWND;
szWinTitle: array[0..254] of Char;
szClassName: array[0..254] of Char;
szURL: array[0..254] of Char;
pid: DWORD;
appName: string;
title: string;
url: string;
begin
cwp := PCWPRETSTRUCT(lParam)^;
case cwp.message of
WM_CREATE,
WM_SETTEXT:
begin
hwndWin := cwp.hwnd;
// GetClassName(hwndWin, szClassName, 255);
// //IE窗口
// if strpas(szClassName) = 'IEFrame' then
// begin
// //buffer传递给EnumChildWindowsProc的Iparam
// EnumChildWindows(hwndWin, @EnumChildWindowsProc, Integer(@szURL[0]));
// url := Trim(szURL);
// {$IFDEF DEBUG}
// WriteScreen('IEFrame: ' + url, 500, 10);
// {$ENDIF}
// end;

//取得窗体标题
GetWindowText(hwndWin, szWinTitle, 254);
title := Trim(szWinTitle);

{$IFDEF DEBUG}
WriteScreen('Title: ' + title, 500, 30);
{$ENDIF}

//取文件名
GetWindowThreadProcessId(hwndWin, @pid);
if Win32Platform = VER_PLATFORM_WIN32_NT then
appName := get_proc_name_nt(pid)
else
appName := get_proc_name_9x(pid);

{$IFDEF DEBUG}
WriteScreen('FileName: ' + appName, 500, 50);
{$ENDIF}

saveLog(appName, title, url);
end;
end;

//传递钩子函数
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
end;

function EnableHook: Boolean; stdcall;
begin
Result := False;
if hNextHookProc <> 0 then
Exit;

//记录使用钩子函数的句柄
//WH_CALLWNDPROCRET hook
hNextHookProc := SetWindowsHookEx(WH_CALLWNDPROCRET, @hookCallBack, hInstance, 0);

//如果成功产生钩子句柄则返回为真
Result := hNextHookProc <> 0;
end;

function DisableHook: Boolean; stdcall;
begin
//关闭钩子
if hNextHookProc <> 0 then
begin
if UnHookWindowsHookEx(hNextHookProc) then
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;

end.

Hook.dll
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,
hookProc in 'hookProc.pas',
uCommon in '../uCommon.pas';

var
procSaveExit: Pointer;

exports //DLL的输出函数
EnableHook,
DisableHook;

//DLL释放处理,用于自动停止钩子

procedure HookExit; far;
begin
if hNextHookProc <> 0 then
DisableHook;

ExitProc := procSaveExit;
end;

{$R *.res}

begin
procSaveExit := ExitProc; //DLL释放时解除挂钩
ExitProc := @HookExit;
end.
 
学习~。。。。。。。。。。。。
 
问题解决了,又浪费了100分
 
http://www.51zhan.com 最好的网址站
http://www.51zhan.com 最好的网址站
http://www.51zhan.com 最好的网址站
 
http://www.51zhan.com 最好的网址站
http://www.51zhan.com 最好的网址站
http://www.51zhan.com 最好的网址站
 
求只显示PDF,XLS,DOC,DWG的控件
 
使用autovue,但不知如何打包
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
689
import
I
I
回复
0
查看
962
import
I
后退
顶部