在Windows系統(tǒng)中用VC++實(shí)現(xiàn)鉤子機(jī)制_第1頁(yè)
在Windows系統(tǒng)中用VC++實(shí)現(xiàn)鉤子機(jī)制_第2頁(yè)
在Windows系統(tǒng)中用VC++實(shí)現(xiàn)鉤子機(jī)制_第3頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

在Windows系統(tǒng)中用VC++實(shí)現(xiàn)鉤子機(jī)制

摘要:本文分析了在Windows環(huán)境下,什么是鉤子程序以及怎樣用VC++實(shí)現(xiàn)一個(gè)鉤子機(jī)制的關(guān)鍵技術(shù)。最后,用一個(gè)可以截獲鼠標(biāo)信息的完整程序說(shuō)明了這些問題。關(guān)鍵詞:鉤子程序,DLL,消息截獲一.

什么是鉤子。Windows系統(tǒng)是建立在事件驅(qū)動(dòng)的機(jī)制上的,說(shuō)穿了就是整個(gè)系統(tǒng)都是通過消息的傳遞來(lái)實(shí)現(xiàn)的。鉤子(hook)是一種特殊的消息處理機(jī)制,鉤子可以監(jiān)視系統(tǒng)或進(jìn)程中的各種事件消息,截獲發(fā)往目標(biāo)窗口的消息并進(jìn)行處理。這樣,我們就可以在系統(tǒng)中安裝自定義的鉤子,監(jiān)視系統(tǒng)中特定事件的發(fā)生,完成特定的功能,比如截獲鍵盤、鼠標(biāo)的輸入,屏幕取詞,日志監(jiān)視等等。鉤子的種類很多,每種鉤子可以截獲并處理相應(yīng)的消息,如鍵盤鉤子可以截獲鍵盤消息,外殼鉤子可以截取、啟動(dòng)和關(guān)閉應(yīng)用程序的消息等。鉤子可以分為線程鉤子和系統(tǒng)鉤子,線程鉤子監(jiān)視指定線程的事件消息,系統(tǒng)鉤子監(jiān)視系統(tǒng)中的所有線程的事件消息。因?yàn)橄到y(tǒng)鉤子會(huì)影響系統(tǒng)中所有的應(yīng)用程序,所以鉤子函數(shù)必須放在獨(dú)立的動(dòng)態(tài)鏈接庫(kù)(DLL)中。二.

實(shí)現(xiàn)鉤子機(jī)制的幾個(gè)關(guān)鍵技術(shù)。1.

windows的鉤子程序,需要用到幾個(gè)sdk中的api函數(shù)。下面列出這幾個(gè)函數(shù)的原型及說(shuō)明:hhooksetwindowshookex(intidhook,hook_proclpfn,hinstancehmod,dworddwthreadid);參數(shù)說(shuō)明如下:

idhook:鉤子的類型

lpfn:鉤子處理函數(shù)地址

hmod:包含鉤子函數(shù)的模塊句柄

dwthreadid:鉤子的監(jiān)控線程函數(shù)說(shuō)明:函數(shù)將在系統(tǒng)中掛上一個(gè)由idhook指定類型的鉤子,監(jiān)控并處理相應(yīng)的特定消息。boolunhookwindowshookex(hhookhhk);函數(shù)說(shuō)明:函數(shù)將撤銷由hhk指定的鉤子。lresultcallnexthookex(hhookhhk,intncode,wparamwparam,lparamlparam);函數(shù)說(shuō)明:函數(shù)將消息向下傳遞,下一個(gè)鉤子處理將截獲這一消息。2.

由于鉤子的處理涉及到模塊及進(jìn)程間的數(shù)據(jù)地址問題,一般情況是把鉤子整合到一個(gè)動(dòng)態(tài)鏈接庫(kù)(dll)中,VC中有三種形式的MFCDLL可供選擇,即RegularstaticallylinkedtoMFCDLL(標(biāo)準(zhǔn)靜態(tài)鏈接MFCDLL)、RegularusingthesharedMFCDLL(標(biāo)準(zhǔn)動(dòng)態(tài)鏈接MFCDLL)以及ExtensionMFCDLL(擴(kuò)展MFCDLL)。第一種DLL在編譯時(shí)把使用的MFC代碼鏈接到DLL中,執(zhí)行程序時(shí)不需要其他MFC動(dòng)態(tài)鏈接類庫(kù)的支持,但體積較大;第二種DLL在運(yùn)行時(shí)動(dòng)態(tài)鏈接到MFC類庫(kù),因而體積較小,但卻依賴于MFC動(dòng)態(tài)鏈接類庫(kù)的支持;這兩種DLL均可被MFC程序和Win32程序使用。第三種DLL的也是動(dòng)態(tài)連接,但做為MFC類庫(kù)的擴(kuò)展,只能被MFC程序使用。另外,要設(shè)立一個(gè)全局?jǐn)?shù)據(jù)共享數(shù)據(jù)段,以存貯一些全局變量,保留上次鉤子消息事件發(fā)生時(shí)的狀態(tài)。3.

Win32DLL的入口和出口函數(shù)都是DLLMain。只要有進(jìn)程或線程載入和卸載DLL時(shí),都會(huì)調(diào)用該函數(shù),其原型是:BOOLWINAPIDllMain(HINSTANCEhinstDLL,DWORDfdwReason,LPVOIDlpvReserved);其中,第一個(gè)參數(shù)表示DLL的實(shí)例句柄;第三個(gè)參數(shù)系統(tǒng)保留;第二個(gè)參數(shù)指明了當(dāng)前調(diào)用該動(dòng)態(tài)連接庫(kù)的狀態(tài),它有四個(gè)可能的值:DLL_PROCESS_ATTACH(進(jìn)程載入)、DLL_THREAD_ATTACH(線程載入)、DLL_THREAD_DETACH(線程卸載)、DLL_PROCESS_DETACH(進(jìn)程卸載)。在DLLMain函數(shù)中可以通過對(duì)傳遞進(jìn)來(lái)的這個(gè)參數(shù)的值進(jìn)行判別,根據(jù)不同的參數(shù)值對(duì)DLL進(jìn)行必要的初始化或清理工作。由于在Win32環(huán)境下,所有進(jìn)程的空間都是相互獨(dú)立的,這減少了應(yīng)用程序間的相互影響,但大大增加了編程的難度。當(dāng)進(jìn)程在動(dòng)態(tài)加載DLL時(shí),系統(tǒng)自動(dòng)把DLL地址映射到該進(jìn)程的私有空間,而且也復(fù)制該DLL的全局?jǐn)?shù)據(jù)的一份拷貝到該進(jìn)程空間,每個(gè)進(jìn)程所擁有的相同的DLL的全局?jǐn)?shù)據(jù)其值卻并不一定是相同的。當(dāng)DLL內(nèi)存被映射到進(jìn)程空間中,每個(gè)進(jìn)程都有自己的全局內(nèi)存拷貝,加載DLL的每一個(gè)新的進(jìn)程都重新初始化這一內(nèi)存區(qū)域,也就是說(shuō)進(jìn)程不能再共享DLL。因此,在Win32環(huán)境下要想在多個(gè)進(jìn)程中共享數(shù)據(jù),就必須進(jìn)行必要的設(shè)置。一種方法便是把這些需要共享的數(shù)據(jù)單獨(dú)分離出來(lái),放置在一個(gè)獨(dú)立的數(shù)據(jù)段里,并把該段的屬性設(shè)置為共享,建立一個(gè)內(nèi)存共享的DLL。三.

用鉤子機(jī)制實(shí)現(xiàn)截獲鼠標(biāo)左右鍵按壓次數(shù)。建立鉤子程序時(shí)需要把鉤子處理整合到動(dòng)態(tài)鏈接庫(kù)中,所以例程中需要建立兩個(gè)project。1.

鉤子處理動(dòng)態(tài)鏈接庫(kù)(1)

選擇mfcappwizard(dll)創(chuàng)建一個(gè)新project,命名為“spy”。(2)

選擇mfcextensiondll類型。(3)

創(chuàng)建一個(gè)新的頭文件,命名為“hook.h”,修改它的代碼如下:extern"C"LRESULTCALLBACKmouseproc(intcode,WPARAMwparam,LPARAMlparam);//鉤子處理函數(shù)extern"C"boolWINAPIstarthook();//啟動(dòng)鉤子函數(shù)extern"C"boolWINAPIstophook();//撤銷鉤子函數(shù)extern"C"intWINAPIgetresultl();//取得鼠標(biāo)左鍵單擊次數(shù)的函數(shù)extern"C"intWINAPIgetresultr();//取得鼠標(biāo)右鍵單擊次數(shù)的函數(shù)(4)

修改spy.cpp程序代碼如下:#include"hook.h"

//包含頭文件hook#pragmadata_seg("publicdata")//定義全局?jǐn)?shù)據(jù)段HHOOKhhook=NULL;//鉤子句柄HINSTANCEpinstance=NULL;//鉤子模塊句柄UINTmouseclickl=0;//記錄鼠標(biāo)左鍵單擊次數(shù)的變量UINTmouseclickr=0;//記錄鼠標(biāo)右鍵單擊次數(shù)#pragmadata_seg()extern"C"intAPIENTRYDllMain(HINSTANCEhInstance,DWORDdwReason,LPVOIDlpReserved)

{if(dwReason==DLL_PROCESS_ATTACH)

{……

//省略部分機(jī)器生成代碼

newCDynLinkLibrary(SpyDLL);

pinstance=hInstance;//取得模塊句柄}……;

}extern"C"LRESULTCALLBACKmouseproc(intcode,

WPARAMwparam,LPARAMlparam)//鉤子處理函{

if(code<0)

//若code〈0,則直接調(diào)用callnexthookex返回returnCallNextHookEx(hhook,code,wparam,lparam);

if(wparam==WM_LBUTTONDOWN)

{

mouseclickl++;//記錄鼠標(biāo)左鍵單擊次數(shù)

}

if(wparam==WM_RBUTTONDOWN)

{

mouseclickr++;//記錄鼠標(biāo)右鍵單擊次數(shù)

}

returnCallNextHookEx(hhook,code,wparam,lparam);}extern"C"boolWINAPIstarthook()//啟動(dòng)鉤子函數(shù){

hhook=SetWindowsHookEx(WH_MOUSE,mouseproc,pinstance,0);//掛上鉤子

if(hhook!=NULL)returntrue;

elsereturnfalse;}extern"C"boolWINAPIstophook()//撤銷鉤子函數(shù){

returnUnhookWindowsHookEx(hhook);//撤銷鉤子}extern"C"intWINAPIgetresultl()//返回鼠標(biāo)左鍵單擊次數(shù){

returnmouseclickl;}extern"C"intWINAPIgetresultr()//返回鼠標(biāo)右鍵單擊次數(shù){

returnmouseclickr;}

(5)

修改spy.def程序代碼如下:

exportsstophook@2starthook@1getresultl@3getresultr@4(6)編譯project,生成spy.dll文件和spy.lib文件。2.

建立使用鉤子的應(yīng)用程序(1)

生成一個(gè)單文檔的可執(zhí)行文件(exe)的project。(2)

修改資源中的主選單,增加一個(gè)選單項(xiàng)“監(jiān)控”,下有三個(gè)子選單項(xiàng),分別為“啟動(dòng)”、“撤銷”和“取出”。(3)

在project中加入spy.lib文件。(4)

分別修改“啟動(dòng)”、“撤銷”和“取出”選單項(xiàng)的command響應(yīng)函數(shù)如下:#include"E:\DevStudio\MyProjects\spy\hook.h"http://路徑可不同voidCMainFrame::OnMenuitem32771()//“啟動(dòng)”選單項(xiàng)的響應(yīng)函數(shù){

starthook();}voidCMainFrame::OnMenuitem32772()//“撤銷”選單項(xiàng)的響應(yīng)函數(shù){

stophook();}voidCMainFrame::OnMenuitem32773()//“取出”選單項(xiàng)的響應(yīng)函數(shù){

intresultl=getresultl();

intresultr=getresultr();

charbuffer[80];

wsprintf(buffer,"在程序運(yùn)行期間,你共單擊鼠標(biāo)左鍵%d次,右鍵%d次!",resultl,resultr);

::MessageBox(this->m_hWnd,buffer,"message",MB_OK);}編譯這個(gè)project,并把spy.dll放到生成的可執(zhí)行文件目錄下,便可運(yùn)行程序。運(yùn)行時(shí),選擇“監(jiān)控”選單中的“啟動(dòng)”選單項(xiàng),鉤子便開始工作,監(jiān)視鼠標(biāo)的活動(dòng)情況;選擇“撤銷”選

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論