使用SetWindowsHookEx一直发生错误,提示如下:
Access violation at address 00D433DB. Write of address CC00D41B下面是我的代码:
--------------------------
EXE部分:
unit UnitMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TfrmMain = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
frmMain: TfrmMain;implementation
procedure StartHook(QQHandle : longint); external 'Inject.dll' name 'StartHook';
procedure StopHook; external 'Inject.dll' name 'StopHook';
{$R *.dfm}procedure TfrmMain.FormCreate(Sender: TObject);
begin
Self.Icon := Application.Icon;
Application.Title := Self.Caption;
end;procedure TfrmMain.Button1Click(Sender: TObject);
begin
StartHook(GetWindowThreadProcessID(Self.Handle,nil));
end;procedure TfrmMain.Button2Click(Sender: TObject);
begin
StopHook;
end;end.-------------------------
DLL部分:
library Inject;{ 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,
UnitHook in 'UnitHook.pas';{$R *.res}
exports
StartHook,StopHook;begin
end.----------------
unit UnitHook;interfaceuses Windows, SysUtils, Classes, math, messages, dialogs; procedure StartHook(QQProcID : Cardinal);stdcall;
procedure StopHook;stdcall;implementationvar
MessageHook : HHOOK;
function MyHookProc(iCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall;
begin
if wParam = WM_MOUSEMOVE then
showmessage('Get It');
Result := CallNextHookEx(MessageHook, iCode, wParam, lParam);
end;procedure StartHook(QQProcID : Cardinal);stdcall;export;
begin
if MessageHook = 0 then
begin
MessageHook := SetWindowsHookEx(WH_GETMESSAGE,MyHookProc,HInstance,QQProcID);
if longint(MessageHook) = 0 then
showmessage(SysErrorMessage(GetLastError));
end;
end;procedure StopHook;stdcall;export;
begin
if MessageHook <> 0 then
begin
UnHookWindowsHookEx(MessageHook);
MessageHook := 0;
end;
end;end.
Access violation at address 00D433DB. Write of address CC00D41B下面是我的代码:
--------------------------
EXE部分:
unit UnitMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TfrmMain = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
frmMain: TfrmMain;implementation
procedure StartHook(QQHandle : longint); external 'Inject.dll' name 'StartHook';
procedure StopHook; external 'Inject.dll' name 'StopHook';
{$R *.dfm}procedure TfrmMain.FormCreate(Sender: TObject);
begin
Self.Icon := Application.Icon;
Application.Title := Self.Caption;
end;procedure TfrmMain.Button1Click(Sender: TObject);
begin
StartHook(GetWindowThreadProcessID(Self.Handle,nil));
end;procedure TfrmMain.Button2Click(Sender: TObject);
begin
StopHook;
end;end.-------------------------
DLL部分:
library Inject;{ 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,
UnitHook in 'UnitHook.pas';{$R *.res}
exports
StartHook,StopHook;begin
end.----------------
unit UnitHook;interfaceuses Windows, SysUtils, Classes, math, messages, dialogs; procedure StartHook(QQProcID : Cardinal);stdcall;
procedure StopHook;stdcall;implementationvar
MessageHook : HHOOK;
function MyHookProc(iCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall;
begin
if wParam = WM_MOUSEMOVE then
showmessage('Get It');
Result := CallNextHookEx(MessageHook, iCode, wParam, lParam);
end;procedure StartHook(QQProcID : Cardinal);stdcall;export;
begin
if MessageHook = 0 then
begin
MessageHook := SetWindowsHookEx(WH_GETMESSAGE,MyHookProc,HInstance,QQProcID);
if longint(MessageHook) = 0 then
showmessage(SysErrorMessage(GetLastError));
end;
end;procedure StopHook;stdcall;export;
begin
if MessageHook <> 0 then
begin
UnHookWindowsHookEx(MessageHook);
MessageHook := 0;
end;
end;end.
但showmessage(SysErrorMessage(GetLastError));显示“操作成功完成”。
请各位指点一下究竟错在哪里了?
SetWindowsHookEx(WH_GETMESSAGE,MyHookProc,GetCurrentThreadId(),QQProcID);好像曾看资料里说过,除了WH_JOURNALRECORD和WH_JOURNALPLAYBACK这两个钩子(或者还有其他的)可以用全局实例以外,其他的都只能用局部,所以应该不能用HInstance
但还是出现“Access violation at address 00D433DB. Write of address CC00D41B”。
我只想钩一个进程,不想钩全局的,难道SetWindowsHookEx的第4个参数一定要是0吗?
int idHook, // type of hook to install
HOOKPROC lpfn, // address of hook procedure
HINSTANCE hMod, // handle to application instance
DWORD dwThreadId // identity of thread to install hook for
);
看仔细里面参数的意义哦SetWindowsHookEx(WH_MOUSE, @HookMouseProc, hModule, iThreadID);
把stdcall去掉吗?还是改成别的什么?