钩子注入程序

程序作用:
在Explorer.exe的窗口接到任何一个鼠标消息时在Explorer.exe进程注入一个线程,该线程显示一个窗体.

程序的问题,如果程序在Explorer.exe还没有接收到有效的鼠标消息之前被关闭,则进程注入不会成功.

启动程序:

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.


启动程序的窗口单元.


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

function EnableMouseHook:Boolean; stdcall; external 'HookDLL.dll' name 'EnableMouseHook';
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  //启动钩子.
  EnableMouseHook;
end;

end.
 
钩子和线程注入DLL:

library hookDLL;
uses
  SysUtils,
  Classes,
  Hookunit in 'Hookunit.pas',
  Unit2 in 'Unit2.pas' {Form2};

{$R *.RES}
//导出函数.
exports EnableMouseHook,DisableMouseHook,CreateImmitThread;
begin
end.

//钩子和线程注入实现单元.
unit Hookunit;

interface
uses Windows,Messages,Controls,Sysutils,Dialogs;

Type
  TCreateImmitThread=Procedure;stdcall;
var hHk: HHOOK;//钩子的句柄值。

function MouseHookProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM): LRESULT;stdcall;
//鼠标钩子的回调函数,即用它来处理得到消息后要干什么。
//nCode参数是Hook的标志,一般只关心小于0时。看下面的详细说明
//WParam参数表示鼠标消息的类型
//LParam参数是一个指向 TMOUSEHOOKSTRUCT 结构的指针。结构包含了鼠标消息的状态,我只用了hwnd一个
//即鼠标消息要传递给的窗口句柄。
//返回值如果不是0的话Windows就把这个消息丢掉,其它的程序就不会再收到这个消息了。

//两个函数都是Boolean类型,成功都是返回True
function EnableMouseHook:Boolean; stdcall; export;
function DisableMouseHook:Boolean; stdcall; export;

//创建注入线程.
Procedure CreateImmitThread; stdcall; export;

implementation

uses Classes , Unit2;

procedure HandleEvent(HLib:THandle); stdcall;
var
  Msg: TMsg;
  MutexHandle:THandle;
begin
  //再检查一次全局原子,如果该原是存在,则退出本函数,线程中止.
  MutexHandle := windows.GlobalFindAtom('abhjjhsdhjdshjds111');
  if MutexHandle <> 0 then
    Exit;
  MutexHandle:=Windows.GlobalAddAtom('abhjjhsdhjdshjds111');
  //添加一个全局原子.
  try
    //创建一个Form.
    Form2:=TForm2.Create(nil);
    try
      Form2.Show;
      //显示Form.

      //消息循环.
      while True do
      begin
        //如果Form已经被关闭.
        //注意这是和Form.OnClose事件和Form.OnDestroy事件配合使用的.
        if Form2=nil then
          Break;
        //检查消息队列.
        if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
        begin
          //如果得到WM_QUIT消息,则中止循环.
          if Msg.Message = WM_QUIT then
            Break;
          //分发消息.
          TranslateMessage(Msg);
          DispatchMessage(Msg);
        end;
      end;
    finally
      //如果Form2还没有被释放.
      if Form2<>nil then
        Form2.Free;
    end;
  finally
    //释放全局原子对象.
    Windows.GlobalDeleteAtom(MutexHandle);
  end;
end;

Procedure CreateImmitThread; stdcall;
var
  ThreadID:DWORD;
begin
  //该函唯一的功能就是创建并启动一个线程.
  CreateThread(nil, 0, @HandleEvent, nil, 0, ThreadID);
end;

function MouseHookProc(nCode: Integer;WParam: WPARAM;LParam:LPARAM): LRESULT;stdcall;
var a:Array[0..255] of char;
  s:String;
  H:THandle;
  P:Pointer;
  MutexHandle:THandle;
begin
  Result:=0;//最好首先给它一个返回值,不然会有警告的!记住这可不是C语言。
  //当nCode小于0时表示还有其它的Hook必须把参数传给它。
  //此时就要用Api函数CallNextHookEx让它调用下一个Hook!!!当然不用好像也可以。
  if nCode < 0 then
    Result:=CallNextHookEx(hHk,nCode,wParam,lParam)//参数是现成的,直接用就可以了。
  else
  begin
    GetModuleFileName(0,a,255);
    s:=UpperCase(StrPas(a));
    if Pos('EXPLORER.EXE',s)>0 then//如果是资源管理器Explorer.EXE.
    begin
      MutexHandle := windows.GlobalFindAtom('abhjjhsdhjdshjds111');//检查是不存在全局原子
      if MutexHandle <> 0 then//如果存在,则表示该窗口已经显示出来了.
        exit;
      H:=LoadLibrary('HookDLL.dll');//装载需要注入的DLL,其实就是本DLL.
      if H<>INVALID_HANDLE_VALUE then
      begin
        P:=GetProcAddress(H,'CreateImmitThread');//得到注入的函数地址.
        if P<>nil then
          TCreateImmitThread(P);//执行函数,该函数仅启动一个线程.
      end;
    end;
  end;
end;

function EnableMouseHook:Boolean; stdcall; export;
begin
  if hHk = 0 then //为了安全,必须判断一下再设置钩子。
  Begin
    //第三个参数的Hinstance 在Delphi中有定义,用就可以了。第四个参数必须为0
    hHk := SetWindowsHookEx(WH_MOUSE,@MouseHookProc,Hinstance,0);
    Result := True;
  end
  else
    Result := False;
end;

function DisableMouseHook:Boolean; stdcall; export;
begin
  if hHk <> 0 then //如果有钩子就卸掉它。
  begin
    UnHookWindowsHookEx(hHk);
    hHk := 0;
    Result := True;
  end
  else
    Result := False;
end;
end.

注入后线程启动的窗体:

unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Close;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //窗口关闭时释放自身.
  Action:=caFree;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  //窗口释放时置Form2为nil
  Form2:=nil;
end;

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值