


版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
在Windows系統(tǒng)中用VC++實現(xiàn)鉤子機制
摘要:本文分析了在Windows環(huán)境下,什么是鉤子程序以及怎樣用VC++實現(xiàn)一個鉤子機制的關(guān)鍵技術(shù)。最后,用一個可以截獲鼠標信息的完整程序說明了這些問題。關(guān)鍵詞:鉤子程序,DLL,消息截獲一.
什么是鉤子。Windows系統(tǒng)是建立在事件驅(qū)動的機制上的,說穿了就是整個系統(tǒng)都是通過消息的傳遞來實現(xiàn)的。鉤子(hook)是一種特殊的消息處理機制,鉤子可以監(jiān)視系統(tǒng)或進程中的各種事件消息,截獲發(fā)往目標窗口的消息并進行處理。這樣,我們就可以在系統(tǒng)中安裝自定義的鉤子,監(jiān)視系統(tǒng)中特定事件的發(fā)生,完成特定的功能,比如截獲鍵盤、鼠標的輸入,屏幕取詞,日志監(jiān)視等等。鉤子的種類很多,每種鉤子可以截獲并處理相應(yīng)的消息,如鍵盤鉤子可以截獲鍵盤消息,外殼鉤子可以截取、啟動和關(guān)閉應(yīng)用程序的消息等。鉤子可以分為線程鉤子和系統(tǒng)鉤子,線程鉤子監(jiān)視指定線程的事件消息,系統(tǒng)鉤子監(jiān)視系統(tǒng)中的所有線程的事件消息。因為系統(tǒng)鉤子會影響系統(tǒng)中所有的應(yīng)用程序,所以鉤子函數(shù)必須放在獨立的動態(tài)鏈接庫(DLL)中。二.
實現(xiàn)鉤子機制的幾個關(guān)鍵技術(shù)。1.
windows的鉤子程序,需要用到幾個sdk中的api函數(shù)。下面列出這幾個函數(shù)的原型及說明:hhooksetwindowshookex(intidhook,hook_proclpfn,hinstancehmod,dworddwthreadid);參數(shù)說明如下:
idhook:鉤子的類型
lpfn:鉤子處理函數(shù)地址
hmod:包含鉤子函數(shù)的模塊句柄
dwthreadid:鉤子的監(jiān)控線程函數(shù)說明:函數(shù)將在系統(tǒng)中掛上一個由idhook指定類型的鉤子,監(jiān)控并處理相應(yīng)的特定消息。boolunhookwindowshookex(hhookhhk);函數(shù)說明:函數(shù)將撤銷由hhk指定的鉤子。lresultcallnexthookex(hhookhhk,intncode,wparamwparam,lparamlparam);函數(shù)說明:函數(shù)將消息向下傳遞,下一個鉤子處理將截獲這一消息。2.
由于鉤子的處理涉及到模塊及進程間的數(shù)據(jù)地址問題,一般情況是把鉤子整合到一個動態(tài)鏈接庫(dll)中,VC中有三種形式的MFCDLL可供選擇,即RegularstaticallylinkedtoMFCDLL(標準靜態(tài)鏈接MFCDLL)、RegularusingthesharedMFCDLL(標準動態(tài)鏈接MFCDLL)以及ExtensionMFCDLL(擴展MFCDLL)。第一種DLL在編譯時把使用的MFC代碼鏈接到DLL中,執(zhí)行程序時不需要其他MFC動態(tài)鏈接類庫的支持,但體積較大;第二種DLL在運行時動態(tài)鏈接到MFC類庫,因而體積較小,但卻依賴于MFC動態(tài)鏈接類庫的支持;這兩種DLL均可被MFC程序和Win32程序使用。第三種DLL的也是動態(tài)連接,但做為MFC類庫的擴展,只能被MFC程序使用。另外,要設(shè)立一個全局數(shù)據(jù)共享數(shù)據(jù)段,以存貯一些全局變量,保留上次鉤子消息事件發(fā)生時的狀態(tài)。3.
Win32DLL的入口和出口函數(shù)都是DLLMain。只要有進程或線程載入和卸載DLL時,都會調(diào)用該函數(shù),其原型是:BOOLWINAPIDllMain(HINSTANCEhinstDLL,DWORDfdwReason,LPVOIDlpvReserved);其中,第一個參數(shù)表示DLL的實例句柄;第三個參數(shù)系統(tǒng)保留;第二個參數(shù)指明了當(dāng)前調(diào)用該動態(tài)連接庫的狀態(tài),它有四個可能的值:DLL_PROCESS_ATTACH(進程載入)、DLL_THREAD_ATTACH(線程載入)、DLL_THREAD_DETACH(線程卸載)、DLL_PROCESS_DETACH(進程卸載)。在DLLMain函數(shù)中可以通過對傳遞進來的這個參數(shù)的值進行判別,根據(jù)不同的參數(shù)值對DLL進行必要的初始化或清理工作。由于在Win32環(huán)境下,所有進程的空間都是相互獨立的,這減少了應(yīng)用程序間的相互影響,但大大增加了編程的難度。當(dāng)進程在動態(tài)加載DLL時,系統(tǒng)自動把DLL地址映射到該進程的私有空間,而且也復(fù)制該DLL的全局數(shù)據(jù)的一份拷貝到該進程空間,每個進程所擁有的相同的DLL的全局數(shù)據(jù)其值卻并不一定是相同的。當(dāng)DLL內(nèi)存被映射到進程空間中,每個進程都有自己的全局內(nèi)存拷貝,加載DLL的每一個新的進程都重新初始化這一內(nèi)存區(qū)域,也就是說進程不能再共享DLL。因此,在Win32環(huán)境下要想在多個進程中共享數(shù)據(jù),就必須進行必要的設(shè)置。一種方法便是把這些需要共享的數(shù)據(jù)單獨分離出來,放置在一個獨立的數(shù)據(jù)段里,并把該段的屬性設(shè)置為共享,建立一個內(nèi)存共享的DLL。三.
用鉤子機制實現(xiàn)截獲鼠標左右鍵按壓次數(shù)。建立鉤子程序時需要把鉤子處理整合到動態(tài)鏈接庫中,所以例程中需要建立兩個project。1.
鉤子處理動態(tài)鏈接庫(1)
選擇mfcappwizard(dll)創(chuàng)建一個新project,命名為“spy”。(2)
選擇mfcextensiondll類型。(3)
創(chuàng)建一個新的頭文件,命名為“hook.h”,修改它的代碼如下:extern"C"LRESULTCALLBACKmouseproc(intcode,WPARAMwparam,LPARAMlparam);//鉤子處理函數(shù)extern"C"boolWINAPIstarthook();//啟動鉤子函數(shù)extern"C"boolWINAPIstophook();//撤銷鉤子函數(shù)extern"C"intWINAPIgetresultl();//取得鼠標左鍵單擊次數(shù)的函數(shù)extern"C"intWINAPIgetresultr();//取得鼠標右鍵單擊次數(shù)的函數(shù)(4)
修改spy.cpp程序代碼如下:#include"hook.h"
//包含頭文件hook#pragmadata_seg("publicdata")//定義全局數(shù)據(jù)段HHOOKhhook=NULL;//鉤子句柄HINSTANCEpinstance=NULL;//鉤子模塊句柄UINTmouseclickl=0;//記錄鼠標左鍵單擊次數(shù)的變量UINTmouseclickr=0;//記錄鼠標右鍵單擊次數(shù)#pragmadata_seg()extern"C"intAPIENTRYDllMain(HINSTANCEhInstance,DWORDdwReason,LPVOIDlpReserved)
{if(dwReason==DLL_PROCESS_ATTACH)
{……
//省略部分機器生成代碼
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++;//記錄鼠標左鍵單擊次數(shù)
}
if(wparam==WM_RBUTTONDOWN)
{
mouseclickr++;//記錄鼠標右鍵單擊次數(shù)
}
returnCallNextHookEx(hhook,code,wparam,lparam);}extern"C"boolWINAPIstarthook()//啟動鉤子函數(shù){
hhook=SetWindowsHookEx(WH_MOUSE,mouseproc,pinstance,0);//掛上鉤子
if(hhook!=NULL)returntrue;
elsereturnfalse;}extern"C"boolWINAPIstophook()//撤銷鉤子函數(shù){
returnUnhookWindowsHookEx(hhook);//撤銷鉤子}extern"C"intWINAPIgetresultl()//返回鼠標左鍵單擊次數(shù){
returnmouseclickl;}extern"C"intWINAPIgetresultr()//返回鼠標右鍵單擊次數(shù){
returnmouseclickr;}
(5)
修改spy.def程序代碼如下:
exportsstophook@2starthook@1getresultl@3getresultr@4(6)編譯project,生成spy.dll文件和spy.lib文件。2.
建立使用鉤子的應(yīng)用程序(1)
生成一個單文檔的可執(zhí)行文件(exe)的project。(2)
修改資源中的主選單,增加一個選單項“監(jiān)控”,下有三個子選單項,分別為“啟動”、“撤銷”和“取出”。(3)
在project中加入spy.lib文件。(4)
分別修改“啟動”、“撤銷”和“取出”選單項的command響應(yīng)函數(shù)如下:#include"E:\DevStudio\MyProjects\spy\hook.h"http://路徑可不同voidCMainFrame::OnMenuitem32771()//“啟動”選單項的響應(yīng)函數(shù){
starthook();}voidCMainFrame::OnMenuitem32772()//“撤銷”選單項的響應(yīng)函數(shù){
stophook();}voidCMainFrame::OnMenuitem32773()//“取出”選單項的響應(yīng)函數(shù){
intresultl=getresultl();
intresultr=getresultr();
charbuffer[80];
wsprintf(buffer,"在程序運行期間,你共單擊鼠標左鍵%d次,右鍵%d次!",resultl,resultr);
::MessageBox(this->m_hWnd,buffer,"message",MB_OK);}編譯這個project,并把spy.dll放到生成的可執(zhí)行文件目錄下,便可運行程序。運行時,選擇“監(jiān)控”選單中的“啟動”選單項,鉤子便開始工作,監(jiān)視鼠標的活動情況;選擇“撤銷”選
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)療物資采購風(fēng)險管理與控制
- 代買貨物合同范例
- 買賣門市定金合同范例
- 2025年小學(xué)班主任工作總結(jié)經(jīng)驗教訓(xùn)總結(jié)模版
- 買賣大型設(shè)備合同范例
- 公司配件采購合同范例
- 廣電工作者個人年度工作總結(jié)模版
- 人口健康信息分析與教育引導(dǎo)
- erp系統(tǒng)維護合同范例
- 專職教室聘用合同范例
- GB/T 11032-2020交流無間隙金屬氧化物避雷器
- 煤礦爆破工培訓(xùn)
- 液化石油氣安全標簽
- 水車租賃合同范本(3篇)
- 空港新城特勤消防站施工組織設(shè)計
- 北師大版三年級數(shù)學(xué)下冊競賽卷
- 2022山東歷史高考答題卡word版
- 中醫(yī)醫(yī)院兒科建設(shè)與管理指南(試行)
- Q∕SY 1143-2008 三維地質(zhì)建模技術(shù)要求
- 大地構(gòu)造學(xué)派及其構(gòu)造單元匯總
- 麗聲北極星分級繪本第二級上Dinner for a Dragon 課件
評論
0/150
提交評論