Hook與回調函數

剛剛接觸Hook(鉤子),在當看到網上一大堆資料的時候感覺懵逼了,而且感覺很多文章寫得都不是我想要知道的,所以在這裡總結下Hook與回調函數。
首先先來說說HOOK好了,鉤子是什麼?但在此之前先要明白Windows的消息機制。

Windows消息機制:
Windows操作系統會向用戶提供界面,它以事件的方式驅動,也就是說,當點擊鼠標,按下鍵盤,都是有事件發生。當發生這個事件時候,OS將預先設定好的消息傳送給應用程序,應用程序收到消息后執行相對應的動作。
舉個例子:假設我們打開了Notepad.exe,這時我們按下‘A’鍵,消息過程是
(1)系統檢測到'A'鍵被按下這個事件發生;
(2)OS將這個事件添加到系統的消息隊列;
(3)OS判斷是哪一個程序發生事件,系統判斷到是Notepad這個程序發生的;
(4)OS從系統消息隊列取出消息,添加到NOtepad(應用程序)消息隊列;
(5)NOtepad(應用程序)監控到應用程序消息隊列有“A”被按下這個消息,對用對應的程序處理這個事件。
通過上面的例子,有些人可能說,這多麻煩啊。應用程序自己檢測有沒有消息不就行了嗎,應用程序檢測到有消息直接作出消息的處理?幹嘛還要通過OS。真的是這樣嗎?首先,鍵盤,鼠標,這些輸入設備都是在底層的,應用程序是不可以調用到底層的東西;其次就算可以調用的底層的設備,意思有按鍵事件發生的時候直接被應用程序處理,OS是多任務操作系統,當打開Notepad,calc后,這時候按下按鍵(會產生按鍵事件),那這個時候應該是Notepad處理這個按鍵事件,還是calc處理這個按鍵事件?(注:第二個解釋可能說得不是很清楚,舉個不是很恰當的例子,科任老師老師(按鍵事件)要找同學A(某應用程序)處理某事,這時科任老師(按鍵事件)就會找到班主任(OS),因為班主任(OS)知道同學們(許多應用程序)的特點;班主任找到同學A來處理,假設某天班主任(OS)不在,科任老師雖然想找一個同學處理某事,卻找不到該找誰了。)

上面了解Windows的消息機制,那麼下面我們來了解Hook
鉤子(HOOK)
從上面的Windows消息機制可以看到,消息先是從系統消息隊列然後在轉到應用程序消息隊列的,這兩者之間會有一個鉤鏈(Hook chain),我們安裝的鉤子就是在鉤鏈上。其實棧空間一樣,先進後出,最後安裝的鉤子最先處理。
下面是設置鉤子函數
HHOOK WINAPI SetWindowsHookEx(
__in int idHook, //idHook:钩子过程类型,
__in HOOKPROC lpfn, //相应的钩子过程,也就是一个处理消息的回调函数名而已
__in HINSTANCE hMod, //指向钩子过程所在的应用程序实例句柄,如钩子过程所在的DLL的句柄
__in DWORD dwThreadId //指定与钩子相关的线程标志。如果为0,那么钩子将与桌面上运行的所有线程相关。
);
應用,設置按鍵消息:
SetWindowsHookEx(
WH_KEYBOARD, //按鍵消息
KeyboardProc, //回調函數
g_hInstance, // 钩子过程所在的DLL的句柄
0 //全局鉤子
);

回調函數
SetWindowsHookEx的第二個參數傳入的是一個函數的地址。那麼這個地址對應的函數,就被稱作回調函數。回調函數有什麼作用,不就是將函數地址傳進來而已嗎?
有三個函數,Fun1();add(int a ,int b),cmp(int a ,int b)
正常的流程,函數Fun1()實現對add(int a ,int b)的函數調用,我們正常的做法無非就是在Fun1中調用add(int a ,int b)。調用如下:
Fun1(){
int a = 3;
int b = 4;
add(a,b);
}
函數Fun1()實現對cmp(int a ,int b)的函數調用,我們正常的做法無非就是在Fun1中調用cmp(int a ,int b)。調用如下:
Fun1(){
int a = 3;
int b = 4;
cmp(int a ,int b)
}
假設這個時候,需要對Fun1()被封裝起來了,那麼就只能使用其中一個功能了,Fun要麼實現add(int a ,int b),要麼cmpadd(int a ,int b),因為某些原因,需要的程序的功能是不定的,也就是某些時候需要Fun需要使用add(int a ,int b),cmp(int a ,int b)。那應該怎麼辦呢?
時候,在Fun1()設置一個函數地址指針變量。當這個地址指向add時,調用add函數,當需要使用cmp(int a ,int b),函數指針指向cmp函數。
在Windows API中很明顯函數都是封裝起來了,例如 WINAPI SetWindowsHookEx,要在SetWindowsHookEx直接添加某個函數功能,顯然是不科學。回調函數就可以輕鬆解決掉該問題。正如上面提到的
SetWindowsHookEx(
WH_KEYBOARD, //按鍵消息
KeyboardProc, //回調函數
g_hInstance, // 钩子过程所在的DLL的句柄
0 //全局鉤子
);
假設需要調用不同的處理函數,只需要把函數地址KeyboardProc,更換就可以了。
就寫到這裡吧。。。

转载于:https://www.cnblogs.com/cyhtide/p/6774459.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值