截获消息(2)
by sssa2000
2004/07/03
放假了,突然想起还没写完这个东西,呵呵 迟到了。虽然我也知道没什么人看,我还是有始有终,写完它。
上次说到在自己的窗体中截获消息,我们的目的是截获制定程序的消息,怎么办呢?很容易的,我们想到了钩子。
Hook可真是好冬冬,没有他的话黑客编程可就没什么乐趣了。
我们用一个getmessage的hook来钩住我们想要得线程的消息。
我们来看一下setwindowshookex函数,可能大家比我熟了 ,我还是唠叨一次吧:
SetWindowsHookEx( idHook:Integer; //钩子类型
Lpfn:TFNHookProc; //钩子函数指针
Hmod:HINST; //delphi里一般都设为HInstance
dwThreadId:DWORD //关联的线程
):HHook;stcall;
具体我就不说了,钩子类型很多种什么鼠标 键盘,消息,shell,等等很多种,我们今天要用的是WH_GETMESSAGE类型,用处是:再getmessage函数已经搜索到一个来自应用队列的消息时调用。
再说一下dwThreadID这个参数制定了线程的id。钩子函数能够监视这个参数定义的线程,或者系统的所有的线程。使用它来过滤并在系统或窗口处理之前处理特定的消息。如果设为0,表示挂钩可以在所有的线程内调用。看来这个参数对我们很重要。
来看一个简单的例子:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
WM_TestMessage = WM_USER + 2000;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
var
HookHandle: HHOOK;
function TestHookProc(Code: Integer; WParam: Longint;Msg:Longint): Longint;stdcall;
begin
if (Code = HC_ACTION) then
if PMsg(Msg)^.Message = WM_TestMessage then
begin
showMessage('已经截获该消息');
end;
Result := CallNextHookEx(HookHandle, Code, WParam, Longint(@Msg));
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
HookHandle:=SetWindowsHookEx(WH_GETMESSAGE,TestHookProc,0,GetCurrentThreadID);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
PostMessage(self.Handle,WM_TestMessage,0,0);
end;
end.
大家着重注意看下面这一句:
HookHandle:=SetWindowsHookEx(WH_GETMESSAGE,TestHookProc,0,GetCurrentThreadID);
用的是getcurrentthreadid 这是为了演示个大家看,我们可以设置为0,这样就可以监视所有线程了。
由于windows的每一个进程都有独立的进程空间,所以如果要对别的进程操作还要进行进程插入,就是我们常说得injection!! 哇咔咔咔,说到这个词都觉得很酷。
进程插入我就不说了,当然还有办法的,把钩子写在dll里面做成全局的钩子也是可以的,不过还是建议用插入的方法 毕竟全局钩子对系统的性能降低比较大。
好了 该说得都说了。
转载请注明出处哦。