现在的位置: 首页 > 综合 > 正文

Delphi 钩子 注入线程(2)

2018年05月27日 ⁄ 综合 ⁄ 共 4174字 ⁄ 字号 评论关闭
程序作用:
在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.


 

抱歉!评论已关闭.