久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

在VC++ 6.0下應(yīng)用Win32系統(tǒng)鉤子技術(shù)

 talentfirst1 2010-07-15
一,、引言
鉤子的本質(zhì)是一段用以處理系統(tǒng)消息的程序,,通過(guò)系統(tǒng)調(diào)用,把它掛入系統(tǒng),。鉤子的種類很多,,每種鉤子可以截獲并處理相應(yīng)的消息,每當(dāng)特定的消息發(fā)出,,在到達(dá)目的窗口之前,,鉤子程序先行截獲該消息、得到對(duì)此消息的控制權(quán),。此時(shí)鉤子函數(shù)可以對(duì)截獲的消息進(jìn)行加工處理,,甚至可以強(qiáng)制結(jié)束消息的傳遞。這有點(diǎn)類似與MFC中的PreTranslateMessage函數(shù),,所不同的是該函數(shù)只能用于攔截本進(jìn)程中的消息,,而對(duì)系統(tǒng)消息則無(wú)能為力。

二,、Win32系統(tǒng)鉤子的實(shí)現(xiàn)
每種類型的鉤子均由系統(tǒng)來(lái)維護(hù)一個(gè)鉤子鏈,,最近安裝的鉤子位于鏈的開(kāi)始,擁有最高的優(yōu)先級(jí),,而最先安裝的鉤子則處在鏈的末尾,。要實(shí)現(xiàn)Win32的系統(tǒng)鉤子,首先要調(diào)用SDK中的API函數(shù)SetWindowsHookEx來(lái)安裝這個(gè)鉤子函數(shù),,其原型是:
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
其中,,第一個(gè)參數(shù)是鉤子的類型,常用的有WH_MOUSE,、WH_KEYBOARD,、WH_GETMESSAGE等;第二個(gè)參數(shù)是鉤子函數(shù)的地址,,當(dāng)鉤子鉤到任何消息后便調(diào)用這個(gè)函數(shù),;第三個(gè)參數(shù)是鉤子函數(shù)所在模塊的句柄;第四個(gè)參數(shù)是鉤子相關(guān)函數(shù)的ID用以指定想讓鉤子去鉤哪個(gè)線程,,為0時(shí)則攔截整個(gè)系統(tǒng)的消息此時(shí)為全局鉤子,。如果指定確定的線程,,即為線程專用鉤子。
全局鉤子函數(shù)必須包含在DLL(動(dòng)態(tài)鏈接庫(kù))中,,而線程專用鉤子則可包含在可執(zhí)行文件中,。得到控制權(quán)的鉤子函數(shù)在處理完消息后,可以調(diào)用另外一個(gè)SDK中的API函數(shù)CallNextHookEx來(lái)繼續(xù)傳遞該消息,。也可以通過(guò)直接返回TRUE來(lái)丟棄該消息,,阻止該消息的傳遞。
使用全局鉤子函數(shù)時(shí)需要以DLL為載體,,VC6中有三種形式的MFC DLL可供選擇,,即Regular statically linked to MFC DLL(標(biāo)準(zhǔn)靜態(tài)鏈接MFC DLL)、Regular using the shared MFC DLL(標(biāo)準(zhǔn)動(dòng)態(tài)鏈接MFC DLL)以及Extension MFC DLL(擴(kuò)展MFC DLL),。第一種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程序使用,。

三、Win32 DLL
Win32 DLL的入口和出口函數(shù)都是DLLMain這同Win16 DLL是有區(qū)別的,。只要有進(jìn)程或線程載入和卸載DLL時(shí),,都會(huì)調(diào)用該函數(shù),其原型是:
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);
其中,,第一個(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ù)中可以通過(guò)對(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,。

四、全局共享數(shù)據(jù)的實(shí)現(xiàn)
可以用#pragma data_seg建立一個(gè)新的數(shù)據(jù)段并定義共享數(shù)據(jù),,其具體格式為:
#pragma data_seg ("shareddata")
HWND sharedwnd=NULL;//共享數(shù)據(jù)
#pragma data_seg()
所有在data_seg pragmas語(yǔ)句之間聲明的變量都將在shareddata段中,。僅定義一個(gè)數(shù)據(jù)段還不能達(dá)到共享數(shù)據(jù)的目的,還要告訴編譯器該段的屬性,,有兩種方法可以實(shí)現(xiàn)該目的(其效果是相同的),,一種方法是在.DEF文件中加入如下語(yǔ)句:
SETCTIONS
shareddata READ WRITE SHARED
另一種方法是在項(xiàng)目設(shè)置鏈接選項(xiàng)中加入如下語(yǔ)句:
/SECTION:shareddata,rws 

五、鼠標(biāo)鉤子程序示例
本示例程序用到全局鉤子函數(shù),,程序分兩部分:可執(zhí)行程序MouseDemo和動(dòng)態(tài)連接庫(kù)MouseHook,。首先編制MFC擴(kuò)展動(dòng)態(tài)連接庫(kù)MouseHook.dll:
(一)選擇MFC AppWizard(DLL)創(chuàng)建項(xiàng)目Mousehook;
(二)選擇MFC Extension DLL(MFC擴(kuò)展DLL)類型,;
(三)通過(guò)Project菜單的AddToProject子菜單的"New…"添加頭文件MouseHook.h,。
(四)在頭文件中建立鉤子類:
class AFX_EXT_CLASS CMouseHook:public CObject
{
public:
CMouseHook();  //鉤子類的構(gòu)造函數(shù)
~CMouseHook();  //鉤子類的析構(gòu)函數(shù)
BOOL StartHook(HWND hWnd);   //安裝鉤子函數(shù)
BOOL StopHook();    //卸載鉤子函數(shù)
};
(五)在MouseHook.cpp文件中加入#include"MouseHook.h"語(yǔ)句;
(六)加入全局共享數(shù)據(jù)變量:
#pragma data_seg("mydata")
HWND glhPrevTarWnd=NULL;  //上次鼠標(biāo)所指的窗口句柄
HWND glhDisplayWnd=NULL;  //顯示目標(biāo)窗口標(biāo)題編輯框的句柄
HHOOK glhHook=NULL;   //安裝的鼠標(biāo)勾子句柄
HINSTANCE glhInstance=NULL; //DLL實(shí)例句柄
#pragma data_seg()
(七)在DEF文件中定義段屬性:
SECTIONS
mydata READ WRITE SHARED
(八)在主文件MouseHook.cpp的DllMain函數(shù)中加入保存DLL實(shí)例句柄的語(yǔ)句:
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
if (!AfxInitExtensionModule(MouseHookDLL, hInstance))
return 0;
new CDynLinkLibrary(MouseHookDLL);
glhInstance=hInstance;    //插入保存DLL實(shí)例句柄
}
else if (dwReason == DLL_PROCESS_DETACH)
{
AfxTermExtensionModule(MouseHookDLL);
}
return 1; // ok
}
這個(gè)函數(shù)最重要的部分是調(diào)用AfxInitExtensionModule(),,它初始化DLL使它在MFC框架中正確的工作,。它需要傳遞給DllMain()的DLL實(shí)例句柄和AFX_EXTENSION_MODULE結(jié)構(gòu),結(jié)構(gòu)中存在著對(duì)MFC有用的信息,。
(九) 類CMouseHook的成員函數(shù)的具體實(shí)現(xiàn):
Cmousehook::Cmousehook() //類構(gòu)造函數(shù)
{
}
Cmousehook::~Cmousehook() //類析構(gòu)函數(shù)
{
stophook();
}
BOOL Cmousehook::starthook(HWND hWnd)  //安裝鉤子并設(shè)定接收顯示窗口句柄
{
BOOL bResult=FALSE;
glhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);
if(glhHook!=NULL)
bResult=TRUE;
glhDisplayWnd=hWnd;  //設(shè)置顯示目標(biāo)窗口標(biāo)題編輯框的句柄
return bResult;
}
BOOL Cmousehook::stophook()  //卸載鉤子
{
BOOL bResult=FALSE;
if(glhHook)
{
bResult= UnhookWindowsHookEx(glhHook);
if(bResult)
{
glhPrevTarWnd=NULL;
glhDisplayWnd=NULL;//清變量
glhHook=NULL;
}
}
return bResult;
}
(十) 鉤子函數(shù)的實(shí)現(xiàn)
LRESULT WINAPI MouseProc(int nCode,WPARAM wparam,LPARAM lparam)
{
LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *) lparam;
if (nCode>=0)
{
HWND glhTargetWnd=pMouseHook->hwnd;  //取目標(biāo)窗口句柄
HWND ParentWnd=glhTargetWnd;
while (ParentWnd !=NULL)
{
glhTargetWnd=ParentWnd;
ParentWnd=GetParent(glhTargetWnd); //取應(yīng)用程序主窗口句柄
}
if(glhTargetWnd!=glhPrevTarWnd)
{
char szCaption[100];
GetWindowText(glhTargetWnd,szCaption,100); //取目標(biāo)窗口標(biāo)題
if(IsWindow(glhDisplayWnd))
SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption);
glhPrevTarWnd=glhTargetWnd;   //保存目標(biāo)窗口
}
}
return CallNextHookEx(glhHook,nCode,wparam,lparam); //繼續(xù)傳遞消息
}
編譯完成便可得到運(yùn)行時(shí)所需的鼠標(biāo)鉤子的動(dòng)態(tài)連接庫(kù)MouseHook.dll和鏈接時(shí)用到的MouseHook.lib,。 

六、集成
下面新建一調(diào)用鼠標(biāo)鉤子動(dòng)態(tài)連接庫(kù)的鉤子可執(zhí)行程序:
(一) 用MFC的AppWizard(EXE)創(chuàng)建項(xiàng)目MouseDemo,;
(二) 選擇"基于對(duì)話應(yīng)用",,其余幾步均為確省,;
(三) 在對(duì)話框上加入一個(gè)編輯框IDC_EDIT1,;
(四) 在MouseDemo.h中加入對(duì)Mousehook.h的包含語(yǔ)句:#Include"Mousehook.h",;
(五) 在CMouseDemoDlg.h的CMouseDemoDlg類定義中添加私有數(shù)據(jù)成員:CMouseHook m_hook;
(六) 在OnInitDialog函數(shù)的"TODO注釋"后添加:
CWnd * pwnd=GetDlgItem(IDC_EDIT1);  //取得編輯框的類指針
m_hook.StartHook(pwnd->GetSafeHwnd()); //取得編輯框的窗口句柄并安裝鉤子
(七)鏈接DLL庫(kù),即把Mousehook.lib加入到項(xiàng)目設(shè)置鏈接標(biāo)簽中,;
(八)把MouseHook.h和MouseHook.lib復(fù)制到MouseDemo工程目錄中,,MouseHook.dll復(fù)制到Debug目錄下。編譯執(zhí)行程序即可,。當(dāng)鼠標(biāo)滑過(guò)窗口時(shí)便會(huì)在編輯框中將此窗口的標(biāo)題顯示出來(lái),。

結(jié)論:
系統(tǒng)鉤子具有相當(dāng)強(qiáng)大的功能,通過(guò)這種技術(shù)可以對(duì)幾乎所有的Windows系統(tǒng)消息進(jìn)行攔截,、監(jiān)視,、處理。這種技術(shù)可以廣泛應(yīng)用于各種軟件,,尤其是需要有監(jiān)控,、自動(dòng)記錄等對(duì)系統(tǒng)進(jìn)行監(jiān)測(cè)功能的軟件。本程序只對(duì)鼠標(biāo)消息進(jìn)行攔截,,相應(yīng)的也可以在Win32環(huán)境下對(duì)鍵盤(pán),、端口等應(yīng)用此技術(shù)完成特定的功能。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多