VB 钩子详解

合集下载

基于VB的键盘钩子算法的实现

基于VB的键盘钩子算法的实现

输入 的运作 ,然 后根据 虚拟键 表判断 按键 的类 型 , 最 后把 得到的准 确的按键类 型输 出。
21 键 盘 工作 流 程 图 ( 1 . 图 )
少 的一 部分 在使 用计算机 进行操 作的 时候 , 经常会 使用 到一些快捷 的操作方 式或获取 键盘 的按键 信息 . 例 如使用 快捷 键来实 现复 制 、粘 贴或 是否 按 了 E c s、
2 键 盘 模 块 ( 2 . 3 图 )
机 息 . 可以强制结 束消息 的传递 。 还 总 2 键 盘 钩 子 的 工作 原 理 第


3 键 盘 钩 子 实现 算 法
使 用 不 同 的 W idw P 函 数 获 取 键 盘 的 动 作 n o sA I

9 1 6
簟 麓纛 蠢
T b 键 a Si t hf 键
vK y sae b e e c p v Ky  ̄ e be H vKy be
vKy rn b eP i t vK y b 2 6 5 9 7
空 格 键 等 操 作 信 息 。 捷 键 具 有 操 作 简单 、 便 、 捷 快 方 快 等优 点 . 就 需 要 我 们 在 编 写 程 序 代 码 的 过 程 中增 加 这 对 键 盘 的 按 键 进 行 判 断 . 个 过 程 就 是 所 谓 的 键 盘 钩 这 子 功 能 利 用 V 在 B来 编 写 所 需 要 的 应 用 程 序 时 . 于 由 V B无 法 直 接 对 系 统 的 注 册 表 进 行 操 作 对 于 此 类 操
图 1 键 盘 工 作 流程 图
22 键 盘的虚拟键 简表 ( 1 . 表 )
在 表 1中 . 一 列 是 系 统 各 个 键 中 的 名 称 . 二 第 第

简单易学 图文并茂 VB系统钩子与快捷键开发

简单易学 图文并茂 VB系统钩子与快捷键开发

简单易学图文并茂 系统钩子与快捷键开发创意和设计目标我喜欢将新建目录或者文件以日期打头,这样很方便排序和查找。

如下图:但每次新建目录后,都要手动输入日期。

这很不方便。

于是想到用快捷键了输入这个日期的创意。

目标是每当新建目录或文件后,按下F5键,自动插入当前日期。

为实现这个功能,可使用VB的Sends函数。

但因为需要程序在后台运行,因此打算把程序图标放到右下角的托盘中。

并且,因为它在按下F5键后执行,因此需要从系统中把按键信息捕捉出来,这就要用到系统钩子。

第一步创建一个Windows应用程序因为未来的程序在后台运行,因此它不需要任何界面。

这里把程序默认创建的Form的透明度设为0,把Border设为None,ControlBox设为0,ShowInTaskBar设为0。

这样它就不会在系统底部的状态栏出现了。

在Form上添加一个NotifyIcon,并指定一个喜欢的图标,这样程序在运行的时候,在右下角的托盘会出现一个图标。

之后,可以再加入一个ContextMenuStrip控件,并把它指定给NotifyIcon,这样右键点击图标的时候可以跳出控制菜单。

为方便调试,我在弹出目录中制作了两个功能,一个是显示和隐藏窗口,这个功能可为今后扩展用;一个是关闭功能,点击它可以关闭这个后台程序。

这两个功能不是我们的重点,这里只把代码贴出来。

***************************************************‘这个程序改变窗口的透明度,则窗口可以在桌面上显示和隐藏Private Sub changeShoe(ByVal sender As System.Object, ByVal e As KeyEventArgs)Select Case Me.OpacityCase 1Me.Opacity = 0Case 0Me.Opacity = 1End SelectEnd Sub‘这里将菜单第一项,即“Show Hide”和上述程序绑定起来Public Sub New()' 此调用是设计器所必需的。

VB_HOOK_使用详解

VB_HOOK_使用详解

VB HOOK(钩子)超级无敌详细用法(介绍)hook是WINDOWS提供的一种消息处理机制,它使得程序员可以使用子过程来监视系统消息,并在消息到达目标过程前得到处理。

下面将介绍WINNDOWS HOOKS并且说明如何在WINDOWS 程序中使用它。

关于HOOKS使用HOOK 将会降低系统效率,因为它增加了系统处量消息的工作量。

建议在必要时才使用HOOK,并在消息处理完成后立即移去该HOOK。

HOOK链WINDOWS提供了几种不同类型的HOOKS;不同的HOOK可以处理不同的消息。

例如,WH_MOUSE HOOK用来监视鼠标消息。

WINDOWS为这几种HOOKS维护着各自的HOOK链。

HOOK链是一个由应用程序定义的回调函数队列,当某种类型的消息发生时,WINDOWS向此种类型的HOOK链的第一个函数发送该消息,在第一函数处理完该消息后由该函数向链表中的下一个函数传递消息,依次向下。

如果链中某个函数没有向下传送该消息,那么链表中后面的函数将得不到此消息。

(对于某些类型的HOOK,不管HOOK链中的函数是否向下传递消息,与此类型HOOK联系的所有HOOK函数都会收到系统发送的消息)HOOK过程为了拦截特定的消息,你可以使用SetWindowsHookEx函数在该类型的HOOK 链中安装你自己的HOOK函数。

该函数语法如下:public function MyHook(nCode,wParam,iParam) as long‘加入代码end function其中MyHook可以随便命名,其它不能变。

该函数必须放在模块段。

nCode指定HOOK类型。

wParam,iParam的取值随nCode不同而不同,它代表了某种类型的HOOK的某个特定的动作。

SetWindowsHookEx总是将你的HOOK函数放置在HOOK链的顶端。

你可以使用CallNextHookEx函数将系统消息传递给HOOK链中的下一个函数。

用VB实现的全局键盘钩子

用VB实现的全局键盘钩子

用VB实现的全局键盘钩子2010-04-06 13:30代码功能:实时监测Caps Lock、NumLock、Scroll Lock三个按件的状态,并显示在Label1 Label2 Label3三个标签中'.bas模块中Public m_hDllKbdHook As Long 'public variable holding'the handle to the hook procedurePublic Const WH_KEYBOARD_LL As Long = 13 'enables monitoring of keyboard 'input events about to be posted 'in a thread input queuePrivate Const HC_ACTION As Long = 0 'wParam and lParam parameters'contain information about a'keyboard messagePublic Const VK_CAPITAL As Long = &H14Public Const VK_NUMLOCK As Long = &H90Public Const VK_SCROLL As Long = &H91Private Const LLKHF_UP As Long = &H80& 'test the transition-state flagPublic Type KeyboardByteskbByte(0 To 255) As ByteEnd TypePrivate Type KBDLLHOOKSTRUCTvkCode As Long 'a virtual-key code in the range 1 to 254 scanCode As Long 'hardware scan code for the keyflags As Long 'specifies the extended-key flag,'event-injected flag, context code,'and transition-state flagtime As Long 'time stamp for this messagedwExtraInfo As Long 'extra info associated with the messageEnd TypePublic Declare Function SetWindowsHookEx Lib "user32" _Alias "SetWindowsHookExA" _(ByVal idHook As Long, _ByVal lpfn As Long, _ByVal hmod As Long, _ByVal dwThreadId As Long) As LongPublic Declare Function UnhookWindowsHookEx Lib "user32" _(ByVal hHook As Long) As LongPublic Declare Function CallNextHookEx Lib "user32" _(ByVal hHook As Long, _ByVal nCode As Long, _ByVal wParam As Long, _ByVal lParam As Long) As LongPublic Declare Sub CopyMemory Lib "kernel32" _Alias "RtlMoveMemory" _(pDest As Any, _pSource As Any, _ByVal cb As Long)Public Declare Function GetKeyboardState Lib "user32" _(kbArray As KeyboardBytes) As LongPublic Declare Function GetKeyState Lib "user32" _(ByVal nVirtKey As Long) As IntegerPublic Function LowLevelKeyboardProc(ByVal nCode As Long, _ByVal wParam As Long, _ByVal lParam As Long) As Long Dim kbdllhs As KBDLLHOOKSTRUCTIf nCode = HC_ACTION ThenCall CopyMemory(kbdllhs, ByVal lParam, Len(kbdllhs))If (kbdllhs.flags And LLKHF_UP) ThenSelect Case kbdllhs.vkCodeCase VK_NUMLOCKbel1.Visible = (GetKeyState(VK_NUMLOCK) = &HFF81)Case VK_CAPITALbel2.Visible = (GetKeyState(VK_CAPITAL) = &HFF81)Case VK_SCROLLbel3.Visible = (GetKeyState(VK_SCROLL) = &HFF81)Case ElseEnd SelectEnd IfEnd If 'nCode = HC_ACTIONLowLevelKeyboardProc = CallNextHookEx(m_hDllKbdHook, _nCode, _wParam, _lParam)End FunctionForm1中加入3个标签控件Label1、Label2、Label3Form1中的代码Private Sub Form_Load()Dim kbdState As KeyboardBytesCall GetKeyboardState(kbdState)With Label1.Caption = "Numlock is ON".Alignment = vbRightJustifyEnd WithWith Label2.Caption = "Caps lock is ON".Alignment = vbRightJustifyEnd WithWith Label3.Caption = "Scroll lock is ON".Alignment = vbRightJustifyEnd WithLabel1.Visible = kbdState.kbByte(VK_NUMLOCK) = 1Label2.Visible = kbdState.kbByte(VK_CAPITAL) = 1Label3.Visible = kbdState.kbByte(VK_SCROLL) = 1'set and obtain the handle to the keyboard hookm_hDllKbdHook = SetWindowsHookEx(WH_KEYBOARD_LL, _AddressOf LowLevelKeyboardProc, _ App.hInstance, _0&)If m_hDllKbdHook = 0 ThenMsgBox "Failed to install low-level keyboard hook."End IfEnd SubPrivate Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)If m_hDllKbdHook <> 0 ThenCall UnhookWindowsHookEx(m_hDllKbdHook)End IfEnd Sub'还有一段可以禁用Ctrl+Esc Alt + Esc Alt+Tab三组热键的Private Const WH_KEYBOARD_LL = 13& 'enables monitoring of keyboard 'input events about to be posted 'in a thread input queuePrivate Const HC_ACTION = 0& 'wParam and lParam parameters 'contain information about a'keyboard messagePrivate Const LLKHF_EXTENDED = &H1& 'test the extended-key flag Private Const LLKHF_INJECTED = &H10& 'test the event-injected flag Private Const LLKHF_ALTDOWN = &H20& 'test the context codePrivate Const LLKHF_UP = &H80& 'test the transition-state flag Private Const VK_TAB = &H9 'virtual key constantsPrivate Const VK_CONTROL = &H11Private Const VK_ESCAPE = &H1BPrivate Type KBDLLHOOKSTRUCTvkCode As Long 'a virtual-key code in the range 1 to 254 scanCode As Long 'hardware scan code for the keyflags As Long 'specifies the extended-key flag,'event-injected flag, context code,'and transition-state flagtime As Long 'time stamp for this messagedwExtraInfo As Long 'extra info associated with the messageEnd TypePrivate Declare Function SetWindowsHookEx Lib "user32" _Alias "SetWindowsHookExA" _(ByVal idHook As Long, _ByVal lpfn As Long, _ByVal hmod As Long, _ByVal dwThreadId As Long) As LongPrivate Declare Function UnhookWindowsHookEx Lib "user32" _(ByVal hHook As Long) As LongPrivate Declare Function CallNextHookEx Lib "user32" _(ByVal hHook As Long, _ByVal nCode As Long, _ByVal wParam As Long, _ByVal lParam As Long) As LongPrivate Declare Sub CopyMemory Lib "kernel32" _Alias "RtlMoveMemory" _(pDest As Any, _pSource As Any, _ByVal cb As Long)Private Declare Function GetAsyncKeyState Lib "user32" _(ByVal vKey As Long) As IntegerPrivate m_hDllKbdHook As Long 'private variable holding'the handle to the hook procedure Public Sub Main()'set and obtain the handle to the keyboard hookm_hDllKbdHook = SetWindowsHookEx(WH_KEYBOARD_LL, _AddressOf LowLevelKeyboardProc, _ App.hInstance, _0&)If m_hDllKbdHook <> 0 ThenMsgBox "Ctrl+Esc, Alt+Tab and Alt+Esc are blocked. " & _"Click OK to quit and re-enable the keys.", _vbOKOnly Or vbInformation, _"Keyboard Hook Active"Call UnhookWindowsHookEx(m_hDllKbdHook)ElseMsgBox "Failed to install low-level keyboard hook - " & stDllErrorEnd IfEnd SubPublic Function LowLevelKeyboardProc(ByVal nCode As Long, _ByVal wParam As Long, _ByVal lParam As Long) As LongStatic kbdllhs As KBDLLHOOKSTRUCTIf nCode = HC_ACTION ThenCall CopyMemory(kbdllhs, ByVal lParam, Len(kbdllhs))'Ctrl+Esc --------------If (kbdllhs.vkCode = VK_ESCAPE) And _CBool(GetAsyncKeyState(VK_CONTROL) _And &H8000) ThenDebug.Print "Ctrl+Esc blocked"LowLevelKeyboardProc = 1Exit FunctionEnd If 'kbdllhs.vkCode = VK_ESCAPE'Alt+Tab --------------If (kbdllhs.vkCode = VK_TAB) And _CBool(kbdllhs.flags And _LLKHF_ALTDOWN) ThenDebug.Print "Alt+Tab blocked"LowLevelKeyboardProc = 1Exit FunctionEnd If 'kbdllhs.vkCode = VK_TAB'Alt+Esc --------------If (kbdllhs.vkCode = VK_ESCAPE) And _CBool(kbdllhs.flags And _LLKHF_ALTDOWN) ThenDebug.Print "Alt+Esc blocked"LowLevelKeyboardProc = 1Exit FunctionEnd If 'kbdllhs.vkCode = VK_ESCAPEEnd If 'nCode = HC_ACTIONLowLevelKeyboardProc = CallNextHookEx(m_hDllKbdHook, _ nCode, _wParam, _lParam)End Function。

VB键盘钩子源码:截取一切键盘按键

VB键盘钩子源码:截取一切键盘按键

VB键盘钩子源码:截取一切键盘按键(2011-07-15 10:52:11)转载▼分类:我的VB标签:杂谈1、UI设计:2、程序源码:(1)FrmHook源码Option ExplicitDim WithEvents Hook As ClsHook '创建一个需要事件支持的Hook为模块ClsHookPrivate Declare Function MapVirtualKeyEx Lib "user32" Alias "MapVirtualKeyExA" (ByVal uCode As Long, ByVal uMapType As Long, ByVal dwhkl As Long) As Long'根据指定的映射类型,执行不同的扫描码和字符转换'' uCode Long,欲转换的源字符或代码' uMapType Long,控制映射类型,如下所示' 0 —— uCode是个虚拟键码?函数返回相应的扫描码' 1 —— uCode是个扫描码?函数返回相应的虚拟键码' 2—— uCode是个虚拟键码。

函数返回相应的ASCII值(未加Shift组合键)。

针对死键,高位设为1。

如果出错,返回NULL' dwhkl Long,键盘布局的句柄Private Declare Function GetKeyboardLayout Lib "user32" (ByVal dwLayout As Long) As Long'取得一个句柄,描述指定应用程序的键盘布局' dwLayout ,//欲检查的线程的标识符Private Declare Function GetForegroundWindow Lib "user32" () As LongPrivate Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long'获取与指定窗口关联在一起的一个进程和线程标识符' lpdwProcessId Long,指定一个变量,用于装载拥有那个窗口的一个进程的标识符' hwnd Long,指定窗口句柄Private Sub Form_Load()Set Hook = New ClsHookHook.SetHook'App.TaskVisible = FalseMe.HideEnd SubPrivate Sub Form_Unload(Cancel As Integer)Hook.UnHookSet Hook = NothingEnd SubPrivate Sub Hook_KeyDown(KeyCode As Integer, Shift As Integer) '钩子的KeyDown事件,在模块中我们自己定义的事件KeyDownDim StrCode As StringStrCode = CodeToString(KeyCode)'判断ShiftIf StrCode = "[Shift]" Or StrCode = "[Alt]" Or StrCode = "[Ctrl]" ThenIf Shift = vbAltMask + vbCtrlMask Then StrCode = "[Alt + Ctrl]"If Shift = vbAltMask + vbShiftMask Then StrCode = "[Alt + Shift]"If Shift = vbCtrlMask + vbShiftMask Then StrCode = "[Ctrl + Shift]"If Shift = vbCtrlMask + vbShiftMask + vbAltMask Then StrCode = "[Ctrl + Shift +Alt]"ElseIf Shift = vbShiftMask Then StrCode = StrCode & " + [Shift]"If Shift = vbCtrlMask Then StrCode = StrCode & " + [Ctrl]"If Shift = vbAltMask Then StrCode = StrCode & " + [Alt]"If Shift = vbAltMask + vbCtrlMask Then StrCode = StrCode & " + [Alt + Ctrl]"If Shift = vbAltMask + vbShiftMask Then StrCode = StrCode & " + [Alt + Shift]"If Shift = vbCtrlMask + vbShiftMask Then StrCode = StrCode & " + [Ctrl + Shift]"If Shift = vbCtrlMask + vbShiftMask + vbAltMask Then StrCode = StrCode & " + [Ctrl + Shift+Alt]"End If'热键Ctrl+J,呼出窗口If StrCode = "[j] + [Ctrl]" ThenMe.ShowApp.TaskVisible = TrueEnd IfText1.Text = Text1.Text & Now & "------" & StrCode & vbCrLfEnd Sub'把按键码换为StringPrivate Function CodeToString(nCode As Integer) As String Dim StrKey As StringSelect Case nCodeCase vbKeyBack: StrKey = "BackSpace"Case vbKeyTab: StrKey = "Tab"Case vbKeyClear: StrKey = "Clear"Case vbKeyReturn: StrKey = "Enter"Case vbKeyShift: StrKey = "Shift"Case vbKeyControl: StrKey = "Ctrl"Case vbKeyMenu: StrKey = "Alt"Case vbKeyPause: StrKey = "Pause"Case vbKeyCapital: StrKey = "CapsLock"Case vbKeyEscape: StrKey = "ESC"Case vbKeySpace: StrKey = "SPACEBAR"Case vbKeyPageUp: StrKey = "PAGE UP"Case vbKeyPageDown: StrKey = "PAGE DOWN"Case vbKeyEnd: StrKey = "END"Case vbKeyHome: StrKey = "HOME"Case vbKeyLeft: StrKey = "LEFT ARROW"Case vbKeyUp: StrKey = "UP ARROW"Case vbKeyRight: StrKey = "RIGHT ARROW"Case vbKeyDown: StrKey = "DOWN ARROW"Case vbKeySelect: StrKey = "SELECT"Case vbKeyPrint: StrKey = "PRINT SCREEN"Case vbKeyExecute: StrKey = "EXECUTE"Case vbKeySnapshot: StrKey = "SNAPSHOT"Case vbKeyInsert: StrKey = "INS"Case vbKeyDelete: StrKey = "DEL"Case vbKeyHelp: StrKey = "HELP"Case vbKeyNumlock: StrKey = "NUM LOCK"Case vbKey0 To vbKey9: StrKey = Chr$(nCode)Case vbKeyA To vbKeyZ: StrKey = LCase(Chr$(nCode)) 'MapVirtualKeyEx(nCode, 2, GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow, 0))))Case vbKeyF1 To vbKeyF16: StrKey = "F" & CStr(nCode - 111)Case vbKeyNumpad0 To vbKeyNumpad9: StrKey = "Numpad " & CStr(nCode - 96)Case vbKeyMultiply: StrKey = "Numpad {*}"Case vbKeyAdd: StrKey = "Numpad {+}"Case vbKeySeparator: StrKey = "Numpad {ENTER}"Case vbKeySubtract: StrKey = "Numpad {-}"Case vbKeyDecimal: StrKey = "Numpad {.}"Case vbKeyDivide: StrKey = "Numpad {/}"Case ElseStrKey = Chr$(MapVirtualKeyEx(nCode, 2, GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow, 0)))) End SelectCodeToString = "[" & StrKey & "]"End FunctionPrivate Sub text1_Change()Text1.SelStart = Len(Text1.Text)End Sub(2)ModHook源码Option ExplicitPublic Declare Function CallNextHookEx Lib "user32.dll" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lparam As Any) As LongPublic Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)Public OldHook As Long '全局变量OldHook存储钩子句柄Public LngClsPtr As Long '保存对象地址'回调函数Public Function BackHook(ByVal nCode As Long, ByVal wParam As Long, ByVal lparam As Long) As LongIf nCode < 0 Then '如果nCode小于0,上次就说过喽,小于0代表没有拦截到键盘消息;当nCode为0的时候,所有的键盘消息都将被拦截,BackHook = CallNextHookEx(OldHook, nCode, wParam, lparam) 'wParam为消息的种类(种类知道吧?KeyDown ……)lparam存储了拦截到的消息;没有拦截到消息只好呼叫下个钩子Exit FunctionEnd IfResolvePointer(LngClsPtr).RiseEvent (lparam) '得到消息的地址'处理过后一定要将消息归还给系统,难免还有别人要这个消息呢?Call CallNextHookEx(OldHook, nCode, wParam, lparam)End Function'得到对象的地址Private Function ResolvePointer(ByVal lpObj As Long) As ClsHookDim oSH As ClsHookCopyMemory oSH, lpObj, 4&Set ResolvePointer = oSHCopyMemory oSH, 0&, 4&End Function(3)ClsHook源码:Option Explicit '声明,在VB中,开头使用声明可以减少很多的错误Public Event KeyDown(KeyCode As Integer, Shift As Integer) '自定义事件KeyDownPrivate Type EVENTMSG '定义事件消息的类型wMsg As Long '消息lParamLow As LonglParamHigh As LongmsgTime As Long '消息时间hWndMsg As Long '消息句柄End Type'Private Const WH_GETMESSAGE As Long = 3Private Const WH_JOURNALRECORD = 0Private Const WM_KEYDOWN = &H100Private Declare Function SetWindowsHookEx Lib "user32.dll" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long 'dwThreadId监控代码,0为全局钩子Private Declare Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hHook As Long) As Long Private Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Integer Public Sub SetHook()OldHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf BackHook, App.hInstance, 0) End SubPublic Sub UnHook()Call UnhookWindowsHookEx(OldHook)End SubFriend Function RiseEvent(ByVal lparam As Long) As LongDim Msg As EVENTMSGDim IntShift As Integer 'ShiftDim IntCode As Integer 'KeyCodeCopyMemory Msg, ByVal lparam, Len(Msg) '利用指针技术将消息从lparam中的数据拷贝到Msg的地址中,简单的说就是把lparam的数据赋值给MsgIntShift = 0Select Case Msg.wMsg '检查消息状态Case WM_KEYDOWN '如果消息的事件为KeyDown(键盘按下)'得到Shift,Ctrl,Alt的按键状态If GetAsyncKeyState(vbKeyShift) Then IntShift = (IntShift Or 1)If GetAsyncKeyState(vbKeyControl) Then IntShift = (IntShift Or 2)If GetAsyncKeyState(vbKeyMenu) Then IntShift = (IntShift Or 4)IntCode = Msg.lParamLow And &HFF '得到KeyCode(及按键码)RaiseEvent KeyDown(IntCode, IntShift) 'RaiseEvent 引发模块(ClsHook)中声明的事件KeyDownEnd SelectEnd FunctionPrivate Sub Class_Initialize() '初始化类LngClsPtr = ObjPtr(Me) 'ObjPtr,返回对象的地址,将本类的存储地址返回给变量LngClsPtrEnd Sub3、软件运行效果:运行后自动隐藏,按ctrl+j调出程序显示:。

VB外挂之HOOK技术的最详细教程

VB外挂之HOOK技术的最详细教程

vb外挂之HOOK技术终极详细解说By:史上最大小强很多学习vb的人都想学习外挂及hook,我在网上也找到了一段程序,后台键盘记录外挂,其实网上大多数流传的HOOK代码都跟这段代码几乎一个出处。

网上有关于这些代码的解释,但是关键部分根本就没解释,等于没说。

下面的程序解释得很详细。

有的地方全属个人看法,不过还是值得一看。

不对的地方欢迎大家指出。

当然,高手勿笑。

好吧,正式我们的hook学习。

Hook并不神秘,它说到底就是通过调用API函数在消息队列中安装钩子,实现截获消息,处理消息的功能。

在这里,我浅浅的讲讲windows的消息机制。

比如,我们按键盘的某个键时,系统就会生成一个消息到系统的消息队列,系统再发送到应用程序消息队列中,windows有不同的消息队列。

对于键盘钩子,是安装在系统的消息队列中。

看程序:(以下程序在模块中,呵呵,工程-----添加模块)Option Explicit ‘强制性变量声明,不允许出现未声明的变量。

呵呵,都懂!!Public Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer‘Getkeystate是api函数,顾名思义,获取某个键的状态,参数nvirtkey就是某个键的虚拟键键码,不同的系统虚拟键码不同。

比如vbkeycontrol或者vbkeyshift就可以作为参数。

返回值是16位的,如开关键打开,则位0设为1(开关键包括CapsLock,NumLock,ScrollLock);如某个键当时正处于按下状态,则位15为1;如已经抬起,则为0。

数据在储存器中,最高位为1时是负数,为0时是正数。

Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long‘Setwindowshookex,就是建立钩子的函数,最主要的的函数。

VB 钩子详解

VB 钩子详解

Windows钩子函数的概念和实现方法首先我们必须大致了解Windows的基本运作机理,Windows作为一个多任务操作系统,它是分有层次概念的,运行在最底下的称为Ring 0层,在这一层里基本上都是一些硬件驱动程序和Windows的总内核,一般的应用程序极少极少运行在这层,当然也有例外,例如调试软件SoftICE(不过基本上这个软件的作用是Crack软件而不是调试)、还原精灵还有分区魔法大师,就是运行在Ring 0层的,另外就是著名的CIH病毒。

运行在Ring 0级的程序能够对所有硬件进行直接地址级访问,所受到的限制也最小。

消息(Message)传递是Windows独有的一种机制,因为Windows规定运行在Ring 0以上的程序是没有权利知道究竟硬件发生了怎样的中断变化的,Windows统一将这些中断变化封装成一系列的消息(黑箱作业,也就是常说的Black Box),比如鼠标移动,系统产生一个OnMouseMove消息(但这条消息从何而来,相关的硬件中断向量是什么,程序无从得知),OnMouseMove这条消息最后送达每一个窗口程序以供处理。

在更高层次的地方,比如说控件级,所有的消息还被封装成一系列“事件”,比如TextBox控件有KeyPress事件,实际上,这些事件都是林林种种的消息映射。

事件的概念使得程序员能够更加傻瓜化地进行编程,但是从另一个角度来说,这种黑箱作业也使得程序员过分依赖系统的安排,限制了程序员的思维,举个例子,Windows为按钮控件封装了大部分常用的属性和事件,完成一般的常规妈作是没有问题的,但是很遗憾,或许是Windows的疏忽,按钮控件的字体颜色永远默认是黑色,而且Windows没有为此提供一个专门的接口来修改,碰到这种情况,程序员就会非常头疼。

钩子函数(Hook Function),就像一把钩子,它的作用是将消息在抵达窗口程序之前先钩到一个地方以便程序员进行分析,这个地方称为挂接函数链,消息在这里先被一系列的函数处理然后由程序员决定是否交还给Windows系统,在这里,你可以“吞噬”(Lickup)一些你不希望发生的消息,比如说你吞掉所有的键盘消息而不交还给系统,那么键盘将会失灵。

vb外挂HOOK终极解说

vb外挂HOOK终极解说

vb外挂之HOOK技术终极详细解说阿祥(qq:475335620)很多学习vb的人都想学习外挂及hook,我在网上也找到了一段程序,后台键盘记录外挂,其实网上大多数流传的HOOK代码都跟这段代码几乎一个出处。

网上有关于这些代码的解释,但是关键部分根本就没解释,等于没说。

下面的程序解释得很详细。

有的地方全属个人看法,不过还是值得一看。

不对的地方欢迎大家指出。

当然,高手勿笑。

插入一段。

(现在做软件都卖不到钱,比如外挂脚本交易平台,能赚钱的作者都是那几个,不是跟网站勾搭、就是确实很厉害的人,我就不信能写出“anjian精灵”的人找不到能编外挂的人。

所以,想拼命成为作者的人大多数都是浪费精力,成为了作者大多数都赚不到钱。

不如写个开源的,还能促进社会进步,呵呵。

)好吧,正式我们的hook学习。

Hook并不神秘,它说到底就是通过调用API函数在消息队列中安装钩子,实现截获消息,处理消息的功能。

在这里,我浅浅的讲讲windows的消息机制。

比如,我们按键盘的某个键时,系统就会生成一个消息到系统的消息队列,系统再发送到应用程序消息队列中,windows有不同的消息队列。

对于键盘钩子,是安装在系统的消息队列中。

看程序:(以下程序在模块中,呵呵,工程-----添加模块)Option Explicit ‘强制性变量声明,不允许出现未声明的变量。

呵呵,都懂!!Public Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer‘Getkeystate是api函数,顾名思义,获取某个键的状态,参数nvirtkey就是某个键的虚拟键键码,不同的系统虚拟键码不同。

比如vbkeycontrol或者vbkeyshift就可以作为参数。

返回值是16位的,如开关键打开,则位0设为1(开关键包括CapsLock,NumLock,ScrollLock);如某个键当时正处于按下状态,则位15为1;如已经抬起,则为0。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Windows钩子函数的概念和实现方法首先我们必须大致了解Windows的基本运作机理,Windows作为一个多任务操作系统,它是分有层次概念的,运行在最底下的称为Ring 0层,在这一层里基本上都是一些硬件驱动程序和Windows的总内核,一般的应用程序极少极少运行在这层,当然也有例外,例如调试软件SoftICE(不过基本上这个软件的作用是Crack软件而不是调试)、还原精灵还有分区魔法大师,就是运行在Ring 0层的,另外就是著名的CIH病毒。

运行在Ring 0级的程序能够对所有硬件进行直接地址级访问,所受到的限制也最小。

消息(Message)传递是Windows独有的一种机制,因为Windows规定运行在Ring 0以上的程序是没有权利知道究竟硬件发生了怎样的中断变化的,Windows统一将这些中断变化封装成一系列的消息(黑箱作业,也就是常说的Black Box),比如鼠标移动,系统产生一个OnMouseMove消息(但这条消息从何而来,相关的硬件中断向量是什么,程序无从得知),OnMouseMove这条消息最后送达每一个窗口程序以供处理。

在更高层次的地方,比如说控件级,所有的消息还被封装成一系列“事件”,比如TextBox控件有KeyPress事件,实际上,这些事件都是林林种种的消息映射。

事件的概念使得程序员能够更加傻瓜化地进行编程,但是从另一个角度来说,这种黑箱作业也使得程序员过分依赖系统的安排,限制了程序员的思维,举个例子,Windows为按钮控件封装了大部分常用的属性和事件,完成一般的常规妈作是没有问题的,但是很遗憾,或许是Windows的疏忽,按钮控件的字体颜色永远默认是黑色,而且Windows没有为此提供一个专门的接口来修改,碰到这种情况,程序员就会非常头疼。

钩子函数(Hook Function),就像一把钩子,它的作用是将消息在抵达窗口程序之前先钩到一个地方以便程序员进行分析,这个地方称为挂接函数链,消息在这里先被一系列的函数处理然后由程序员决定是否交还给Windows系统,在这里,你可以“吞噬”(Lickup)一些你不希望发生的消息,比如说你吞掉所有的键盘消息而不交还给系统,那么键盘将会失灵。

当然,经过了这道周折,系统效率将会有极其微小的降低,但是,由于Windows规定所有不运行在Ring 0层的程序都不能直接访问硬件中断,因此作为一种中断驱动程序的补充,钩子函数在很多场合下是非常有用的,有时候甚至是唯一的方法。

下面就以键盘拦截为例讲述钩子函数的使用方法:首先定义以下API:Public Declare Function SetWindowsHookEx Lib "user32" _Alias "SetWindowsHookExA" (ByVal idHook As Long, _ByVal lpfn As Long, _ByVal hmod As Long, _ByVal dwThreadId As Long) As LongSetWindowsHookEx,这个函数是一切钩子函数的根本,其作用是通知Windows进行钩子妈作并定义钩子函数。

参数1,idHook为定义需要进行的拦截类型,是键盘拦截?鼠标拦截?还是别的。

如 WH_KEYBOARD捕捉键盘消息,而WH_MOUSE捕捉鼠标消息。

参数2,lpfn为该挂接函数链的首地址指针,因为VB是没有指针这种数据类型的所以用Long 代替。

lpfn为钩子函数,在 VB中可以使用 AddressOf 获得钩子函数的地址。

这个函数因为钩子类型不同而有所不同。

如键盘钩子为:Public Function KeyboardProc(ByVal nCode As Long, _ByVal wParam As Long, _ByVal lParam As Long) As Long如果 Code 不为 0,钩子函数必须调用 CallNextHookEx,将消息传递给下面的钩子。

wParam 和 lParam不是按键。

参数3,hmod为创建钩子函数那个实体的句柄,即你的程序本身的句柄(handle),hmod用于全局钩子,VB要实现钩子,必须设为0。

(关于句柄:每一个程序都有一个ID号称为进程,句柄则分得更细,每一个进程里的每一个控件的ID号称为句柄。

比如一个程序既有输入框又有下拉条,那么下拉条和输入框都有自己的ID号,这个称为句柄。

)参数4,dwThreadId ,为监控代码,0表示全局监控,dwThreadId用于线程钩子 VB 中可以设置为 App.ThreadID。

UnhookWindowsHookEx 函数为释放钩子,将钩子函数所占用的资源交还给系统,起一个简单的清道夫功能。

Private Declare Sub CopyMemory Lib "kernel32" _Alias "RtlMoveMemory" _(pDest As Any, _pSource As Any, _ByVal cb As Long)CopyMemory 作用是将内存里的某一块数据pSource拷贝到另一个地址pDest。

最后一个参数cb表示拷贝内容的字节大小。

Private Declare Function GetAsyncKeyState Lib "user32" _(ByVal vKey As Long) As IntegerGetAsyncKeyState作用是获得各种辅助功能键的状态(如CTRL,SHIFT什么的)。

Private Declare Function CallNextHookEx Lib "user32" _(ByVal hHook As Long, _ByVal nCode As Long, _ByVal wParam As Long, _ByVal lParam As Long) As LongCallNextHookEx 挂钩函数拦截了某条消息后,由CallNextHookEx决定是否将这些消息送还给Windows系统。

Private Type KBDLLHOOKSTRUCTvkCode As LongscanCode As Longflags As Longtime As LongdwExtraInfo As LongEnd TypeKBDLLHOOKSTRUCT为键盘钩子的结构体定义,关于该结构的成员,我没有从API函数帮助库里找到任何资源,不过大概猜也能猜出来。

成员1:vkCode为虚拟键码成员2:scanCode为扫描码成员3:flags为功能键状态成员4:扩展信息?实际上本例中我们只是需要简单的知道vkCode然后用chr函数置换成字符即可,所谓的vkCode实际上和ASCIIC码是一一对应的。

Private Const HC_ACTION = 0Private Const LLKHF_EXTENDED = &H1Private Const LLKHF_INJECTED = &H10Private Const LLKHF_ALTDOWN = &H20Private Const LLKHF_UP = &H80Private Const WH_KEYBOARD_LL = 13&Public Const VK_TAB = &H9Public Const VK_CONTROL = &H11Public Const VK_ESCAPE = &H1BPublic Const VK_DELETE = &H2E以上10个定义为常量定义,常量定义没有什么特别好说的,仅仅是帮助记忆而已。

你完全可以在使用VK_DELETE的地方使用&H2E,如果你觉得&H2E比VK_DELETE更容易理解的话...Public KeyboardHandle As Long全局变量KeyboardHandle 为键盘钩子函数句柄,这个变量在开始挂钩的时候产生,结束挂钩的时候需要用它进行清场。

好了,现在我们开始工作:首先创建一个工程,因为我们需要一个实体来运行我们的钩子函数,所以必须创建一个工程,在窗体部分填写:Private Const WH_KEYBOARD_LL = 13&Windows规定,键盘拦截的ID号为13号拦截。

Public Sub HookKeyboard()KeyboardHandle = SetWindowsHookEx( _WH_KEYBOARD_LL, AddressOf KeyboardCallback, _App.hInstance, 0&)End Sub定义一个不带参数的子程序HookKeyboard,KeyboardHandle 存储钩子函数所产生的ID号,这个在清场的时候需要用到。

SetWindowsHookEx 的4个参数,第一个,WH_KEYBOARD_LL, 正如前面定义的常量,它为13第二个,AddressOf KeyboardCallback,这是自VB5以来的一次革命,VB5之后增加了一个保留字AddressOf,它的作用是获取某一个函数的首地址指针,在VB5之前的版本是没有这个功能的,有了AddressOf,大大扩展了VB的功能,才使得VB能够调用绝大部分API函数。

因为VB本身并不存在指针。

此行的意思是获得挂接函数链的首地址。

第三个,App.hInstance,App也是VB的保留字,表示本程序本身,如App.Path表示本程序当前目录,App.hInstance表示的是本程序本身的句柄,关于句柄前面已有所描述。

第四个,0,表示全局拦截,意思就是拦截所有窗口下的键盘输入。

定义完钩子函数,下面进入函数的具体实现,这些函数属于全局函数,所以不能在窗体级定义,必须降低到“模块”级别,现创建一个模块,然后开始编写,注:在VB里调用API几乎都是模块级的,很少出现在窗体级。

实际不必深究这个问题,只要记住凡是调用API就用模块来编写就没错了。

Public Function KeyboardCallback(ByVal Code As Long, _ByVal wParam As Long, ByVal lParam As Long) As LongStatic Hookstruct As KBDLLHOOKSTRUCTIf (Code = HC_ACTION) ThenCall CopyMemory(Hookstruct, ByVal lParam, Len(Hookstruct))If (IsHooked(Hookstruct)) ThenKeyboardCallback = 1Exit FunctionEnd IfEnd IfKeyboardCallback = CallNextHookEx(KeyboardHandle, _Code, wParam, lParam)End Function函数KeyboardCallback,是整个钩子函数的核心,参数1:Code,表示拦截层次,之前我们已经说过,如果Code为0,则拦截所有窗口的键盘输入。

相关文档
最新文档