⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delphi钩子.txt

📁 讲解如何使用DELPHI制作钩子,东西很简单适合于初学者
💻 TXT
📖 第 1 页 / 共 5 页
字号:
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
PlayLog:=0;
//建立键盘鼠标操作消息纪录回放链
hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc,
HInstance,0);
Button3.Enabled:=False;
end;
end.
代码添加完毕后,运行程序,点击“纪录”按钮开始纪录操作,这时你可以在文本控件中输入一些文字或者点击
“范例”按钮,然后点击“停止”按钮停止纪录,再点击“回放”按钮就可以讲先前所做的操作回放。
在上面的程序中,HookProc是纪录操作的消息函数,每当有鼠标键盘消息发生时,系统都会调用该函数,
消息信息就保存在地址lParam中,我们可以讲消息保存在一个数组中。PlayProc是消息回放函数,当系统可以
执行消息回放时调用该函数,程序就将先前纪录的消息值返回到lParam指向的区域中,系统就会执行该消息,
从而实现了消息回放。
Delphi - 关于钩子函数HOOK (6)
以下例程可以实现禁止用户用ALT+TAB或ALT+ESCAPE键切换程序,并且可以屏蔽左右windows键:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
btn2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }end;
{按键消息的结构,Delphi中也没有,自己定义吧。这也就我为什么说用C写
这样的程序更好的原因之一。还必须注意的是这个结构在Windows NT 4 sp3以上系统
中才能使用}
tagKBDLLHOOKSTRUCT = packed record
vkCode: DWORD;//虚拟键值
scanCode: DWORD;//扫描码值(没有用过,我也不懂^_^)
{一些扩展标志,这个值比较麻烦,MSDN上说得也不太明白,但是
根据这个程序,这个标志值的第六位数(二进制)为1时ALT键按下为0相反。}
flags: DWORD;
time: DWORD;//消息时间戳
dwExtraInfo: DWORD;//和消息相关的扩展信息
end;
KBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;
PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
//这个是低级键盘钩子的索引值,Delphi中没有,必须自己定义
const WH_KEYBOARD_LL = 13;
//定义一个常量好和上面哪个结构中的flags比较而得出ALT键是否按下
const LLKHF_ALTDOWN = $20;
var
Form1: TForm1;
hhkLowLevelKybd: HHOOK;
implementation
{$R *.dfm}
{
功能:低级键盘钩子的回调函数,在里面过滤消息
参数:nCode 是Hook的标志
WParam 表示消息的类型
LParam 是一个指向我们在上面定义的哪个结构KBDLLHOOKSTRUCT的指针
返回值:如果不是0的话windows就把这个消息丢掉,程序就不会再收到这个消息了。
}
function LowLevelKeyboardProc(nCode: Integer;
WParam: WPARAM;LParam: LPARAM):LRESULT; stdcall;
var
fEatKeystroke: BOOL;
p: PKBDLLHOOKSTRUCT;
begin
Result := 0;
fEatKeystroke := FALSE;
p := PKBDLLHOOKSTRUCT (lParam);
//nCode值为HC_ACTION时表示WParam和LParam参数包涵了按键消息
if (nCode = HC_ACTION) then
begin
//拦截按键消息并测试是否是左windows、右windows、Ctrl+Esc、Alt+Tab、和Alt+Esc功能键。
case wParam of
WM_KEYDOWN,
WM_SYSKEYDOWN,
WM_KEYUP,
WM_SYSKEYUP:
fEatKeystroke :=
(p.vkCode = VK_rwin) or (p.vkCode = VK_lwin) or
((p.vkCode = VK_TAB) and ((p.flags and LLKHF_ALTDOWN) 0)) or
((p.vkCode = VK_ESCAPE) and ((p.flags and LLKHF_ALTDOWN) 0)) or
((p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) 0));
end;
end;
if fEatKeystroke = True then
Result := 1;
if nCode 0 then
Result := CallNextHookEx(0, nCode, wParam, lParam);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
//设置低级键盘钩子
if hhkLowLevelKybd = 0 then
begin
hhkLowLevelKybd := SetWindowsHookExW(WH_KEYBOARD_LL,
LowLevelKeyboardProc, Hinstance, 0);
if hhkLowLevelKybd 0 then
MessageBox(Handle, '低级键盘钩子设置成功!', '提示', MB_OK)
else
MessageBox(Handle, '低级键盘钩子设置失败!', '提示', MB_OK);
end
else
MessageBox(Handle, '低级键盘钩子已设置!', '提示', MB_OK);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
//卸载低级键盘钩子
if hhkLowLevelKybd 0 then
if UnhookWindowsHookEx(hhkLowLevelKybd) False then
begin
MessageBox(Handle, '低级键盘钩子卸载成功!', '提示', MB_OK);
hhkLowLevelKybd := 0;
end
else
MessageBox(Handle, '低级键盘钩子卸载失败!', '提示', MB_OK)
else
MessageBox(Handle, '没有发现低级键盘钩子!', '提示', MB_OK);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
//在Form关闭的时候检测,如果没有卸载钩子就卸载之
if hhkLowLevelKybd 0 then
UnhookWindowsHookEx(hhkLowLevelKybd);
end;
上面例程在WINXP和DELPHI 7.0中使用通过。
Delphi - 关于钩子函数HOOK (7)
关于钩子函数的讲解
这是win32汇编语言中关于钩子函数的讲解,是丛windows的底层讲的,对于c,vb,delphi语言,原理都相同,只是语法的问题。
  
   WINDOWS钩子函数
  本文中我们将要学习WINDOWS钩子函数的使用方法。WINDOWS钩子函数的功能非常强大,
有了它您可以探测其它进程并且改变其它进程的行为。
  理论:
  WINDOWS的钩子函数可以认为是WINDOWS的主要特性之一。利用它们,您可以捕捉您自己进程或其它进程发生的事件。
通过“钩挂”,您可以给WINDOWS一个处理或过滤事件的回调函数,该函数也叫做“钩子函数”,当每次发生您感兴趣的事件时,
WINDOWS都将调用该函数。一共有两种类型的钩子:局部的和远程的。
  局部钩子仅钩挂您自己进程的事件。
  远程的钩子还可以将钩挂其它进程发生的事件。远程的钩子又有两种:
  基于线程的 它将捕获其它进程中某一特定线程的事件。简言之,就是可以用来观察其它进程中的某一特定线程将发生的事件。
  系统范围的 将捕捉系统中所有进程将发生的事件消息。
  安装钩子函数将会影响系统的性能。监测“系统范围事件”的系统钩子特别明显。因为系统在处理所有的相关事件
时都将调用您的钩子函数,这样您的系统将会明显的减慢。所以应谨慎使用,用完后立即卸载。还有,由于您可以预先
截获其它进程的消息,所以一旦您的钩子函数出了问题的话必将影响其它的进程。记住:功能强大也意味着使用时要负责任。
  在正确使用钩子函数前,我们先讲解钩子函数的工作原理。当您创建一个钩子时,WINDOWS会先在内存中创建一个数据
结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去。新的钩子将加到老的前面。
当一个事件发生时,如果您安装的是一个局部钩子,您进程中的钩子函数将被调用。如果是一个远程钩子,系统就必须把钩子
函数插入到其它进程的地址空间,要做到这一点要求钩子函数必须在一个动态链接库中,所以如果您想要使用远程钩子,
就必须把该钩子函数放到动态链接库中去。当然有两个例外:工作日志钩子和工作日志回放钩子。这两个钩子的钩子函数必
须在安装钩子的线程中。原因是:这两个钩子是用来监控比较底层的硬件事件的,既然是记录和回放,所有的事件就当然都
是有先后次序的。所以如果把回调函数放在DLL中,输入的事件被放在几个线程中记录,所以我们无法保证得到正确的次序。
故解决的办法是:把钩子函数放到单个的线程中,譬如安装钩子的线程。
  钩子一共有14种,以下是它们被调用的时机:
  WH_CALLWNDPROC 当调用SendMessage时
  WH_CALLWNDPROCRET 当SendMessage的调用返回时
  WH_GETMESSAGE 当调用GetMessage 或 PeekMessage时
  WH_KEYBOARD 当调用GetMessage 或 PeekMessage 来从消息队列中查询WM_KEYUP 或 WM_KEYDOWN 消息时
  WH_MOUSE 当调用GetMessage 或 PeekMessage 来从消息队列中查询鼠标事件消息时
  WH_HARDWARE 当调用GetMessage 或 PeekMessage 来从消息队列种查询非鼠标、键盘消息时
  WH_MSGFILTER 当对话框、菜单或滚动条要处理一个消息时。该钩子是局部的。它时为那些有自己的消息处理过程的控件对象设计的。
  WH_SYSMSGFILTER 和WH_MSGFILTER一样,只不过是系统范围的
  WH_JOURNALRECORD 当WINDOWS从硬件队列中获得消息时
  WH_JOURNALPLAYBACK 当一个事件从系统的硬件输入队列中被请求时
  WH_SHELL 当关于WINDOWS外壳事件发生时,譬如任务条需要重画它的按钮.
  WH_CBT 当基于计算机的训练(CBT)事件发生时
  WH_FOREGROUNDIDLE 由WINDOWS自己使用,一般的应用程序很少使用
  WH_DEBUG 用来给钩子函数除错
  现在我们知道了一些基本的理论,现在开始讲解如何安装/卸载一个钩子。
  要安装一个钩子,您可以调用SetWindowHookEx函数。该函数的原型如下:
  SetWindowsHookEx proto HookType:DWORD, pHookProc:DWORD, hInstance:DWORD, ThreadID:DWORD
  HookType 是我们上面列出的值之一,譬如: WH_MOUSE, WH_KEYBOARD
  pHookProc 是钩子函数的地址。如果使用的是远程的钩子,就必须放在一个DLL中,否则放在本身代码中
  hInstance 钩子函数所在DLL的实例句柄。如果是一个局部的钩子,该值为NULL
ThreadID 是您安装该钩子函数后想监控的线程的ID号。该参数可以决定该钩子是局部的还是系统范围的。如果该值为NULL,
那么该钩子将被解释成系统范围内的,那它就可以监控所有的进程及它们的线程。如果您指定了您自己进程中的某个线程ID 号,
那该钩子是一个局部的钩子。如果该线程ID是另一个进程中某个线程的ID,那该钩子是一个全局的远程钩子。
这里有两个特殊情况:WH_JOURNALRECORD 和 WH_JOURNALPLAYBACK总是代表局部的系统范围的钩子,之所以说是局部,
是因为它们没有必要放到一个DLL中。WH_SYSMSGFILTER 总是一个系统范围内的远程钩子。其实它和WH_MSGFILTER钩子类似,
如果把参数ThreadID设成0的话,它们就完全一样了。
  如果该函数调用成功的话,将在eax中返回钩子的句柄,否则返回NULL。您必须保存该句柄,因为后面我们还要它来卸载钩子。
  要卸载一个钩子时调用UnhookWidowHookEx函数,该函数仅有一个参数,就是欲卸载的钩子的句柄。如果调用成功的话,
在eax中返回非0值,否则返回NULL。
  现在您知道了如何安装和卸载一个钩子了,接下来我们将看看钩子函数。.
  只要您安装的钩子的消息事件类型发生,WINDOWS就将调用钩子函数。譬如您安装的钩子是WH_MOUSE类型,
那么只要有一个鼠标事件发生时,该钩子函数就会被调用。不管您安装的时那一类型钩子,钩子函数的原型都时是一样的:
  HookProc proto nCode:DWORD, wParam:DWORD, lParam:DWORD
  
  nCode 指定是否需要处理该消息
  wParam 和 lParam 包含该消息的附加消息
  HookProc 可以看作是一个函数名的占位符。只要函数的原型一致,您可以给该函数取任何名字。
至于以上的几个参数及返回值的具体含义各种类型的钩子都不相同。譬如:
  WH_CALLWNDPROC
  nCode 只能是HC_ACTION,它代表有一个消息发送给了一个窗口
  wParam 如果非0,代表正被发送的消息
  lParam 指向CWPSTRUCT型结构体变量的指针
  return value: 未使用,返回0
  WH_MOUSE
  nCode 为HC_ACTION 或 HC_NOREMOVE
  wParam 包含鼠标的事件消息
  lParam 指向MOUSEHOOKSTRUCT型结构体变量的指针
  return value: 如果不处理返回0,否则返回非0值
  所以您必须查询您的WIN32 API 指南来得到不同类型的钩子的参数的详细定义以及它们返回值的意义。
这里还有一个问题需要注意:所有的钩子都串在一个链表上,最近加入的钩子放在链表的头部。当一个事件发生时,
WINDOWS将按照从链表头到链表尾调用的顺序。所以您的钩子函数有责任把消息传到下一个链中的钩子函数。
当然您可以不这样做,但是您最好明白这时这么做的原因。在大多数的情况下,最好把消息事件传递下去以便
其它的钩子都有机会获得处理这一消息的机会。调用下一个钩子函数可以调用函数CallNextHookEx。该函数的原型如下:
  CallNextHookEx proto hHook:DWORD, nCode:DWORD, wParam:DWORD, lParam:DWORD
  hHook 时是您自己的钩子函数的句柄。利用该句柄可以遍历钩子链。
  nCode, wParam and lParam 您只要把传入的参数简单传给CallNextHookEx即可。
  请注意:对于远程钩子,钩子函数必须放到DLL中,它们将从DLL中映射到其它的进程空间中去。
当WINDOWS映射DLL到其它的进程空间中去时,不会把数据段也进行映射。简言之,所有的进程仅共享DLL的代码,
至于数据段,每一个进程都将有其单独的拷贝。这是一个很容易被忽视的问题。您可能想当然的以为,
在DLL中保存的值可以在所有映射该DLL的进程之间共享。在通常情况下,由于每一个映射该DLL的进程都有自己的数据段,
所以在大多数的情况下您的程序运行得都不错。但是钩子函数却不是如此。对于钩子函数来说,要求DLL的数据段对所有
的进程也必须相同。这样您就必须把数据段设成共享的,这可以通过在链接开关中指定段的属性来实现。在MASM中您可以这么做:
  /SECTION:<section name>, S
  已初期化的段名是.data,未初始化的段名是.bss。`加入您想要写一个包含钩子函数的DLL,而且想使它的未初始化的
数据段在所有进程间共享,您必须这么做:
  link /section:.bss,S /DLL /SUBSYSTEM:WINDOWS ..........
  S 代表该段是共享段。
  例子:
  一共有两个模块:一个是GUI部分,另一个是安装和卸载钩子的DLL。
  ;--------------------------------------------- 主程序的源代码部分--------------------------------------
  .386
  .model flat,stdcall
  option casemap:none
  include \masm32\include\windows.inc
  include \masm32\include\user32.inc
  include \masm32\include\kernel32.inc
  include mousehook.inc
  includelib mousehook.lib
  includelib \masm32\lib\user32.lib
  includelib \masm32\lib\kernel32.lib
  wsprintfA proto C :DWORD,:DWORD,:VARARG
  wsprintf TEXTEQU <wsprintfA>
  .const
  IDD_MAINDLG equ 101
  IDC_CLASSNAME equ 1000
  IDC_HANDLE equ 1001
  IDC_WNDPROC equ 1002
  IDC_HOOK equ 1004
  IDC_EXIT equ 1005
  WM_MOUSEHOOK equ WM_USER+6
  DlgFunc PROTO :DWORD,:DWORD,:DWORD,:DWORD
  .data
  HookFlag dd FALSE
  HookText db "&Hook",0
  UnhookText db "&Unhook",0
  template db "%lx",0
  .data?
  hInstance dd ?
  hHook dd ?
  .code
  start:
   invoke GetModuleHandle,NULL
   mov hInstance,eax
   invoke DialogBoxParam,hInstance,IDD_MAINDLG,NULL,addr DlgFunc,NULL
   invoke ExitProcess,NULL
  DlgFunc proc h

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -