日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅谈HOOK

發布時間:2023/12/16 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈HOOK 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要: 本文針對HOOK技術在VC編程中的應用進行討論,并著重對應用比較廣泛的全局HOOK做了闡述。

  一、引言

  Windows操作系統是建立在事件驅動機制之上的,系統各部分之間的溝通也都是通過消息的相互傳遞而實現的。但在通常情況下,應用程序只能處理來自進程內部的消息或是從其他進程發過來的消息如果需要對在進程外傳遞的消息進行攔截處理就必須采取一種被稱為HOOK(鉤子)的技術。鉤子是Windows操作系統中非常重要的一種系統接口,用它可以輕松截獲并處理在其他應用程序之間傳遞的消息,并由此可以完成一些普通應用程序難以實現的特殊功能。基于鉤子在消息攔截處理中的強大功能,本文即以VC++ 6.0為編程背景對鉤子的基本概念及其實現過程展開討論。為方便理解,在文章最后還給出了一個簡單的有關鼠標鉤子的應用示例。

  二、鉤子的基本原理

  鉤子的本質是一段用以處理系統消息的程序,通過系統調用,將其掛入到系統。鉤子的種類有很多,每一種鉤子負責截獲并處理相應的消息。鉤子機制允許應用程序截獲并處理發往指定窗口的消息或特定事件,其監視的窗口即可以是本進程內的也可以是由其他進程所創建的。在特定的消息發出,并在到達目的窗口之前,鉤子程序先行截獲此消息并得到對其的控制權。此時在鉤子函數中就可以對截獲的消息進行各種修改處理,甚至強行終止該消息的繼續傳遞。

  任何一個鉤子都由系統來維護一個指針列表(鉤子鏈表),其指針指向鉤子的各個處理函數。最近安裝的鉤子放在鏈的開始,最早安裝的鉤子則放在最后,當鉤子監視的消息出現時,操作系統調用鏈表開始處的第一個鉤子處理函數進行處理,也就是說最后加入的鉤子優先獲得控制權。在這里提到的鉤子處理函數必須是一個回調函數(callback function),而且不能定義為類成員函數,必須定義為普通的C函數。在使用鉤子時可以根據其監視范圍的不同將其分為全局鉤子線程鉤子兩大類,其中線程鉤子只能監視某個線程,而全局鉤子則可對在當前系統下運行的所有線程進行監視。顯然,線程鉤子可以看作是全局鉤子的一個子集,全局鉤子雖然功能強大但同時實現起來也比較煩瑣:其鉤子函數的實現必須封裝在動態鏈接庫中才可以使用。

  鉤子的安裝與卸載

  由于全局鉤子具有相當的廣泛性而且在功能上完全覆蓋了線程鉤子,因此下面就主要對應用較多的全局鉤子的安裝與使用進行討論。前面已經提過,操作系統是通過調用鉤子鏈表開始處的第一個鉤子處理函數而進行消息攔截處理的。因此,為了設置鉤子,只需將回調函數放置于鏈首即可,操作系統會使其首先被調用。在具體實現時由函數SetWindowsHookEx()負責將回調函數放置于鉤子鏈表的開始位置。SetWindowsHookEx()函數原型聲明如下:

HHOOK SetWindowsHookEx(int idHook;
HOOKPROC lpfn;
HINSTANCE hMod;
DWORD dwThreadId);

  其中:參數idHook 指定了鉤子的類型,總共有如下13種:

   WH_CALLWNDPROC 系統將消息發送到指定窗口之前的"鉤子"
   WH_CALLWNDPROCRET 消息已經在窗口中處理的"鉤子"
   WH_CBT 基于計算機培訓的"鉤子"
   WH_DEBUG 差錯"鉤子"
   WH_FOREGROUNDIDLE 前臺空閑窗口"鉤子"
   WH_GETMESSAGE 接收消息投遞的"鉤子"
   WH_JOURNALPLAYBACK 回放以前通過WH_JOURNALRECORD"鉤子"記錄的輸入消息
   WH_JOURNALRECORD 輸入消息記錄"鉤子"
   WH_KEYBOARD 鍵盤消息"鉤子"
   WH_MOUSE 鼠標消息"鉤子"
   WH_MSGFILTER 對話框、消息框、菜單或滾動條輸入消息"鉤子"
   WH_SHELL 外殼"鉤子"
   WH_SYSMSGFILTER 系統消息"鉤子"

  參數lpfn為指向鉤子處理函數的指針,即回調函數的首地址;參數hMod則標識了鉤子處理函數所處模塊的句柄;第四個參數dwThreadId 指定被監視的線程,如果明確指定了某個線程的ID就只監視該線程,此時的鉤子即為線程鉤子如果該參數被設置為0,則表示此鉤子為監視系統所有線程的全局鉤子。此函數在執行完后將返回一個鉤子句柄。

  雖然對于線程鉤子并不要求其象全局鉤子一樣必須放置于動態鏈接庫中,但是推薦其也在動態鏈接庫中實現。因為這樣的處理不僅可使鉤子可為系統內的多個進程訪問,也可以在系統中被直接調用,而且對于一個只供單進程訪問的鉤子,還可以將其鉤子處理過程放在安裝鉤子的同一個線程內,此時SetWindowsHookEx()函數的第三個參數也就是該線程的實例句柄。

  在SetWindowsHookEx()函數完成對鉤子的安裝后,如果被監視的事件發生,系統馬上會調用位于相應鉤子鏈表開始處的鉤子處理函數進行處理,每一個鉤子處理函數在進行相應的處理時都要考慮是否需要把事件傳遞給下一個鉤子處理函數。如果要傳遞,就通過函數CallNestHookEx()來解決。盡管如此,在實際使用時還是強烈推薦無論是否需要事件傳遞而都在過程的最后調用一次CallNextHookEx( )函數,否則將會引起一些無法預知的系統行為或是系統鎖定。該函數將返回位于鉤子鏈表中的下一個鉤子處理過程的地址,至于具體的返回值類型則要視所設置的鉤子類型而定。該函數的原型聲明如下:

LRESULT CallNextHookEx(HHOOK hhk;int nCode;WPARAM wParam;LPARAM lParam);

  其中,參數hhk為由SetWindowsHookEx()函數返回的當前鉤子句柄;參數nCode為傳給鉤子過程的事件代碼;參數wParam和lParam 則為傳給鉤子處理函數的參數值,其具體含義同設置的鉤子類型有關。

  最后,由于安裝鉤子對系統的性能有一定的影響,所以在鉤子使用完畢后應及時將其卸載以釋放其所占資源。釋放鉤子的函數為UnhookWindowsHookEx(),該函數比較簡單只有一個參數用于指定此前由SetWindowsHookEx()函數所返回的鉤子句柄,原型聲明如下:

BOOL UnhookWindowsHookEx(HHOOK hhk);

  三、鼠標鉤子的簡單示例

  最后,為更清楚展示HOOK技術在VC編程中的應用,給出一個有關鼠標鉤子使用的簡單示例。在鉤子設置時采用的是全局鉤子。下面就對鼠標鉤子的安裝、使用以及卸載等過程的實現進行講述:

  由于本例程需要使用全局鉤子,因此首先構造全局鉤子的載體--動態鏈接庫。考慮到 Win32 DLL與Win16 DLL存在的差別,在Win32環境下要在多個進程間共享數據,就必須采取一些措施將待共享的數據提取到一個獨立的數據段,并通過def文件將其屬性設置為讀寫共享:

#pragma data_seg("TestData")
HWND glhPrevTarWnd=NULL; // 窗口句柄
HWND glhHook=NULL; // 鼠標鉤子句柄
HINSTANCE glhInstance=NULL; // DLL實例句柄
#pragma data_seg()
……
SECTIONS // def文件中將數據段TestData設置為讀寫共享
TestData READ WRITE SHARED


  在安裝全局鼠標鉤子時使用函數SetWindowsHookEx(),并設定鼠標鉤子的處理函數為MouseProc(),安裝函數返回的鉤子句柄保存于變量glhHook中:

void StartHook(HWND hWnd)
{
……
glhHook=(HWND)SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);
}


  鼠標鉤子安裝好后,在移動、點擊鼠標時將會發出鼠標消息,這些消息均經過消息處理函數MouseProc()的攔截處理。在此,每當捕獲到系統各線程發出的任何鼠標消息后首先獲取當前鼠標所在位置下的窗口句柄,并進一步通過GetWindowText()函數獲取到窗口標題。在處理函數完成后,通過CallNextHookEx()函數將事件傳遞到鉤子列表中的下一個鉤子處理函數:

LRESULT WINAPI MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *) lParam;
if(nCode>=0)
{
HWND glhTargetWnd=pMouseHook->hwnd;
//取目標窗口句柄
HWND ParentWnd=glhTargetWnd;
while(ParentWnd !=NULL)
{
glhTargetWnd=ParentWnd;
//取應用程序主窗口句柄
ParentWnd=GetParent(glhTargetWnd);
}
if(glhTargetWnd!=glhPrevTarWnd)
{
char szCaption[100];
//取目標窗口標題
GetWindowText(glhTargetWnd,szCaption,100);
……
}
}
//繼續傳遞消息
return CallNextHookEx((HHOOK)glhHook,nCode,wParam,lParam);
}


  最后,調用UnhookWindowsHookEx()函數完成對鉤子的卸載:

void StopHook()
{
……
UnhookWindowsHookEx((HHOOK)glhHook);
}


  現在完成的是鼠標鉤子的動態鏈接庫,經過編譯后需要經應用程序的調用才能實現對當前系統下各線程間鼠標消息的攔截處理。這部分同普通動態鏈接庫的使用沒有任何區別,在將其加載到進程后,首先調用動態鏈接庫的StartHook()函數安裝好鉤子,此時即可對系統下的鼠標消息實施攔截處理,在動態鏈接庫被卸載即終止鼠標鉤子時通過動態鏈接庫中的StopHook()函數卸載鼠標鉤子。

  經上述編程,在安裝好鼠標鉤子后,鼠標在移動到系統任意窗口上時,馬上就會通過對鼠標消息的攔截處理而獲取到當前窗口的標題。實驗證明此鼠標鉤子的安裝、使用和卸載過程是正確的。

  四、小結

  鉤子,尤其是系統鉤子具有相當強大的功能,通過這種技術可以對幾乎所有的Windows系統消息和事件進行攔截處理。這種技術廣泛應用于各種自動監控系統對進程外消息的監控處理。本文只對鉤子的一些基本原理和一般的使用方法做了簡要的探討,感興趣的讀者完全可以在本文所述代碼基礎之上用類似的方法實現對諸如鍵盤鉤子外殼鉤子等其他類型鉤子的安裝與使用。本文所述代碼在Windows 98下由Microsoft Visual C++ 6.0編譯通過。

?

?

Hook機制

??????

一、基本概念:

?

??? 鉤子(Hook),是Windows消息處理機制的一個平臺,應用程序可以在上面設置子程以監視指定窗口的某種消息,而且所監視的窗口可以是其他進程所創建的。當消息到達后,在目標窗口處理函數之前處理它。鉤子機制允許應用程序截獲處理window消息或特定事件

?

??? 鉤子實際上是一個處理消息的程序段,通過系統調用,把它掛入系統。每當特定的消息發出,在沒有到達目的窗口前,鉤子程序就先捕獲該消息,亦即鉤子函數先得到控制權。這時鉤子函數即可以加工處理(改變)該消息,也可以不作處理而繼續傳遞該消息,還可以強制結束消息的傳遞

?

二、運行機制:

?

1、鉤子鏈表和鉤子子程:

?

??? 每一個Hook都有一個與之相關聯的指針列表,稱之為鉤子鏈表,由系統來維護。這個列表的指針指向指定的、應用程序定義的、被Hook子程調用的回調函數,也就是該鉤子的各個處理子程。當與指定的Hook類型關聯的消息發生時,系統就把這個消息傳遞到Hook子程。一些Hook子程可以只監視消息,或者修改消息,或者停止消息的前進,避免這些消息傳遞到下一個Hook子程或者目的窗口。最近安裝的鉤子放在鏈的開始,而最早安裝的鉤子放在最后,也就是后加入的先獲得控制權。

?

?????? Windows 并不要求鉤子子程的卸載順序一定得和安裝順序相反。每當有一個鉤子被卸載,Windows 便釋放其占用的內存,并更新整個Hook鏈表。如果程序安裝了鉤子,但是在尚未卸載鉤子之前就結束了,那么系統會自動為它做卸載鉤子的操作。

?

??? 鉤子子程是一個應用程序定義的回調函數(CALLBACK Function),不能定義成某個類的成員函數(#add static 成員函數則可),只能定義為普通的C函數。用以監視系統或某一特定類型的事件,這些事件可以是與某一特定線程關聯的,也可以是系統中所有線程的事件。

?

?? ?鉤子子程必須按照以下的語法

??? LRESULT CALLBACK HookProc

?????? (

?????? ?????? int nCode,

???? ???? WPARAM wParam,

???? ???? LPARAM lParam

???? );

HookProc是應用程序定義的名字。

?

nCode參數是Hook代碼,Hook子程使用這個參數來確定任務。這個參數的值依賴于Hook類型,每一種Hook都有自己的Hook代碼特征字符集。

wParamlParam參數的值依賴于Hook代碼,但是它們的典型值是包含了關于發送或者接收消息的信息。

?

2、鉤子的安裝與釋放:

?

??? 使用API函數SetWindowsHookEx()把一個應用程序定義的鉤子子程安裝到鉤子鏈表中。SetWindowsHookEx函數總是在Hook鏈的開頭安裝Hook子程。當指定類型的Hook監視的事件發生時,系統就調用與這個Hook關聯的Hook鏈的開頭的Hook子程。每一個Hook鏈中的Hook子程都決定是否把這個事件傳遞到下一個Hook子程。Hook子程傳遞事件到下一個Hook子程需要調用CallNextHookEx函數。

???

HHOOK SetWindowsHookEx(

     int idHook,????? // 鉤子的類型,即它處理的消息類型

     HOOKPROC lpfn,?? // 鉤子子程的地址指針。如果dwThreadId參數為0

???????????????????? ?? // 或是一個由別的進程創建的線程的標識,

???????????????????? ?? // lpfn必須指向DLL中的鉤子子程。

???????????????????? ?? // 除此以外,lpfn可以指向當前進程的一段鉤子子程代碼。

???????????????????? ?? // 鉤子函數的入口地址,當鉤子鉤到任何消息后便調用這個函數。

     HINSTANCE hMod,?// 應用程序實例的句柄。標識包含lpfn所指的子程的DLL

???????????????????? ?? // 如果dwThreadId 標識當前進程創建的一個線程,

???????????????????? ?? // 而且子程代碼位于當前進程,hMod必須為NULL

???????????????????? ?? // 可以很簡單的設定其為本應用程序的實例句柄。

     DWORD dwThreadId // 與安裝的鉤子子程相關聯的線程的標識符。

???????????????????? ?? // 如果為0,鉤子子程與所有的線程關聯,即為全局鉤子。

     ??????????? );

  函數成功則返回鉤子子程的句柄,失敗返回NULL

?

  以上所說的鉤子子程與線程相關聯是指在一鉤子鏈表中發給該線程的消息同時發送給鉤子子程,且被鉤子子程先處理。

?

??? 在鉤子子程中調用得到控制權的鉤子函數在完成對消息的處理后,如果想要該消息繼續傳遞,那么它必須調用另外一個SDK中的API函數CallNextHookEx來傳遞它,以執行鉤子鏈表所指的下一個鉤子子程。這個函數成功時返回鉤子鏈中下一個鉤子過程的返回值,返回值的類型依賴于鉤子的類型。這個函數的原型如下:

?

LRESULT CallNextHookEx

???????????????????? (

??????????????????????????? HHOOK hhk;

??????????????????????????? int nCode;

??????????????????????????? WPARAM wParam;

??????????????????????????? LPARAM lParam;

???????????????????? ?);

????????????????????

hhk為當前鉤子的句柄,由SetWindowsHookEx()函數返回。

NCode為傳給鉤子過程的事件代碼。

wParamlParam 分別是傳給鉤子子程的wParam值,其具體含義與鉤子類型有關。

?????????????

??? 鉤子函數也可以通過直接返回TRUE來丟棄該消息,并阻止該消息的傳遞。否則的話,其他安裝了鉤子的應用程序將不會接收到鉤子的通知而且還有可能產生不正確的結果。

?

??? 鉤子在使用完之后需要用UnHookWindowsHookEx()卸載,否則會造成麻煩。釋放鉤子比較簡單,UnHookWindowsHookEx()只有一個參數。函數原型如下:

?

UnHookWindowsHookEx

????????????? (

????????????? HHOOK hhk;

????????????? );

函數成功返回TRUE,否則返回FALSE

?

3、一些運行機制:

?

??? Win16環境中,DLL的全局數據對每個載入它的進程來說都是相同的;而在Win32環境中,情況卻發生了變化,DLL函數中的代碼所創建的任何對象(包括變量)都歸調用它的線程或進程所有。當進程在載入DLL時,操作系統自動把DLL地址映射到該進程的私有空間,也就是進程的虛擬地址空間,而且也復制該DLL的全局數據的一份拷貝到該進程空間。也就是說每個進程所擁有的相同的DLL的全局數據,它們的名稱相同,但其值卻并不一定是相同的,而且是互不干涉的。

??????

?????? 因此,在Win32環境下要想在多個進程中共享數據,就必須進行必要的設置。在訪問同一個Dll的各進程之間共享存儲器是通過存儲器映射文件技術實現的。也可以把這些需要共享的數據分離出來,放置在一個獨立的數據段里,并把該段的屬性設置為共享。必須給這些變量賦初值,否則編譯器會把沒有賦初始值的變量放在一個叫未被初始化的數據段中。

?

?????? #pragma data_seg預處理指令用于設置共享數據段。例如:

#pragma data_seg("SharedDataName")

HHOOK hHook=NULL;

#pragma data_seg()

?????? #pragma data_seg("SharedDataName")#pragma data_seg()之間的所有變量 將被訪問該Dll的所有進程看到和共享。

?

??? 當進程隱式或顯式調用一個動態庫里的函數時,系統都要把這個動態庫映射到這個進程的虛擬地址空間里(以下簡稱"地址空間")。這使得DLL成為進程的一部分,以這個進程的身份執行,使用這個進程的堆棧。

?

4、系統鉤子與線程鉤子:

?

??? SetWindowsHookEx()函數的最后一個參數決定了此鉤子是系統鉤子還是線程鉤子。

???

?? ?線程勾子用于監視指定線程的事件消息。線程勾子一般在當前線程或者當前線程派生的線程內。

???

??? 系統勾子監視系統中的所有線程的事件消息。因為系統勾子會影響系統中所有的應用程序,所以勾子函數必須放在獨立的動態鏈接庫(DLL) 中。系統自動將包含"鉤子回調函數"DLL映射到受鉤子函數影響的所有進程的地址空間中,即將這個DLL注入了那些進程。

?

幾點說明:

?1)如果對于同一事件(如鼠標消息)既安裝了線程勾子又安裝了系統勾子,那么系統會自動先調用線程勾子,然后調用系統勾子。

?

?2)對同一事件消息可安裝多個勾子處理過程,這些勾子處理過程形成了勾子鏈。當前勾子處理結束后應把勾子信息傳遞給下一個勾子函數。

?

?3)勾子特別是系統勾子會消耗消息處理時間,降低系統性能。只有在必要的時候才安裝勾子,在使用完畢后要及時卸載。

?

三、鉤子類型

?

??? 每一種類型的Hook可以使應用程序能夠監視不同類型的系統消息處理機制。下面描述所有可以利用的Hook類型。

?

1WH_CALLWNDPROCWH_CALLWNDPROCRET Hooks

?

??? WH_CALLWNDPROCWH_CALLWNDPROCRET Hooks使你可以監視發送到窗口過程的消息。系統在消息發送到接收窗口過程之前調用WH_CALLWNDPROC Hook子程,并且在窗口過程處理完消息之后調用WH_CALLWNDPROCRET Hook子程。

?

??? WH_CALLWNDPROCRET Hook傳遞指針到CWPRETSTRUCT結構,再傳遞到Hook子程。CWPRETSTRUCT結構包含了來自處理消息的窗口過程的返回值,同樣也包括了與這個消息關聯的消息參數。

?

2WH_CBT Hook

?

??? 在以下事件之前,系統都會調用WH_CBT Hook子程,這些事件包括:

??? 1. 激活,建立,銷毀,最小化,最大化,移動,改變尺寸等窗口事件;

??? 2. 完成系統指令;

??? 3. 來自系統消息隊列中的移動鼠標,鍵盤事件;

??? 4. 設置輸入焦點事件;

??? 5. 同步系統消息隊列事件。

???

??? Hook子程的返回值確定系統是否允許或者防止這些操作中的一個。

?

3WH_DEBUG Hook

?

??? 在系統調用系統中與其他Hook關聯的Hook子程之前,系統會調用WH_DEBUG Hook子程。你可以使用這個Hook來決定是否允許系統調用與其他Hook關聯的Hook子程。

?

4WH_FOREGROUNDIDLE Hook

?

??? 當應用程序的前臺線程處于空閑狀態時,可以使用WH_FOREGROUNDIDLE Hook執行低優先級的任務。當應用程序的前臺線程大概要變成空閑狀態時,系統就會調用WH_FOREGROUNDIDLE Hook子程。

?

5WH_GETMESSAGE Hook

?

??? 應用程序使用WH_GETMESSAGE Hook來監視從GetMessage or PeekMessage函數返回的消息。你可以使用WH_GETMESSAGE Hook去監視鼠標和鍵盤輸入,以及其他發送到消息隊列中的消息。

?

6WH_JOURNALPLAYBACK Hook

?

??? WH_JOURNALPLAYBACK Hook使應用程序可以插入消息到系統消息隊列。可以使用這個Hook回放通過使用WH_JOURNALRECORD Hook記錄下來的連續的鼠標和鍵盤事件。只要WH_JOURNALPLAYBACK Hook已經安裝,正常的鼠標和鍵盤事件就是無效的。WH_JOURNALPLAYBACK Hook是全局Hook,它不能象線程特定Hook一樣使用。WH_JOURNALPLAYBACK Hook返回超時值,這個值告訴系統在處理來自回放Hook當前消息之前需要等待多長時間(毫秒)。這就使Hook可以控制實時事件的回放。WH_JOURNALPLAYBACKsystem-wide local hooks,它們不會被注射到任何行程位址空間。

?

7WH_JOURNALRECORD Hook

?

??? WH_JOURNALRECORD Hook用來監視和記錄輸入事件。典型的,可以使用這個Hook記錄連續的鼠標和鍵盤事件,然后通過使用WH_JOURNALPLAYBACK Hook來回放。WH_JOURNALRECORD Hook是全局Hook,它不能象線程特定Hook一樣使用。WH_JOURNALRECORDsystem-wide local hooks,它們不會被注射到任何行程位址空間。

?

8WH_KEYBOARD Hook

?

??? 在應用程序中,WH_KEYBOARD Hook用來監視WM_KEYDOWN and WM_KEYUP消息,這些消息通過GetMessage or PeekMessage function返回。可以使用這個Hook來監視輸入到消息隊列中的鍵盤消息。

?

9WH_KEYBOARD_LL Hook

?

??? WH_KEYBOARD_LL Hook監視輸入到線程消息隊列中的鍵盤消息。

?

10WH_MOUSE Hook

?

??? WH_MOUSE Hook監視從GetMessage 或者 PeekMessage 函數返回的鼠標消息。使用這個Hook監視輸入到消息隊列中的鼠標消息。

?

11WH_MOUSE_LL Hook

?

??? WH_MOUSE_LL Hook監視輸入到線程消息隊列中的鼠標消息。

?

12WH_MSGFILTER WH_SYSMSGFILTER Hooks

?

??? WH_MSGFILTER WH_SYSMSGFILTER Hooks使我們可以監視菜單,滾動條,消息框,對話框消息并且發現用戶使用ALT+TAB or ALT+ESC 組合鍵切換窗口。WH_MSGFILTER Hook只能監視傳遞到菜單,滾動條,消息框的消息,以及傳遞到通過安裝了Hook子程的應用程序建立的對話框的消息。WH_SYSMSGFILTER Hook監視所有應用程序消息。

???

??? WH_MSGFILTER WH_SYSMSGFILTER Hooks使我們可以在模式循環期間過濾消息,這等價于在主消息循環中過濾消息。

???

通過調用CallMsgFilter function可以直接的調用WH_MSGFILTER Hook。通過使用這個函數,應用程序能夠在模式循環期間使用相同的代碼去過濾消息,如同在主消息循環里一樣。

?

13WH_SHELL Hook

?

?? ?外殼應用程序可以使用WH_SHELL Hook去接收重要的通知。當外殼應用程序是激活的并且當頂層窗口建立或者銷毀時,系統調用WH_SHELL Hook子程。

????? WH_SHELL 共有5鐘情況:

1. 只要有個top-levelunowned 窗口被產生、起作用、或是被摧毀;

2. Taskbar需要重畫某個按鈕;

3. 當系統需要顯示關于Taskbar的一個程序的最小化形式;

4. 當目前的鍵盤布局狀態改變;

5. 當使用者按Ctrl+Esc去執行Task Manager(或相同級別的程序)。

?

??? 按照慣例,外殼應用程序都不接收WH_SHELL消息。所以,在應用程序能夠接收WH_SHELL消息之前,應用程序必須調用SystemParametersInfo function注冊它自己。

?

?

?

關于鉤子HOOK函數的詳細說明

?

鉤子HOOK函數是Windows消息處理機制的一部分,通過設置“鉤子”,應用程序可以在系統級對所有消息、事件進行過濾,訪問在正常情況下無法訪問的消息。當然,這么做也是需要付出一定的代價的。由于多了這么一道處理過程,系統性能會受到一定的影響,所以大家在必要的時候才使用“鉤子”,并在使用完畢及時將其刪除。

  首先讓我們看看HOOK函數是怎么安裝、調用和刪除的。應用程序通常是調用SetWindowsHookEx()函數來進行安裝的,其函數的原型如下:

?

SetWindowsHookEx(

?

Int idHook;

?

HOOKPROC lpfn;

?

HINSTANCE hMod;

?

DWORD dwThreadId;

?

);

?

參數說明:

?

idHook 是”鉤子”的類型,”鉤子”的類型一共有13種,具體如下表:

?

“鉤子”類型

解釋

?

WH_CALLWNDPROC

系統將消息發送到指定窗口之前的“鉤子”

?

WH_CALLWNDPROCRET

消息已經在窗口中處理的“鉤子”

?

WH_CBT

基于計算機培訓的“鉤子”

?

WH_DEBUG

差錯“鉤子”

?

WH_FOREGROUNDIDLE

前臺空閑窗口“鉤子”

?

WH_GETMESSAGE

接收消息投遞的“鉤子”

?

WH_JOURNALPLAYBACK

回放以前通過WH_JOURNALRECORD“鉤子”記錄的輸入消息

?

WH_JOURNALRECORD

輸入消息記錄“鉤子”

?

WH_KEYBOARD

鍵盤消息“鉤子”

?

WH_MOUSE

鼠標消息“鉤子”

?

WH_MSGFILTER

對話框、消息框、菜單或滾動條輸入消息“鉤子”

?

WH_SHELL

外殼“鉤子”

?

WH_SYSMSGFILTER

系統消息“鉤子”

?

?

lpfn 指向“鉤子”過程的指針。

?

hMod “鉤子”過程所在模塊的句柄。

?

dwThreadId “鉤子”相關線程的標識。

?

  通常我們都是把”鉤子”做成動態鏈接庫,這樣的好處是可以是系統內的每個進程訪問。但是也可以在系統中直接調用,我的建議還是用動態庫。如果用動態庫的話,那么SetWindowsHookEx()中的第三個參數就是該動態鏈接庫模塊的句柄;對于一個只供單個進程訪問的”鉤子”,可以將其”鉤子”過程放在安裝”鉤子”的同一個線程內,此時SetWindowsHookEx()中的第三個參數為該線程的hInstance。安裝”鉤子”有兩種方法:1.你可以把他做成動態連接庫文件,和程序一起編譯。2.你可以在程序的任何地方直接調用。第2種的方法太麻煩,我不建議用,在這里我就不詳細介紹啦。相比之下第1種比較簡單。其”鉤子”的過程都在動態鏈接庫內完成。SetWindowsHookEx()函數是一個安裝函數,如故一個由某種類型的”鉤子”監視的事件發生,系統就會調用相應類型的”鉤子”鏈開始處的”鉤子”過程,”鉤子”鏈的每個”鉤子”過程都要考慮是否把事件傳遞給下一個”鉤子”過程。如果要傳遞的話,就要調用CallNestHookEx()函數。這個函數成功時返回”鉤子”鏈中下一個”鉤子”過程的返回值,返回值的類型依賴于”鉤子”的類型。這個函數的原型如下:

?

LRESULT CallNextHookEx(

?

HHOOK hhk;

?

int nCode;

?

WPARAM wParam;

?

LPARAM lParam;

?

);

?

  其中hhk為當前”鉤子”的句柄,由SetWindowsHookEx()函數返回。NCode為傳給”鉤子”過程的事件代碼。wParamlParam 分別是傳給”鉤子”過程的wParam值,其具體含義與”鉤子”類型有關。

?

釋放”鉤子”

?

  釋放”鉤子”比較簡單,他只有一個參數。當不在需要”鉤子”時,應及時將其釋放。他是調用UnhookWindowsHookEx()函數來實現的,函數原型如下:

?

UnhookWindowsHookEx(

?

HHOOK hhk;

?

);

?

函數成功返回TRUE,否則返回FALSE

?

如果我這樣講您還是不明白的話,請看下面給出的一些典型“鉤子”代碼和說明。

?

LRESULT WINAPI CallWndProc(int nCode,WPARAM wParam,LPARAM lParam)

?

{

?

if(nCode<0)

?

return CallNextHookEx(NULL,nCode,wParam,lParam);

?

switch(nCode)

?

{

?

case HC_ACTION:

?

//”鉤子”程序要處理什么的代碼

?

break;

?

default:

?

break;

?

}

?

return CallNextHookEx(NULL,nCode,wParam,lParam);

?

}

?

  這是WH_CALLWNDPROC”鉤子”的代碼,此”鉤子”允許程序監視由函數SendMessage發送給窗口過程的消息。系統將消息發送到目的窗口之前調用WH_CALLWNDPROC “鉤子”過程。

?

LRESULT WINAPI CallwndProc(int nCode,WPARAM,wParam,LPARAM lParam)

?

{

?

if(nCode<0) return callNextHookEx(NULL,nCode,wParam,lParam);

?

switch(nCode)

?

{

?

case HC_ACTION:

?

switch(wParam)

?

{

?

Case PM_REMOVE:

?

//某個應用程序調用了GetMessage函數或者是帶PM_REMOVE參數的//PeekMessage函數,從消息隊列中移去一個消息。

?

Break;

?

Case PM_NOREMOVE:

?

//某個應用程序以PM_NOREMOVE為參數調用PeekMessage函數

?

break;

?

default:

?

break;

?

}

?

break;

?

default:

?

break;

?

}

?

return CallNextHookEx(NULL,nCode,wParam,lParam);

?

}

?

  這是調用WH_GETMESSAGE的函數,此函數允許應用程序監視函數GetMessage PeekMessage返回的消息。應用程序可以用鉤子WH_GETMESSAGE來監視鼠標和鍵盤的輸入以及其他系統發送到消息隊列中的消息。

?

LRESULT CALLBACK CBTProc(int nCode,WPARAM wParam,LPARAM lParam)

?

{

?

If(nCode<0) Return callNextHookEx(NULL,nCode,wParam,lParam);

?

Switch(nCode)

?

{

?

case HCBT_ACTIVATE:

?

//系統將激活一個窗口

?

break;

?

case HCBT_CLICKSKIPPED:

?

//系統從系統消息隊列中移去一個鼠標消息

?

break;

?

case HCBT_CREATEWND:

?

//系統將創建一個窗口

?

break;

?

case HCBT_DESTROYWND:

?

//系統將關閉一個窗口

?

break;

?

case HCBT_KEYSKIPPED:

?

//系統從系統消息隊列中移去一個鍵盤消息

?

break;

?

case HCBT_MINMAX:

?

//系統將最大化或最小化一個窗口

?

break;

?

case HCBT_MOVESIZE:

?

//系統將移動一個窗口或改變一個窗口的大小

?

break;

?

case HCBT_QS:

?

//系統在系統消息隊列中檢索到WM_QUEUESYNC消息

?

break;

?

case HCBT_SETFOCUS:

?

//系統設置鍵盤輸入窗口

?

break;

?

case HCBT_SYSCOMMAND:

?

//將要執行一個系統命令

?

break;

?

default:

?

//可以添加其他代碼

?

break;

?

}

?

return CallNextHookEx(NULL,nCode,wParam,lParam);

?

}

?

  每種”鉤子”類型都有其對應的函數,這些函數的參數都是一樣的,有興趣的朋友可以在MSDN中找的他們的詳細說明。

?

下面我給出一個完整的”鉤子”安裝和刪除的過程的代碼。

?

#include "stdafx.h"

?

#include "hook.h"

?

HINSTANCE hInstance;

?

HHOOK hhkKeyboard;

?

BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call, LPVOID lpReserved)

?

{

?

switch (ul_reason_for_call)

?

{

?

case DLL_PROCESS_ATTACH:

?

case DLL_THREAD_ATTACH:

?

case DLL_THREAD_DETACH:

?

case DLL_PROCESS_DETACH:

?

break;

?

}

?

hInstance=(HINSTANCE)hModule;

?

return TRUE;

?

}

?

LRESULT KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

?

{

?

MessageBeep(-1);

?

return CallNextHookEx(hhkKeyboard,nCode,wParam,lParam);

?

}

?

HOOK_API BOOL EnableKeyboardCapture()

?

{

?

if(!(hhkKeyboard=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hInstance,0)))

?

return FALSE;

?

return TRUE;

?

}

?

HOOK_API BOOL DisableKeyboardCapture()

?

{

?

return UnhookWindowsHookEx(hhkKeyboard);

?

}

?

注意:這是一個動態鏈接庫文件。

?

在程序中要想調用“鉤子”的時候,有EnableKeyboardCapture()函數就可以啦,但你按鍵的時候就回發出聲音。

?

?

?

Win32Hook一些要點

?

?

如果你看msdn中的setwindowshookex函數說明,你會發現,ms告訴你如果你想

hook全局數據,你必須把hook代碼寫在dll,如果你的hook代碼在.exe,

則你只能hook本進程的數據.

?

你想過這是為什么嗎?

?

win32拋棄了win16的全局內存的概念,每個進程有自己獨立的內存空間,

并且不受其他進程影響.這樣一來所有代碼都只能訪問局部資源,但很顯然有些

應用必須是全局的,比如你的hook,所以ms必須提供一種折衷的安全的方法.

windows中的dll正好可以解決這個問題.

?

dll是一種代碼摸塊,它可以被映射進不同的進程空間,具體方法就不多談了,如果

你有興趣我們以后討論.

?

基于以上原因,ms要求我們把全局hook放進dll,以便由win32映射進不同的進程

空間,每個進程空間中的hook代碼只負責處理該進程中的數據.所有的局部

之和就是全局,這樣既維護了進程空間的獨立性,又可以處理全局數據.

?

你的問題是想hook一個進程的數據,但又不是本進程,所以你必須讓win32幫你把

hook代碼放到其他進程空間,又要有所選擇.

win32在映射hook代碼到其他進程空間中的方法很簡單,就是在另一個進程中調用

Loadlibrary

?

只有Loadlibrary成功以后才能hook到該進程的數據.

如果某個進程執行loadlibrary失敗,那么我們將無法hook到該進程的數據.

?

loadlibrary失敗除了系統原因外,還有個重要因素就是dllmain沒有返回TRUE!

?

根據以上理論,我們只要在 非指定程序 裝載hook dll時讓dllmain返回false,即可達到

你的目的了.

?

所以你需要在hook dll中添加下面的代碼"

?

?

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)

{

switch(dwReason) {

case DLL_PROCESS_ATTACH:

??? ............

?? if(不是指定程序)

???? return FALSE

break;

.................

........

}

??? return TRUE;

}

?

?

?

這里有個例子:

ftp://pub:pub@211.157.101.157/Hook和hotKey.rar

ftp://pub:pub@211.157.101.157/Hook和hotKey源碼.rar

?

利用鍵盤鉤子開發按鍵發音程序

作者:GDGF

?

一、前言

一日,看見我媽正在用電腦練習打字,頻頻低頭看鍵盤,我想:要是鍵盤能發音的話,不就可以方便她養成"盲打"的好習慣嗎?光想不做可不行,開始行動(您可千萬別急著去拿工具箱啊^_^)...

按鍵能發音,其關鍵就是讓程序能夠知道當前鍵盤上是哪個鍵被按下,并播放相應的聲音,自己的程序當然不在話下,那么其它程序當前按下哪個鍵如何得知呢?利用鍵盤鉤子便可以很好地解決。

?

下載本文的全部源代碼 大小:552K

?

二、掛鉤(HOOK)的基本原理

WINDOWS調用掛接的回調函數時首先會調用位于函數鏈首的函數,我們只要將自己的回調函數置于鏈首,該回調函數就會首先被調用。那么如何將我們自己的回調函數置于函數鏈的鏈首呢?函數SetWindowsHookEx()實現的就是該功能。我們首先來看一下SetWindowsHookEx函數的原型:

?

?

HHOOK SetWindowsHookEx(

?int idHook,??????

?HOOKPROC lpfn,????

?HINSTANCE hMod,???

?DWORD dwThreadId?

);

第一個參數:指定鉤子的類型,有WH_MOUSEWH_KEYBOARD等十多種(具體參見MSDN)

第二個參數:標識鉤子函數的入口地址

第三個參數:鉤子函數所在模塊的句柄;

第四個參數:鉤子相關函數的ID用以指定想讓鉤子去鉤哪個線程,為0時則攔截整個系統的消息。

?

另外需要注意的是為了捕獲所有事件,掛鉤函數應該放在動態鏈接庫DLL中。

?

三、具體實現

理論的話就不多說了,運行VC++6.0,新建一個MFC AppWizard(dll)工程,命名為Hook,使用默認的創建DLL類型的選項,也就是使用共享MFC DLL,點擊完成后開始編寫代碼:

?

(1)Hook.h中定義全局函數

BOOL installhook(); //鉤子安裝函數

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);//掛鉤函數

?

(2)Hook.cpp文件的#endif下添加定義全局變量Hook的代碼:

static HHOOK hkb=NULL;

HINSTANCE hins; //鉤子函數所在模塊的句柄

(3)添加核心代碼

BOOL installhook()

{

??? hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);

??? return TRUE;

}

第一個參數指定鉤子的類型,因為我們只用到鍵盤操作所以設定為WH_KEYBOARD;第二個參數將鉤子函數的入口地址指定為KeyboardProc,當鉤子鉤到任何消息后便調用這個函數,即當不管系統的哪個窗口有鍵盤輸入馬上會引起KeyboardProc的動作;第三個參數是鉤子函數所在模塊的句柄;最后一個參數是鉤子相關函數的ID用以指定想讓鉤子去鉤哪個線程,為0時則攔截整個系統的消息;

現在,就開始定義當鍵盤上的鍵按下時程序要做什么了~

KeyboardProc動作:

?

LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

{

??? if(((DWORD)lParam&0x40000000) && (HC_ACTION==nCode))

??? {

?????? switch(wParam) //鍵盤按鍵標識

??????? {

??????? case ''1'':sndPlaySound("1.wav",SND_ASYNC);break; //當數字鍵1被按下

???????? case ''2'':sndPlaySound("2.wav",SND_ASYNC);break;

??????? case ''3'':sndPlaySound("3.wav",SND_ASYNC);break;

??????? case ''4'':sndPlaySound("4.wav",SND_ASYNC);break;

??????? ....

??????? case ''A'':sndPlaySound("a.wav",SND_ASYNC);break; //當字母鍵A被按下

???????? case ''B'':sndPlaySound("b.wav",SND_ASYNC);break;

??????? case ''C'':sndPlaySound("c.wav",SND_ASYNC);break;

??????? case ''D'':sndPlaySound("d.wav",SND_ASYNC);break;

??????? ....

??????? }

???? }

???? LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam );

???? return RetVal;

}

上面的代碼中我們用播放聲音做為按鍵被按下后的動作,API函數sndPlaySound的第一個參數定義的聲音文件的絕對路徑(比如要播放C盤下的a.wav,就定義成"C:\\a.wav");第二參數定義播放模式,SND_ASYNC模式可以及時地釋放正在播放的聲音文件,立刻停止當前聲音的播放轉去播放新的聲音,這樣在我們連續擊鍵時就不會有阻塞感了.為了執行sndPlaySound函數,必須在Hook.cpp的文件頭加上:?#include "mmsystem.h"

并且點擊VC++菜單上的“工程”-“設置”進入Link屬性頁,在L對象/庫模塊下輸入:winmm.lib后確定即可.

?

(4)添加輸出標識

Hook.def的末尾添加

?

?

installhook

KeyboardProc

短短的四步,鍵盤鉤子的制作算是完成了,編譯生成后的DLL文件就可以自由的用別的程序來調用了.

在程序中如何調用DLL呢?那就簡單了.再用VC++6.0新建一個MFC AppWizard(exe)工程,命名為KeySound,點擊"確定"后選擇程序類型為對話框,直接點擊確定即可.

KeySoundDlg.cpp文件中的OnInitDialog()初始化函數的CDialog::OnInitDialog();下面添加:

?

//阻止程序反復駐留內存,也為了防止有兩個程序同時讀取DLL而發生錯誤.

?

?

CreateMutex(NULL, FALSE, "KeySound");

if(GetLastError()==ERROR_ALREADY_EXISTS)

?? OnOK();

?

//讀取DLL

static HINSTANCE hinstDLL;

typedef BOOL (CALLBACK *inshook)();

inshook instkbhook;

if(hinstDLL=LoadLibrary((LPCTSTR)"Hook.dll"))

{

??? instkbhook=(inshook)GetProcAddress(hinstDLL,"installhook");?

??? instkbhook();

}

else

{

??? MessageBox("當前目錄找不到Hook.dll文件,程序初始化失敗");

??? OnOK();

}

將編譯生成后的KeySound.exeHook.dll放在同一目錄下,定義好聲音文件,運行KeySound.exe后打開記事本或寫字板,體驗一下系統為您即時快速地朗讀您按下的每一個鍵的快感吧^-^

?

有一點必須說明,標準鍵盤有101個鍵,您想讓多少鍵發聲音,就必須在上面的KeyboardProc動作里定義多少個鍵,常用的10個數字鍵和26個英文字母不會給您帶來太大的困難,只要相應的''A''對應A,''1''對應1鍵就可以,但如果您希望能讓更多的鍵都有各種特色音樂的話,很可能會遇到一些鍵盤編碼上的麻煩,比如ESC鍵就不能簡單的用''ESC''來搞定了,得用VK_ESCAPE,又比如Alt鍵得用VK_MENU來定義,沒有個鍵盤編碼表的話會令人相當頭疼,這里我介紹一種讓程序來告訴您鍵盤按鍵名稱的方法:

為一個工程添加PreTranslateMessage映射,添加如下代碼:

?

?

char KeyName[50];

ZeroMemory(KeyName,50);

if(pMsg -> message == WM_KEYDOWN)

{

?? GetKeyNameText(pMsg->lParam,KeyName,50);

?? MessageBox(KeyName);

}

那么當程序窗口顯示在面前時按下某個鍵,就會彈出一個消息顯示該鍵的名稱,然后用''''包起來就可以了,比如逗號句號,就是'',''''.'',簡單吧:)

到此就全部完成了按鍵發音程序的編寫,通過改變聲音文件的名稱而不用改動程序本身就可以達到更換按鍵聲音的目的了,只是有個遺憾,聲音文件在硬盤中的位置不能變更,從C盤換移動D盤程序就不能播放了,怎么樣才能靈活的讀取聲音文件呢?可以用API函數GetModuleFileName來得到程序所在的目錄,具體實現方法如下:

(1)Hook.hpublic:下面添加:

?

?

BOOL InitInstance(); //初始化函數

(2)Hook.cpp#endif下添加定義全局變量的代碼:

?

?

char szBuf[256];

char *p;

CString msg;

(3)Hook.cpp中適當位置添加:

?

?

BOOL CHookApp::InitInstance ()

{

?? hins=AfxGetInstanceHandle();

?? GetModuleFileName(AfxGetInstanceHandle( ),szBuf,sizeof(szBuf));

?? p = szBuf;

?? while(strchr(p,''\\''))

?? {

??????? p = strchr(p,''\\'');

??????? p++;

?? }

?? *p = ''\0'';

?? msg=szBuf;

?? return TRUE;

}

(4)新建一個文件夾并命名為Sound;

?

(5)改變聲音文件物理位置定義方式

case ''1'':sndPlaySound(msg+"sound\\1.wav",SND_ASYNC);break;

msg是得到程序當前所在目錄,加上后面的代碼就是指播放當前目錄下的Sound目錄里的1.wav文件,這樣就將聲音文件的絕對路徑改成了靈活的相對路徑.您只要把KeySound.exe,Hook.dllSound文件夾放在同一個文件夾下,以后只要搬動整個文件夾就能實現聲音文件的任意移動了。

?

調試時需要注意:將Hook.dllSound目錄放在KeySound.exe的執行目錄下。假如編譯鏈接的時候出現unresolved external symbol __imp__sndPlaySoundA@8 這樣的信息,請在Project Settings中加入Winmm.lib

?

//

《魔高一丈2.0》開發實例

作者:濟南 宋悅

?

下載本文程序與代碼

http://www.vckbase.com/code/downcode.asp?id=1578

一、開發背景:

?

我想大家都有過忙手忙腳最小化窗口(或關閉窗口)的經歷吧!原因很簡單——不想讓突如其來的老板、老媽、老婆看到我們電腦屏幕上正在顯示的游戲、日記、MM:-) 等屬于個人隱私的東東。 如果能做一個程序在后臺運行,當我們發出一個特殊的輸入事件(我選擇了鼠標左、右鍵同時按下)時,該程序就迅速隱藏正在顯示的窗口,免去人工瞄準并按下每個窗口右上方的那個小得可憐的的最小化按扭之苦了。當危險解除再利用這個特殊事件使隱藏的窗口恢復。這對于像我這樣小腦不太發達、心理素質又不過硬而又經常在老板的眼皮底下“懸崖騎馬”的同志們來說是絕對有實戰意義的。于是我做了這個“魔高一丈”以實現上述功能!

?

?

二、程序原理:

?

首先,我們得能截獲鼠標左、右鍵同時按下去這個事件——這并不難——設一個標志變量當鼠標發出WM_LBUTTONDOWN并且又有WM_RBUTTONDOWN消息發出時把它置“1”罷了。而我要說明的是,這個“同時按下”只是一種宏觀上的概念,鼠標是不會同時發出兩個消息的。其次就是解決不管鼠標位于任何窗口之上都能在程序里截獲(或者稱為監聽更準確)到鼠標發出的消息并加以過濾的問題了,這是很關鍵的。我用了鉤子船長的那只鉤子(Hook),而且是全局的鼠標鉤子,它給了我們跟操作系統溝通的一個機會。許多比較有神秘感的程序(比如金山詞霸的鼠標取詞)都是用它實現的,稍后我將詳細解釋。最后就是剩下能得到可見的窗口的句柄(HANDLE)并根據其句柄顯示、隱藏窗口的問題了,這也沒什么難的有現成的API函數——EnumWindowsShowWindow。你可以先運行一下我的程序(那個大五星,需要把它跟那個Mousehook.dll文件放在一個文件夾下)。當鼠標左右鍵一起按下時所有的窗口都隱藏了;再一次同時按下左右鍵又可恢復隱藏窗口;單擊任務欄右下角(托盤)的圖標可隱藏或顯示本程序窗口。

?

三、開發步驟:

?

0步、選用VC 6.0集成開發環境。

1步、由于建立全局鉤子必須把鉤子函數放在DLL里面,所以我們選擇MFC AppWizard(DLL)創建一個新的項目,命名為“Mousehook”,再選擇選擇MFC Extension DLL類型(為了方便嘛!)。為什么必須把全局鉤子函數放在DLL里呢?這是因為系統會動態地調用你所添加的全局鼠標鉤子,所有窗口消息數都會由于你添加了鼠標鉤子而引起系統處理(何為處理?調用鉤子函數也。)這必然需要操作系統能夠從一個東東里動態地加入這段處理程序,而這個東東非DLL莫屬。

2步、在項目中加入Mousehook.h文件用以構造一個鉤子類——CMousehook,具體如下:

?

class AFX_EXT_CLASS CMousehook:public CObject

{

public:

?CMousehook();

?~CMousehook();

?BOOL starthook();//封裝SetWindowsHookEx( int idHook, HOOK_PROC lpfn, HINSTANCE hMod,DWORD dwThreadID)用來安裝鉤子

?BOOL stophook(); //封裝UnhookWindowsHookEx( HHOOK hhk )用來卸載鉤子

?VOID SetCheck1(UINT i);//處理對話框的選擇鉤選框1

?VOID SetCheck2(UINT i);//處理對話框的選擇鉤選框2

?VOID SetCheck3(UINT i);//處理對話框的選擇鉤選框3

?static BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);//系統回調的鉤子函數

?VOID UseForExit();//退出程序時恢復所有隱藏窗口

};

這里我想特別地提一下EnumWindowsProc函數前的CALLBACKstatic,對于CALLBACK我想給大家一個特別江湖的解釋其就是:凡是由你設計而卻由Windows系統調用的函數,統稱callback函數。這些函數都有一定的類型,以配合Windows的調用操作。——引用臺灣侯師傅的話。他還說,某些Windows API函數會要求以callback函數(的函數地址)作為其參數之一。我們這里用到的又比如 SetWindowsHookEx( int idHook, HOOK_PROC lpfn, HINSTANCE hMod,DWORD dwThreadID)的第二個參數。這種API通常會在進行某種行為之后或滿足某種狀態的情況下調用其參數中的callback函數。又由于系統在調用callback函數的時候并不會借助任何對象去調用該callback函數,所以在用類來封裝callback函數時,需要用static來使callback函數能夠獨立于對象而又屬于類的成員函數。明白了不?(啊?地球人都知道呀!太傷自尊了!)

?

3步、在項目中加入Mousehook.cpp文件在CMousehook里封裝其中加入必要的共享數據以及SetWindowsHookExUnhookWindowsHookEx等函數——這些API函數具體的參數的類型跟作用解釋在程序代碼的注釋里有(網上也到處都有,我也是從網上摳下來的。一個聲音高叫著——當然MSDN里也有。),而把它們寫在文章里就不免有騙取稿費之嫌了。我只是想解釋一下為什么需要使用一個共享的數據段,如下: #pragma data_seg("mydata")????????????? //編譯器識別的指令用以在虛擬內存中開辟一個數據段存放該指令下面的數據

?

HINSTANCE glhInstance=NULL;???????????? //DLL實例(或者說模塊)的句柄。

HHOOK glhHook=NULL;???????????????????? //鼠標鉤子的句柄。

HWND?GlobalWndHandle[100]={NULL,.....};//用來存放被隱藏的窗口的句柄,以數組的形式保存。

??????????????????????????????????????? //該數組必須初始化,原因見下文。我以“......”省略。

UINT?Global_i=0;?????????????????????? //用以在循環中序列化窗口數組的變量。

BOOL?Condition1=0;???????????????????? //用以記錄左鍵按下或釋放的標志變量。

BOOL?Condition2=0;???????????? ????????//用以記錄右鍵按下或釋放的標志變量。

BOOL?HideOrVisitableFlag=0;??????????? //用以標識當再次有左、右鍵同時按下的情況發生時是隱藏還是顯示窗口。

BOOL?Check1=0;???????????????????????? //用來表示控件Check1狀態的標志變量。

BOOL?Check2=0;???????????????????????? //用來表示控件Check2狀態的標志變量。

BOOL?Check3=0;??????????? ?????????????//用來表示控件Check3狀態的標志變量。

?

#pragma data_seg()????????????????????? //#pragma data_seg("mydata") 首尾呼應表示該數據段的結束。

加入上述數據段以后還應在項目里插入一個“Mousehook.def”文件,用:"SECTIONS mydata READ WRITE SHARED"mydata數據段設置為一個可讀寫的共享段。在程序里加入預編譯指令,或在開發環境的項目設置里也可以達到設置數據段屬性的目的,我就不一一贅述了。

我前面講過,系統通過調用放在DLL中的鉤子回調函數來實現全局鉤(鉤取所有窗口的鼠標消息),操作系統對DLL的操作僅僅是把DLL映射到需要它的進程的虛擬地址空間里去。也就是說,DLL函數中的代碼所創建的任何對象(包括變量)都歸調用它的線程或進程所有。“DLLWIN32中什么都不擁有”——這句話很重要。比如我們在DLL里建立了一個變量a,而我們的這個DLL文件又被兩個進程所調用,這兩個進程的中都用到了a可這絕對是兩個不同存儲單元中存儲的兩個a,它們之間沒有絲毫的聯系。給其中一個賦值也絕對不會影響到另一個。而對于本程序的一些數據是需要在不同的進程中保持唯一的(也可以說是一致),比方說: HWND GlobalWndHandle[100]它是用來保存程序做了隱藏的窗口之句柄的數組。當程序運行,我在任意窗口A中同時按下了鼠標左、右鍵,由于設置了鼠標鉤子,系統會調用DLL中的鉤子處理函數截獲消息并加以處理,即把目前的可見窗口隱藏并把窗口句柄保存到GlobalWndHandle[100]數組中以備將來顯示之用。如果不把GlobalWndHandle[100]放到一個共享的數據段里,系統就會在目前我們截獲鼠標消息的A窗口的進程的地址空間里開辟HWND GlobalWndHandle[100]來存儲窗口句柄。這樣對于其他進程就不能方便地得到這個進程存入GlobalWndHandle[100]數組的數據了。這時只能將GlobalWndHandle[100]等需要跨進程訪問的變量數據放在一個共享的數據段里了。另外,需要特別注意——必須給這些變量賦初值(就象我在程序代碼里傻呼呼地寫了100NULL一樣。你可以不初始化這個數組試驗一下,有助于你理解我上面的話),否則編譯器會把沒有賦初始值的變量放在一個叫未被初始化的數據段中。

?

4步:編譯生成dll文件,并用MFC AppWizardexe)建立一個基于對話框的項目,在里面添加一個名為“Mousehook.h”的頭文件其內容與dll項目中的“Mousehook.h”文件一致,打開菜單的“Project Settings”對話框在“Link”選項標簽的“Object/library modules”編輯框里填入Mousehook.lib(此文件是與dll一起生成的,當編譯一個隱式調用dllexe時,lib文件起到提供dll引出函數接口地址的作用,如果此路徑設置不正確程序是無法進行連接的)文件的存放路徑。這樣就可以放心使用dll里定義的CMousehook類的成員了。如下:

1 HideWindowDlg.h中加入#include "MouseHook.h"并在CHideWindowDlg中定義一個CMousehook類對象hook

2 CHideWindowDlg::OnInitDialog()函數中加入hook.starthook()并初始化相關變量,這樣當對話框初始時就會啟動鼠標鉤子。

3 CHideWindowDlg::~CHideWindowDlg()函數中加入hook.stophook()。用以釋放對話框對象時解除鼠標鉤。

為了不忽略讀者的智力水平我只對主要的代碼進行了說明,其余有關托盤、Check控件的部分代碼都比較傳統也沒什么好說明的。最后,編譯成exe文件以后還須把Mousehook.dll文件拷貝到同exe相同的目錄下才能正確運行exe

?

臨了,希望大家能對我上文中含糊、混沌的地方提出批評指正,也歡迎大家來信(me@sanlian.com.cn)切磋。

轉載于:https://www.cnblogs.com/yefengmeander/archive/2011/08/03/2888013.html

總結

以上是生活随笔為你收集整理的浅谈HOOK的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

99精品偷拍视频一区二区三区 | 黄色视屏在线免费观看 | 免费不卡中文字幕视频 | 免费看的黄色小视频 | 色婷婷av一区二 | 日韩成人在线一区二区 | 激情视频91 | 天天操天天操天天操天天操 | 国内三级在线观看 | 涩涩成人在线 | 欧美日韩综合在线 | av黄色免费看 | 欧美另类视频 | 国产999久久久 | 日韩午夜电影网 | 成人精品视频久久久久 | 色婷婷综合久久久 | 国产免费观看久久黄 | 欧美成人精品欧美一级乱黄 | 亚洲h色精品 | 中文字幕日韩av | 精品久久久免费视频 | 中文字幕欧美日韩va免费视频 | 欧美在线视频免费 | 成片免费观看视频大全 | 中文字幕一区二区三区在线视频 | 色婷婷电影 | 在线亚洲播放 | 高清在线一区二区 | av大片网址 | 99久久超碰中文字幕伊人 | 黄色成人在线观看 | 日韩在线观看高清 | 亚洲精品mv在线观看 | 91亚洲精品久久久蜜桃网站 | 亚洲视频在线免费观看 | 激情婷婷综合网 | 色丁香色婷婷 | 国产v在线 | 日日夜夜综合网 | 国产一二区在线观看 | 国产手机视频在线观看 | 日韩中文字幕亚洲一区二区va在线 | 国产不卡精品 | 久久久久久美女 | av中文字幕亚洲 | 成人性生爱a∨ | 在线看v片成人 | 国产成人久久av977小说 | 国产成人精品日本亚洲999 | 韩日精品视频 | 三级小视频在线观看 | 99久久精品国产观看 | 黄色美女免费网站 | 亚洲精品xx | 日韩在线播放欧美字幕 | 成人国产在线 | 国产一级特黄毛片在线毛片 | 97国产在线观看 | 亚洲精品88欧美一区二区 | 狠狠色网 | 午夜精品影院 | 日本在线视频一区二区三区 | 三级午夜片 | 国产精品原创在线 | 国产精品网址在线观看 | 亚洲精品动漫在线 | 日韩在线观看影院 | 天天操操操操操操 | 久久精品99国产精品亚洲最刺激 | 人人澡人人添人人爽一区二区 | 五月综合色婷婷 | 亚洲六月丁香色婷婷综合久久 | 免费毛片一区二区三区久久久 | 国产亚洲在线视频 | 国产a级精品 | 久久免费精彩视频 | 日韩av在线免费播放 | 99视频在线精品免费观看2 | 国产青春久久久国产毛片 | 久二影院| 99久久精| 久久系列 | 亚洲一级片在线看 | 伊人天天综合 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 国产精品毛片一区视频 | 综合激情av | 婷婷丁香社区 | 中文字幕免费在线看 | 中文乱幕日产无线码1区 | av解说在线 | 欧美成人在线免费观看 | 青草视频在线看 | 黄色在线观看免费网站 | 国产成人久久77777精品 | 色综合久久久 | 超碰国产在线 | 国产日韩欧美视频 | 国产精品一区二区三区观看 | 日日草天天干 | 福利网址在线观看 | 成人免费91| 国产高清av免费在线观看 | 婷婷av色综合 | 国产视频九色蝌蚪 | 色综合久久88色综合天天免费 | 在线天堂视频 | 国产第一页在线观看 | 日产乱码一二三区别免费 | 成人av在线电影 | 久久免费国产 | 黄色网址国产 | 久久午夜色播影院免费高清 | 精品视频资源站 | 成人播放器 | 久久96国产精品久久99软件 | 一区二区三区 中文字幕 | 久久久国产精品麻豆 | 久久国语露脸国产精品电影 | 成人a级大片| 久久国产乱 | 亚洲国产中文字幕在线视频综合 | 国产高清精| 综合久久一本 | 国产小视频你懂的 | 操操操日日日干干干 | 日韩欧美在线播放 | 亚洲精品午夜国产va久久成人 | 免费观看视频黄 | 日韩综合第一页 | 国产精品久久久久影院日本 | 免费观看视频的网站 | 久久69av| 亚洲精品18日本一区app | 久青草国产在线 | 91桃色国产在线播放 | 黄av资源 | 粉嫩高清一区二区三区 | av资源中文字幕 | 麻豆视频免费播放 | 日韩欧在线| 视频成人| 久久无码精品一区二区三区 | 中文字幕在线免费观看视频 | 亚洲精品自拍 | 97成人免费 | 欧美激情综合五月色丁香 | 亚洲激情网站免费观看 | 国产高清区 | 日韩黄色免费电影 | 久久综合五月天 | 久久精品视频在线观看免费 | 精品无人国产偷自产在线 | 色婷婷婷| 欧美精品久久久久久久久久丰满 | 日韩高清免费在线 | 91视频 - x99av| av在线com| av免费看av| 婷婷丁香九月 | 色片网站在线观看 | 国产天天爽 | 91久久国产精品 | 午夜国产在线 | 日韩高清dvd | 国产精品福利在线 | 欧美日韩一区二区免费在线观看 | 欧美精品成人在线 | 国产成人精品一区二区三区 | 国产黄a三级三级三级三级三级 | 久久不卡视频 | 特级a老妇做爰全过程 | 91亚洲免费| 91成人看片| av久久久| 欧美在线视频a | 亚洲欧洲国产精品 | 久久爱资源网 | 国产手机视频 | 欧美视频www | 在线观看一级视频 | 最新国产一区二区三区 | 波多野结衣一区三区 | 日韩视频在线观看视频 | 国产一区 在线播放 | 国产视频一区二区在线播放 | 99草视频在线观看 | 中文区中文字幕免费看 | 亚洲国产免费av | 久久综合中文字幕 | 日韩视频在线播放 | 欧美性色xo影院 | 人人爽人人澡人人添人人人人 | 99视频在线 | 高潮久久久久久久久 | 91精品国产网站 | 中文字幕久久精品一区 | 中文字幕网址 | 亚洲人天堂 | 亚洲mv大片欧洲mv大片免费 | 精品久久中文 | 日韩手机在线 | 一区二区三区久久精品 | 成人在线视频观看 | 国产精品久久久久9999 | 成年人免费看 | 成人精品久久 | 欧美在线观看视频 | 探花视频免费观看高清视频 | 嫩草av在线| 亚洲国产中文在线 | 日韩精品首页 | 久久久免费 | 最近免费在线观看 | 精品一区二区av | 久久久久在线 | 亚洲精品国产欧美在线观看 | 日韩精品短视频 | 五月婷婷激情网 | 亚洲成人av电影 | 一区二区电影网 | 亚洲成av人片在线观看香蕉 | 超碰在线天天 | 国产精品久久久久9999吃药 | 三级黄色网址 | 天天色天天干天天色 | 中文字幕免费不卡视频 | 久久久高清免费视频 | 偷拍区另类综合在线 | 中文字幕亚洲综合久久五月天色无吗'' | 久久精品视频网站 | 亚洲乱亚洲乱亚洲 | 国产视频2区 | 午夜精品一区二区三区免费视频 | 在线观看 国产 | 一级片视频免费观看 | 91精品国产福利在线观看 | 国产精品日韩在线观看 | 免费av的网站 | 国产91在线看 | 91麻豆免费版 | 天天五月天色 | 午夜精品久久久久久久爽 | 97超在线视频 | 激情综合色综合久久综合 | 中午字幕在线观看 | 国产一级做a | 欧美日韩精品在线 | 欧美色图另类 | 久久天| 一区二区精 | 欧美特一级片 | 欧美精品久久人人躁人人爽 | 亚洲一级理论片 | av在线播放亚洲 | 女人魂免费观看 | 亚洲第一成网站 | 久久任你操 | 免费一级片在线 | 超碰人人干人人 | av大全在线看 | 欧美做受xxx | 日韩成人免费在线 | 色综合久久悠悠 | 免费在线观看的av网站 | 国产精品 日韩精品 | 在线免费观看麻豆 | 日韩久久久久 | 黄色av一区二区 | 精品久久久久久国产 | 久久免费片 | 国产第一二区 | 国产一区二区久久 | 最近更新好看的中文字幕 | 精品福利国产 | 狠狠操狠狠 | 国产 欧美 在线 | 精品国自产在线观看 | 免费观看日韩 | av片子在线观看 | 在线视频福利 | www免费看 | av一区二区在线观看中文字幕 | 精品亚洲免费视频 | 美女av电影| 综合婷婷丁香 | 色亚洲激情 | 日韩a级免费视频 | 亚洲三级黄色 | 丁香视频五月 | 成年人在线免费视频观看 | 中文字幕2021| 精品亚洲视频在线观看 | 99热.com| 深爱婷婷激情 | 国产精品久久久久久妇 | 成年人在线观看视频免费 | 国产精品ssss在线亚洲 | 18做爰免费视频网站 | 国产资源免费 | 亚洲电影av在线 | 亚洲激情网站免费观看 | 一级片观看 | 久久伊99综合婷婷久久伊 | 国产精品第十页 | a视频在线观看免费 | 99久久999久久久精玫瑰 | 国产高清免费观看 | 亚洲成人av影片 | 免费高清在线观看成人 | 日韩一区二区三免费高清在线观看 | wwwww.国产| 日本中文字幕在线播放 | 日韩 在线a | 日韩二区三区在线观看 | 国产一级做a爱片久久毛片a | 日日操操| 中国一级片在线播放 | www.久艹| 国产美女在线精品免费观看 | 开心婷婷色 | av青草 | 九九精品久久 | 人人舔人人爱 | 欧美性大战久久久久 | 午夜国产一区 | 最近高清中文在线字幕在线观看 | 日韩二区三区在线 | 国产一级淫片在线观看 | 九色91福利 | 男女全黄一级一级高潮免费看 | 天天撸夜夜操 | 中文一区二区三区在线观看 | 天天操天天操天天操天天操 | 狠狠躁天天躁综合网 | 国产成人a v电影 | 中文字幕频道 | 一级黄色大片在线观看 | 激情图片久久 | 欧美整片sss | 久草在线资源免费 | 精品福利视频在线观看 | 国产精品亚洲精品 | 国产中文在线观看 | 亚洲国产中文字幕在线观看 | 日韩中文字幕国产 | 97精品国产97久久久久久春色 | 香蕉视频免费在线播放 | 亚洲妇女av | 天天躁天天狠天天透 | 天天弄天天操 | 免费观看日韩av | 九九久久影院 | 国产不卡一区二区视频 | 精品在线视频一区 | 免费看一级黄色 | 国产成人精品一区二区三区福利 | 九色自拍视频 | 国产精品视频久久久 | 中文网丁香综合网 | 久久人人爽人人爽人人 | 午夜精品一区二区三区在线播放 | 久久avav| 亚洲精品久久久久久久蜜桃 | 国产精品美女久久久久久久 | 中文字幕视频网站 | 久久久久亚洲国产精品 | 狠狠躁日日躁狂躁夜夜躁av | 日韩精品专区 | 又色又爽又黄高潮的免费视频 | 最近更新好看的中文字幕 | 波多野结衣视频一区二区三区 | 五月婷婷综合在线 | 国产精品久久久久免费观看 | av高清影院 | 国产亚洲精品久久久久久移动网络 | 亚洲精品mv在线观看 | 日韩久久精品一区 | 在线观看视频亚洲 | 色丁香久久 | 亚洲激情影院 | 综合色狠狠 | 91成人网在线播放 | 欧美日韩二区在线 | 久久久三级视频 | 国产视频久久久 | 91中文字幕永久在线 | 特级毛片网站 | 色.www| 日日操天天射 | 日韩资源在线播放 | 香蕉精品在线观看 | 免费在线观看av网站 | 九九国产精品视频 | www.天天成人国产电影 | 黄色小说视频在线 | 香蕉色综合 | 精品久久一级片 | 人人干97 | 亚洲精品黄色 | 中文字幕在线观看网 | 一本一本久久a久久精品综合小说 | 国产成人免费在线观看 | 玖玖视频| 超碰97久久 | 中文字幕专区高清在线观看 | 正在播放国产一区二区 | 国产精品一级视频 | 精品在线免费视频 | 国产一级在线免费观看 | 亚洲成人一区 | 国产一二三四在线视频 | 外国av网| 久久久免费看视频 | 久久精品国产美女 | 久久久久激情电影 | 色.www| 999成人国产 | av高清一区二区三区 | 亚洲,国产成人av | 欧美一区在线看 | 在线播放一区二区三区 | 久久成人在线 | 在线成人免费 | 96精品视频 | 欧美在线观看视频 | 在线免费观看黄色 | 日韩v欧美v日本v亚洲v国产v | 国产99一区视频免费 | 女人18片毛片90分钟 | 国产精品美女视频网站 | 午夜精品一区二区三区免费视频 | 精品视频免费观看 | 黄色1级毛片 | 久久艹人人| 久久久国产一区二区三区四区小说 | 久久婷婷综合激情 | 婷婷激情久久 | 在线免费观看欧美日韩 | 亚洲精品 在线视频 | 精品国产自在精品国产精野外直播 | 国产精品18久久久久久久久久久久 | 在线观看中文字幕dvd播放 | 国产美女视频 | 免费视频区 | 国产精品嫩草55av | 91精品视频免费观看 | 精品国产99| 国产999精品久久久久久麻豆 | 久久精品亚洲一区二区三区观看模式 | 国产精品成人久久 | 少妇超碰在线 | 六月天色婷婷 | 日韩午夜高清 | 日韩理论电影在线观看 | 日韩精品一区二区在线视频 | 精品国产精品久久一区免费式 | 在线亚洲免费视频 | 国产精品999久久久 久产久精国产品 | 欧美巨大荫蒂茸毛毛人妖 | 99久国产| 久久人人爽av | 欧美日韩一区二区三区视频 | av3级在线| 精品福利网站 | 亚洲精品在线观看中文字幕 | 久久大视频 | 中文字幕丰满人伦在线 | 五月天天色 | 国内免费久久久久久久久久久 | 婷婷色综 | 狠狠的干狠狠的操 | 午夜男人影院 | 五月婷婷导航 | 成人网色| av在线影片 | 免费黄色网止 | 免费观看的av网站 | 国内精品国产三级国产aⅴ久 | 操天天操 | 久久视频精品在线 | 色婷婷丁香 | 少妇按摩av | 亚洲激情久久 | 久久久久福利视频 | 免费在线黄色av | 日韩av电影手机在线观看 | 日韩免费成人av | 久久久精品国产一区二区电影四季 | 日韩一区二区免费视频 | 免费69视频 | 成年人电影免费在线观看 | 麻豆系列在线观看 | 国产高清av免费在线观看 | 激情五月网站 | 日本精品中文字幕在线观看 | 天天操天天插 | 国产污视频在线观看 | 久久午夜网 | www.夜色321.com | 日韩二级毛片 | 一级一片免费观看 | 又黄又刺激视频 | 成人免费观看网址 | 国模精品一区二区三区 | 国产999精品久久久久久绿帽 | 亚洲国产精品视频 | 亚洲资源片| 亚洲免费精彩视频 | 久久亚洲欧美日韩精品专区 | 日韩精品一区二区三区中文字幕 | 久久久私人影院 | 亚洲一区视频在线播放 | 亚洲欧美激情精品一区二区 | 九草视频在线 | 久久久久亚洲精品中文字幕 | 日韩肉感妇bbwbbwbbw | 国产一区欧美日韩 | 激情小说网站亚洲综合网 | 久久久精品国产一区二区电影四季 | av中文字幕在线观看网站 | 婷婷草 | 最新av在线播放 | 97在线观看免费 | 97碰碰精品嫩模在线播放 | 亚洲激精日韩激精欧美精品 | 日韩黄色免费 | 免费看的黄色片 | 国产麻豆视频在线观看 | 国产又粗又硬又长又爽的视频 | 91x色| av免费观看高清 | 免费观看的av | 欧美激情xxxx性bbbb | 亚洲在线高清 | 99热精品免费观看 | 国产91免费观看 | 久久精品国产精品亚洲 | 久久电影色 | 精品在线观看免费 | 99热只有精品在线观看 | 91黄色在线观看 | 欧美精品久久久久久久久久 | 中文字幕国产在线 | 日韩成人精品 | 国产成人免费精品 | 亚洲最新视频在线 | 午夜狠狠操 | 中文字幕在线观看免费观看 | 亚洲精品欧洲精品 | 一区在线观看 | av网站在线观看免费 | 丁香激情五月婷婷 | 69视频网站| 久久电影网站中文字幕 | 免费看片网站91 | 国产精品入口麻豆 | 婷婷六月网 | www.av免费观看| 香蕉久草 | 日韩高清毛片 | 黄色精品视频 | 亚洲免费专区 | 韩国av在线播放 | 欧洲一区精品 | 日韩91在线 | 在线视频一二三 | 麻豆精品传媒视频 | 免费观看十分钟 | 欧美亚洲三级 | 在线观看视频黄色 | 西西www444 | 免费成人短视频 | 日韩欧美视频免费观看 | 国产精品久久久电影 | 久久免费视频这里只有精品 | 久香蕉 | 91日韩在线播放 | 99视频国产精品免费观看 | 97国产在线 | 热久久视久久精品18亚洲精品 | 9999国产精品 | 人人揉人人揉人人揉人人揉97 | 久久再线视频 | 国产美女视频一区 | 日韩精品久久中文字幕 | 国产欧美中文字幕 | 国产视频1| 亚洲国产成人在线播放 | 国产精品久久麻豆 | 国产精品区免费视频 | 四虎成人网 | 91视频免费视频 | 91在线播放国产 | 国产精品亚洲视频 | 亚洲欧美日韩国产一区二区 | 国内精品久久久久影院日本资源 | 超碰在线亚洲 | 国产精品视频永久免费播放 | 欧美精品v国产精品v日韩精品 | 亚洲国产欧美在线看片xxoo | 国产日产精品一区二区三区四区的观看方式 | av在线一级 | 黄色的网站免费看 | 亚洲亚洲精品在线观看 | 视频成人永久免费视频 | 久久视频在线 | 久久久久免费精品国产小说色大师 | 97免费视频在线播放 | 婷婷精品在线 | 在线黄色国产电影 | 天天操天天摸天天爽 | 亚洲深夜影院 | av爱干| 国产精品18久久久久久vr | 91在线看视频 | 男女激情网址 | 欧美国产日韩一区二区三区 | 成人免费视频免费观看 | 日韩色区| 成人av网站在线观看 | 色福利网站| 天天添夜夜操 | 99精品在这里 | 毛片永久新网址首页 | 日日天天av | 久久久久久福利 | 夜夜躁天天躁很躁波 | 在线 国产一区 | 日韩av黄 | av福利免费 | 国产色网站 | 丁香五月亚洲综合在线 | 日韩精品中文字幕在线不卡尤物 | av在线激情 | 日韩乱理 | 在线观看www91 | 成人在线播放网站 | 欧美aa一级| 日韩二区三区在线 | 中文字幕欧美三区 | 国产成人精品999 | 午夜成人免费电影 | 中文字幕久久精品一区 | 超碰97久久 | 中文视频在线 | 又大又硬又黄又爽视频在线观看 | 亚洲一区欧美精品 | 手机看片国产 | 高清av免费一区中文字幕 | 天天天天色射综合 | 日本中文字幕观看 | 日本黄色免费在线 | 久久 地址 | 久久久国产精品一区二区中文 | 91精品影视 | 96av麻豆蜜桃一区二区 | 久草精品国产 | 久久综合9988久久爱 | av片子在线观看 | 久久国产热| 亚洲精品一区二区久 | 亚洲国产视频a | 99精品视频中文字幕 | 久久国产精品色婷婷 | 久久精品中文字幕少妇 | 日批视频在线观看免费 | 91成人免费电影 | 婷婷综合导航 | 婷婷丁香激情 | 日韩免费成人av | 毛片网站在线看 | 伊人色播| 国产在线播放一区二区三区 | 日本精品久久久久中文字幕5 | 美女网站在线观看 | 中文 一区二区 | 五月婷婷开心 | 国产91精品在线观看 | 五月婷香蕉久色在线看 | 黄色软件大全网站 | 99热精品在线观看 | 久久久久久毛片精品免费不卡 | 亚洲成人av免费 | 国产 日韩 在线 亚洲 字幕 中文 | 久草视频在线资源站 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 91手机电视 | 日韩欧美精品免费 | 成年人黄色在线观看 | 久久久久久久久久久福利 | 精品一区二区在线看 | 亚洲视频精品 | 欧美精品免费一区二区 | 国产精品久久久久久久久久久久午夜 | 国产免费一区二区三区最新 | 亚洲激色 | av韩国在线 | 婷婷视频在线观看 | 国色综合 | 手机av资源 | 日本在线观看视频一区 | 亚洲精品美女久久17c | 国产在线最新 | 二区视频在线观看 | 日日摸日日碰 | 久久久96 | 国产麻豆电影在线观看 | 涩涩资源网 | 日日爽视频 | 最近中文字幕免费观看 | 国产在线播放不卡 | 在线黄色免费 | 色99久久| 日韩欧美一区视频 | 久久乐九色婷婷综合色狠狠182 | www婷婷 | 97爱爱爱 | 中文字幕在线免费播放 | 亚洲精品乱码久久久久 | 日本一区二区高清不卡 | 免费看一及片 | 国产福利91精品 | 国产一级免费视频 | 久久九九影视网 | 久99久在线视频 | 91社区国产高清 | 久久夜色精品国产欧美乱 | 色婷婷av在线 | 夜夜操综合网 | 国产精品久久二区 | 国产精品白浆视频 | 国产精品一区二区视频 | 色综合狠狠干 | 天天爱天天 | 国产丝袜| 久久久久久久福利 | 国产视频一二三 | 天天干天天拍天天操天天拍 | 国产视频久久久 | 天天爱天天射 | 久久精品视频在线免费观看 | 99国产一区二区三精品乱码 | 亚洲综合色网站 | 欧美在线a视频 | 久久精品一二三区 | 黄色a在线观看 | 成人毛片久久 | 精品国产观看 | 综合久久精品 | 国产h在线播放 | 一区二区三区四区免费视频 | 日韩一级精品 | 国产日韩精品欧美 | 国产黄色免费电影 | 精品一区二区久久久久久久网站 | 成人午夜片av在线看 | 91网页版在线观看 | 国产97碰免费视频 | 婷婷综合五月天 | 在线黄av| 96亚洲精品久久久蜜桃 | 日韩精品无码一区二区三区 | 亚洲一二视频 | 久久综合久久综合这里只有精品 | 久草免费手机视频 | 激情网第四色 | 一级a毛片高清视频 | 亚洲精品成人 | 国产成人精品一区二区三区在线观看 | 国产小视频在线免费观看视频 | 久久久久免费电影 | 九九久久国产精品 | 在线观看成人毛片 | 9797在线看片亚洲精品 | 久久99精品国产99久久 | 久久人人爽人人爽 | 一区二区三区四区不卡 | 日韩r级在线 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 色婷婷色 | 美女黄视频免费看 | 久久手机免费视频 | 国产九色视频在线观看 | 在线va视频 | 日本一区二区三区视频在线播放 | 最新av在线播放 | 成人午夜影院在线观看 | 91爱爱电影 | 久久精品4 | 亚洲 欧美 精品 | 91久久久久久久一区二区 | 欧美成人a在线 | 久久老司机精品视频 | 日韩动态视频 | 蜜臀av性久久久久蜜臀av | 国产区精品区 | 午夜av大片 | 一区二区中文字幕在线观看 | 最新国产精品亚洲 | 黄色影院在线观看 | 91探花在线视频 | 日韩精品中文字幕久久臀 | 国产精品嫩草55av | 91最新国产 | 国产粉嫩在线观看 | 天天操天天操天天操 | 国产99久久久国产精品免费二区 | 91亚洲精品久久久蜜桃借种 | 欧美色婷婷 | 91精品办公室少妇高潮对白 | 欧美福利片在线观看 | 四虎最新入口 | 亚洲人成免费网站 | 婷婷新五月 | 最近中文字幕高清字幕在线视频 | 成年人在线观看视频免费 | 天天干天天看 | 欧美性生活小视频 | 97国产一区二区 | 婷婷色伊人 | 天天天干夜夜夜操 | 美女福利视频在线 | 丁香九月婷婷 | 一级a性色生活片久久毛片波多野 | 精品久久久久国产 | 久久调教视频 | 国产精久久久久久妇女av | 久久亚洲专区 | 国产成人精品一区二区 | 一区国产精品 | 91精品国产三级a在线观看 | 奇米影视8888在线观看大全免费 | 中文字幕日韩伦理 | 国产99久久久国产精品成人免费 | 日韩精品五月天 | 99精品在线免费 | 免费视频 你懂的 | 午夜久久久久久久久久影院 | 色的网站在线观看 | 国产成人一级 | 成人a在线观看 | 欧美日韩国产一区二区三区 | 午夜久久电影网 | 91视频久久久久久 | 亚洲91中文字幕无线码三区 | 视频直播国产精品 | 99视频国产精品免费观看 | 中文字幕中文字幕在线一区 | 国产一区久久 | 五月婷婷综 | 国产精品久久伊人 | 日韩亚洲国产中文字幕 | 九九热精品视频在线观看 | 在线精品视频在线观看高清 | 四虎在线免费观看 | 最近字幕在线观看第一季 | 久99久在线| 国产精品久久久久9999 | 精品xxx| 这里只有精品视频在线观看 | 国产伦精品一区二区三区免费 | 91久久精品一区二区二区 | 日韩av免费在线电影 | 欧美成人视 | 国产视频在线一区二区 | 国产在线永久 | 国产精品自拍在线 | 国产一区免费在线观看 | 成年人免费在线观看网站 | 综合网五月天 | 天天干,天天射,天天操,天天摸 | 久久久久亚洲精品国产 | 国产99久久久国产精品成人免费 | 在线观看黄污 | 97超碰人人澡人人爱学生 | 欧美精品一区二区三区一线天视频 | 97电影手机 | 一级一片免费视频 | 深夜成人av| 日韩另类在线 | 亚洲国产成人在线播放 | 丁香五香天综合情 | 91麻豆网 | 欧美久久成人 | 欧美日韩超碰 | 国产福利一区在线观看 | 在线观看免费版高清版 | av电影 一区二区 | 福利视频一区二区 | 日日躁天天躁 | 国产五月婷 | 黄色大片av | 国产视频精品免费播放 | 精品久久久久久亚洲综合网 | 亚洲电影久久 | 亚洲特级毛片 | 夜色成人av| 成人全视频免费观看在线看 | 欧美一级性视频 | 亚洲永久精品在线观看 | 一区二区三区手机在线观看 | 天天干天天在线 | 高清av免费看 | 婷婷综合五月天 | 日韩三级视频在线看 | 国产三级香港三韩国三级 | 亚洲免费国产视频 | 日韩免费一区二区 | 在线观看精品一区 | 免费在线观看国产黄 | 午夜av免费看 | av免费成人 | 国产最新在线视频 | 国产精品视频免费在线观看 | 永久免费av在线播放 | 国产毛片aaa| 亚洲第一区在线播放 | 中文在线免费视频 | 国产伦精品一区二区三区照片91 | 国产精华国产精品 | 国产激情小视频在线观看 | 国产伦精品一区二区三区照片91 | 久久国产精品精品国产色婷婷 | 国产99久久九九精品免费 | 亚洲涩涩涩涩涩涩 | 草久中文字幕 | av经典在线 | 在线国产片| 免费黄a | 福利视频网站 | 日韩免费网址 | 韩国精品一区二区三区六区色诱 | 麻豆传媒视频在线免费观看 | 欧美色综合天天久久综合精品 | 国产精品a成v人在线播放 | www.久久爱.cn | 正在播放国产91 | av中文字幕网 | 久久久久久免费 | 日本在线观看黄色 | 91高清一区 | 91高清一区| 日批网站免费观看 | 色婷婷亚洲 | 亚洲成人资源 | 在线观看深夜视频 | 成人黄色小说网 | 亚洲日本在线视频观看 | 精品国产一区二区三区免费 | 国产精品资源网 | 久久久在线观看 | 免费看片成人 | 久久久久久草 | 精品国产激情 | 国内三级在线观看 | 免费av大全 | 国产1级毛片 | 亚洲一区二区三区精品在线观看 | 国产日韩精品在线 | 香蕉视频在线播放 | 久久99视频免费观看 | free. 性欧美.com | 中文字幕婷婷 | 午夜三级在线 | 成人久久久精品国产乱码一区二区 | 国产破处精品 | 国产成人福利片 | 日韩欧美国产精品 | 天堂在线免费视频 | 免费99精品国产自在在线 | 亚洲精品久久久蜜臀下载官网 | 欧美成人91 | 欧美日韩电影在线播放 | 亚洲一区二区高潮无套美女 | 日韩二区三区 | 日韩精品一区二区久久 | 在线观看免费91 | 久久国产香蕉视频 | 欧美一区二区日韩一区二区 | 久久视频免费 | 狠狠干,狠狠操 | 免费视频久久久 | 国产高清在线不卡 | www.五月天婷婷.com | 在线亚洲高清视频 | 草草草影院| 日免费视频 | 国内精品久久久久影院一蜜桃 | 欧美视频二区 | 波多野结衣在线视频一区 | 美女久久久久久久久久 | 精品福利视频在线观看 | 色婷婷狠狠五月综合天色拍 | 91视频在线国产 | 中文字幕av电影下载 | 精品国产自 |