日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows 全局钩子 Hook 详解

發(fā)布時(shí)間:2024/4/19 windows 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows 全局钩子 Hook 详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

監(jiān)控程序的實(shí)現(xiàn)?
???? 我們發(fā)現(xiàn)一些木馬或其他病毒程序常常會將我們的鍵盤或鼠標(biāo)的操作消息記錄下來然后再將它發(fā)到他們指定的地方以實(shí)現(xiàn)監(jiān)聽.這種功能其他是利用了全局鉤子將鼠標(biāo)或鍵盤消息進(jìn)行了截取,從而獲得了操作的消息.要得到鼠標(biāo)和鍵盤的控制權(quán),我們要用SetWindowsHookEx這個(gè)函數(shù):?
HHOOK SetWindowsHookEx(?
?? int idHook,??????? // type of hook to install?
?? HOOKPROC lpfn,???? // address of hook procedure?
?? HINSTANCE hMod,??? // handle to application instance?
?? DWORD dwThreadId?? // identity of thread to install hook for?
);?
? ? ? ? 其中idHook是要安裝的鉤子標(biāo)識即鉤子的類型,lpfn是鉤子函數(shù)的消息處理過程,hMod是應(yīng)用程序的實(shí)例句柄,dwThreadId是要為哪個(gè)線程安裝鉤子.如果它為0則為全部線程都安裝鉤子,即為全局鉤子.這就是獲得全部應(yīng)用程序消息控制權(quán)的開始.我們安裝的鉤子類型有很多種主要是下面的:?
WH_CALLWNDPROC

WH_CALLWNDPROCRET

WH_CBTWH_DEBUG

WH_FOREGROUNDIDLE

WH_GETMESSAGE

WH_JOURNALPLAYBACK

WH_JOURNALRECORD

WH_KEYBOARD

WH_KEYBOARD_LL

WH_MOUSE

WH_MOUSE_LL

WH_MSGFILTER

WH_SHELL

WH_SYSMSGFILTER?
? ? ? ?其中WH_MOUSE是鼠標(biāo)鉤子,WH_KEYBOARD是鍵盤鉤子.?
不同的鉤子對應(yīng)不同的鉤子過程,鉤子過程的寫法(以鍵盤鉤子過程為例)是:?
LRESULT CALLBACK MouseProc(?
?? int nCode,????? // hook code?
?? WPARAM wParam,? // message identifier?
?? LPARAM lParam?? // mouse coordinates?
);?
鉤子過程的名字是沒關(guān)系的.?


要取消鉤子的安裝可以用UnhookWindowsEx:?
BOOL UnhookWindowsHookEx(?
?? HHOOK hhk?? // handle to hook procedure to remove?
);

? ? ? 下面要介紹一下如何讓每個(gè)應(yīng)用程序要安裝上鉤子函數(shù),要讓每個(gè)應(yīng)用程序都安裝上鉤子要用到動態(tài)鏈接庫的知識,利用動態(tài)鏈接庫加載到每個(gè)應(yīng)用程序中.?
? ? ? ?我們首先用VC6.0新建一個(gè)WINDOWS動態(tài)鏈接庫的空工程,新建一個(gè)頭文件為了動態(tài)鏈接庫本身和使用動態(tài)鏈接庫的應(yīng)用程序也能用,我們定義好導(dǎo)入導(dǎo)出宏和自定義消息以及要導(dǎo)入和導(dǎo)出的函數(shù)的定義:?
//HookDll.h?
// 定義函數(shù)修飾宏,方便引用本DLL工程的導(dǎo)出函數(shù)?
#ifdef KEYHOOKLIB_EXPORTS?
#define KEYHOOKLIB_API ?__declspec(dllexport)???????????????? //導(dǎo)出宏?
#else?
#define KEYHOOKLIB_API ?__declspec(dllimport)?????????????? //導(dǎo)入宏?
#endif?
? ? ? ?// 自定義與主程序通信的消息?
#define HM_KEY WM_USER + 101?????????????????? //自定義鍵盤消息?
#define HM_MOUSE WM_USER +102?????????????? //自定義鼠標(biāo)消息?
? ? ? ?// 聲明要導(dǎo)出的函數(shù)?
BOOL KEYHOOKLIB_API WINAPI SetKeyHook(BOOL bInstall,?
?????????? DWORD dwThreadId = 0, HWND hWndCaller = NULL);?
BOOL KEYHOOKLIB_API WINAPI SetMouseHook(BOOL bInstall,?
?????????? DWORD dwThreadId = 0, HWND hWndCaller = NULL

? ? ?下面再新建一個(gè)C++源文件HookDll.cpp:?
我們先包含<windows.h>頭文件?
再定義#define KEYHOOKLIB_EXPORTS讓包含"HookDll.h"的時(shí)候,我們使用的是導(dǎo)出宏,?
#include "HookDll.h"?
#pragma data_seg("YCIShared")?
? ? ? ?HWND g_hWndCaller = NULL; // 保存主窗口句柄?
? ? ? ?HHOOK g_hHook = NULL;?? // 保存鉤子句柄?
? ? ? ?HHOOK g_hMouseHook=NULL;?
#pragma data_seg()?
? ? ? ?我們上面定義了共享的全局窗口句柄和全局的鉤子標(biāo)識,是為了所有應(yīng)用程序都共享這三個(gè)變量.?
下面是鉤子函數(shù)的實(shí)現(xiàn)代碼:?

[cpp] view plaincopy print?
  • HMODULE?WINAPI?ModuleFromAddress(PVOID?pv)?//獲得鉤子函數(shù)的地址???
  • {???
  • ??????MEMORY_BASIC_INFORMATION?mbi;???
  • ?????if(::VirtualQuery(pv,?&mbi,?sizeof(mbi))?!=?0)???
  • ?????{???
  • ??????????return?(HMODULE)mbi.AllocationBase;???
  • ?????}???
  • ?????else???
  • ????{???
  • ?????????return?NULL;???
  • ????}???
  • }???
  • LRESULT?CALLBACK?KeyHookProc(int?nCode,?WPARAM?wParam,?LPARAM?lParam)//?鍵盤鉤子函數(shù)消息過程???
  • {???
  • ?????if(nCode?<?0?||?nCode?==?HC_NOREMOVE)???
  • ??????????return?::CallNextHookEx(g_hHook,?nCode,?wParam,?lParam);??
  • ?????if(lParam?&?0x40000000)?//?消息重復(fù)就交給下一個(gè)hook鏈???
  • ????{???
  • ???????return?::CallNextHookEx(g_hHook,?nCode,?wParam,?lParam);???
  • ????}??
  • ????//?通知主窗口。wParam參數(shù)為虛擬鍵碼,?lParam參數(shù)包含了此鍵的信息???
  • ????::PostMessage(g_hWndCaller,?HM_KEY,?wParam,?lParam);???//發(fā)送自定義鍵盤消息???
  • ????return?::CallNextHookEx(g_hHook,?nCode,?wParam,?lParam);???
  • }???
  • BOOL?WINAPI?SetKeyHook(BOOL?bInstall,?DWORD?dwThreadId,?HWND?hWndCaller)//?安裝、卸載鉤子的函數(shù)???
  • {???
  • ????BOOL?bOk;???
  • ????g_hWndCaller?=?hWndCaller;??
  • ????if(bInstall)???
  • ???{???
  • ???????g_hHook?=?::SetWindowsHookEx(WH_KEYBOARD,?KeyHookProc,???
  • ???????ModuleFromAddress(KeyHookProc),?dwThreadId);???????????????//安裝鍵盤鉤子???
  • ??????bOk?=?(g_hHook?!=?NULL);???
  • ???}???
  • ???else???
  • ???{???
  • ???bOk?=?::UnhookWindowsHookEx(g_hHook);???
  • ???g_hHook?=?NULL;???
  • ???}??
  • ???return?bOk;???
  • }???
  • LRESULT?CALLBACK?MouseProc(int?nCode,?WPARAM?wParam,?LPARAM?lParam)//鼠標(biāo)鉤子處理過程???
  • {???
  • ???if(nCode?<?0?||?nCode?==?HC_NOREMOVE)???
  • ???return?::CallNextHookEx(g_hMouseHook,?nCode,?wParam,?lParam);???
  • ???::PostMessage(g_hWndCaller,?HM_MOUSE,?wParam,?lParam);//發(fā)送自定義鼠標(biāo)消息???
  • ???return?::CallNextHookEx(g_hMouseHook,?nCode,?wParam,?lParam);???
  • }???
  • BOOL?WINAPI?SetMouseHook(BOOL?bInstall,?DWORD?dwThreadId,?HWND?hWndCaller)???
  • {???
  • ???BOOL?bOk;???
  • ???g_hWndCaller?=?hWndCaller;???
  • ???if(bInstall)???
  • ???{???
  • ???????g_hMouseHook?=?::SetWindowsHookEx(WH_MOUSE,?MouseProc,???
  • ???????ModuleFromAddress(MouseProc),dwThreadId);???//安裝鼠標(biāo)鉤子???
  • ???????bOk?=?(g_hMouseHook?!=?NULL);???
  • ???}???
  • ???else???
  • ??{???
  • ???????bOk?=?::UnhookWindowsHookEx(g_hMouseHook);???
  • ???????g_hMouseHook?=?NULL;???
  • ??}???
  • ?????return?bOk;???
  • }???
  • HMODULE WINAPI ModuleFromAddress(PVOID pv) //獲得鉤子函數(shù)的地址 { MEMORY_BASIC_INFORMATION mbi; if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) { return (HMODULE)mbi.AllocationBase; } else { return NULL; } } LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)// 鍵盤鉤子函數(shù)消息過程 { if(nCode < 0 || nCode == HC_NOREMOVE) return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);if(lParam & 0x40000000) // 消息重復(fù)就交給下一個(gè)hook鏈 { return ::CallNextHookEx(g_hHook, nCode, wParam, lParam); }// 通知主窗口。wParam參數(shù)為虛擬鍵碼, lParam參數(shù)包含了此鍵的信息 ::PostMessage(g_hWndCaller, HM_KEY, wParam, lParam); //發(fā)送自定義鍵盤消息 return ::CallNextHookEx(g_hHook, nCode, wParam, lParam); } BOOL WINAPI SetKeyHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller)// 安裝、卸載鉤子的函數(shù) { BOOL bOk; g_hWndCaller = hWndCaller;if(bInstall) { g_hHook = ::SetWindowsHookEx(WH_KEYBOARD, KeyHookProc, ModuleFromAddress(KeyHookProc), dwThreadId); //安裝鍵盤鉤子 bOk = (g_hHook != NULL); } else { bOk = ::UnhookWindowsHookEx(g_hHook); g_hHook = NULL; }return bOk; } LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)//鼠標(biāo)鉤子處理過程 { if(nCode < 0 || nCode == HC_NOREMOVE) return ::CallNextHookEx(g_hMouseHook, nCode, wParam, lParam); ::PostMessage(g_hWndCaller, HM_MOUSE, wParam, lParam);//發(fā)送自定義鼠標(biāo)消息 return ::CallNextHookEx(g_hMouseHook, nCode, wParam, lParam); } BOOL WINAPI SetMouseHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller) { BOOL bOk; g_hWndCaller = hWndCaller; if(bInstall) { g_hMouseHook = ::SetWindowsHookEx(WH_MOUSE, MouseProc, ModuleFromAddress(MouseProc),dwThreadId); //安裝鼠標(biāo)鉤子 bOk = (g_hMouseHook != NULL); } else { bOk = ::UnhookWindowsHookEx(g_hMouseHook); g_hMouseHook = NULL; } return bOk; }

    最后再在工程目錄下建一個(gè)HookDll.def模塊定義文件.寫上以下代碼?
    LIBRARY HookDll?
    EXPORTS???????? //指明導(dǎo)出函數(shù)名稱?
    ?? SetKeyHook?
    ?? SetMouseHook?
    SECTIONS?????? //指明共享字段?
    ?? YCIShared?? Read Write Shared?
    ? ? ? ? 用了模塊定義文件時(shí),在使用動態(tài)鏈接庫的時(shí)間就可以直接用函數(shù)名調(diào)用函數(shù)了,否則將無法找到函數(shù).其實(shí)用模塊定義文件是為了不讓動態(tài)鏈接庫發(fā)生名字改編.

    ? ? ? ?有了動態(tài)鏈接庫后我們還需要用一個(gè)應(yīng)用程序來設(shè)置和記錄我們的鼠標(biāo)和鍵盤記錄.?
    ? ? ? ?我們新建一個(gè)基于對話框的MFC應(yīng)用程序工程HookApp.我們首先為我們的自定義消息添加所需消息響應(yīng)的實(shí)現(xiàn)代碼.?
    ? ? ? 在對話框類的頭文件的protected下面的注釋宏中間加入?
    afx_msg longonHookKey(WPARAM wParam, LPARAM lParam);?
    afx_msg longonHookMouse(WPARAM wParam, LPARAM lParam);?
    ? ? ? 指明消息處理函數(shù),然后在對話框類的源文件中的?
    BEGIN_MESSAGE_MAP(CHookAppDlg, CDialog)?
    和END_MESSAGE_MAP之間加入下面的代碼?
    ? ? ?ON_MESSAGE(HM_KEY,onHookKey)?
    ? ? ?ON_MESSAGE(HM_MOUSE,onHookMouse)?
    定義好后在源文件中寫其實(shí)現(xiàn)函數(shù):?

    [cpp] view plaincopy print?
  • long?CHookAppDlg::OnHookKey(WPARAM?wParam,?LPARAM?lParam)???
  • {???
  • ??????????//?此時(shí)參數(shù)wParam為用戶按鍵的虛擬鍵碼,???
  • ??????????//?lParam參數(shù)包含按鍵的重復(fù)次數(shù)、掃描碼、前一個(gè)按鍵狀態(tài)等信息???
  • ?????????char?szKey[80];???
  • ????????::GetKeyNameText(lParam,?szKey,?80);???//獲得按鍵名???
  • ?????????CString?strItem;???
  • ?????????strItem.Format("用戶按鍵:%s",?szKey);???
  • ??????????CListBox?*pListCtrl=((CListBox?*)this->GetDlgItem(IDC_LIST1));???
  • ?????????pListCtrl->InsertString(-1,strItem);???
  • ????????CFile?MyFile;???
  • ????????char?*content;???
  • ????????if(!MyFile.Open(this->MyDocumentDir,???
  • ?????????????CFile::modeRead?|?CFile::modeWrite))???
  • ???????{???
  • ?????????????????MyFile.Open(this->MyDocumentDir,???
  • ????????????????????????????CFile::modeCreate);???
  • ????????????????return?0;???
  • ??????}???
  • ??????MyFile.SeekToEnd();?????????????????//移動記錄指針到末尾???
  • ??????pListCtrl->GetText(pListCtrl->GetCount()-1,strItem);???
  • ??????content=strItem.GetBuffer(MAX_PATH);???
  • ???????MyFile.Write(content,strItem.GetLength());???
  • ???????CTime?today=CTime::GetCurrentTime();???
  • ???????CString?str=today.Format("/t/t%Y年%m月%d日?%H:%M:%S/r/n");???
  • ??????MyFile.Write(str.GetBuffer(str.GetLength()),str.GetLength());???
  • ??????MyFile.Close();???
  • ?????return?0;???
  • }???
  • long?CHookAppDlg::OnHookMouse(WPARAM?wParam,?LPARAM?lParam)???
  • {???
  • LPMOUSEHOOKSTRUCT?pMouseHook=(MOUSEHOOKSTRUCT?FAR?*)lParam;???
  • CString?strItem,strText;???
  • ?????CListBox?*pListCtrl=((CListBox?*)this->GetDlgItem(IDC_LIST1));???
  • CPoint?point;???
  • ::GetCursorPos(&point);???
  • ClientToScreen(&point);???
  • CWnd?*pWnd=CWnd::GetForegroundWindow();???
  • if(pWnd)???
  • {???
  • ???char?str[80];???
  • ???pWnd->GetWindowText(str,80);???
  • ???strText.Format("窗口:%s",str);???
  • }???
  • CString?str;???
  • /*CString?tempstr;??
  • //???ClientToScreen(&pMouseHook->pt);??
  • ???int?x,y;??
  • ???x=pMouseHook->pt.x;??
  • ???y=pMouseHook->pt.y;??
  • ???tempstr.Format("X=%d,Y=%d",x,y);??
  • ???strText+=tempstr;*/???
  • ?????if(wParam==WM_RBUTTONDOWN)???
  • ???{???
  • ????????????str.Format("???右鍵單擊:位置?X=%d,Y=%d",point.x,point.y);???
  • ????????????strText+=str;???
  • ????????????pListCtrl->InsertString(-1,strText);???
  • ???????????this->SaveToFile(strText,pListCtrl);???
  • ??}???
  • if(wParam==WM_LBUTTONDBLCLK)???
  • {???
  • ?????ScreenToClient(&point);???
  • ???str.Format("???左鍵雙擊:位置?X=%d,Y=%d",point.x,point.y);???
  • ???strText+=str;???
  • ???pListCtrl->InsertString(-1,strText);???
  • ???this->SaveToFile(strText,pListCtrl);???
  • }???
  • if(wParam==WM_LBUTTONDOWN)???
  • {???
  • ???str.Format("???左鍵單擊:位置?X=%d,Y=%d",point.x,point.y);???
  • ???//MessageBox(strText);???
  • ???strText+=str;???
  • ???pListCtrl->InsertString(-1,strText);???
  • ???this->SaveToFile(strText,pListCtrl);???
  • }???
  • return?0;???
  • }???
  • void?CHookAppDlg::SaveToFile(CString?strText,CListBox?*pListCtrl)???
  • {???
  • char?*content;???
  • ?????CFile?MyFile;???
  • if(!MyFile.Open(this->MyDocumentDir,???
  • ???CFile::modeRead?|?CFile::modeWrite))???
  • {???
  • ???MyFile.Open(this->MyDocumentDir,???
  • ???CFile::modeCreate);???
  • ???pListCtrl->InsertString(-1,"失敗");???
  • ???return;???
  • }???
  • MyFile.SeekToEnd();???
  • content=strText.GetBuffer(strText.GetLength());???
  • MyFile.Write(content,strText.GetLength());???
  • CTime?today=CTime::GetCurrentTime();???
  • CString?strTime=today.Format("/t/t%Y年%m月%d日?%H:%M:%S/r/n");???
  • MyFile.Write(strTime.GetBuffer(strTime.GetLength()),strTime.GetLength());???
  • MyFile.Close();???
  • }???
  • long CHookAppDlg::OnHookKey(WPARAM wParam, LPARAM lParam) { // 此時(shí)參數(shù)wParam為用戶按鍵的虛擬鍵碼, // lParam參數(shù)包含按鍵的重復(fù)次數(shù)、掃描碼、前一個(gè)按鍵狀態(tài)等信息 char szKey[80]; ::GetKeyNameText(lParam, szKey, 80); //獲得按鍵名 CString strItem; strItem.Format("用戶按鍵:%s", szKey); CListBox *pListCtrl=((CListBox *)this->GetDlgItem(IDC_LIST1)); pListCtrl->InsertString(-1,strItem); CFile MyFile; char *content; if(!MyFile.Open(this->MyDocumentDir, CFile::modeRead | CFile::modeWrite)) { MyFile.Open(this->MyDocumentDir, CFile::modeCreate); return 0; } MyFile.SeekToEnd(); //移動記錄指針到末尾 pListCtrl->GetText(pListCtrl->GetCount()-1,strItem); content=strItem.GetBuffer(MAX_PATH); MyFile.Write(content,strItem.GetLength()); CTime today=CTime::GetCurrentTime(); CString str=today.Format("/t/t%Y年%m月%d日 %H:%M:%S/r/n"); MyFile.Write(str.GetBuffer(str.GetLength()),str.GetLength()); MyFile.Close(); return 0; } long CHookAppDlg::OnHookMouse(WPARAM wParam, LPARAM lParam) { LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *)lParam; CString strItem,strText; CListBox *pListCtrl=((CListBox *)this->GetDlgItem(IDC_LIST1)); CPoint point; ::GetCursorPos(&point); ClientToScreen(&point); CWnd *pWnd=CWnd::GetForegroundWindow(); if(pWnd) { char str[80]; pWnd->GetWindowText(str,80); strText.Format("窗口:%s",str); } CString str; /*CString tempstr; // ClientToScreen(&pMouseHook->pt); int x,y; x=pMouseHook->pt.x; y=pMouseHook->pt.y; tempstr.Format("X=%d,Y=%d",x,y); strText+=tempstr;*/ if(wParam==WM_RBUTTONDOWN) { str.Format(" 右鍵單擊:位置 X=%d,Y=%d",point.x,point.y); strText+=str; pListCtrl->InsertString(-1,strText); this->SaveToFile(strText,pListCtrl); } if(wParam==WM_LBUTTONDBLCLK) { ScreenToClient(&point); str.Format(" 左鍵雙擊:位置 X=%d,Y=%d",point.x,point.y); strText+=str; pListCtrl->InsertString(-1,strText); this->SaveToFile(strText,pListCtrl); } if(wParam==WM_LBUTTONDOWN) { str.Format(" 左鍵單擊:位置 X=%d,Y=%d",point.x,point.y); //MessageBox(strText); strText+=str; pListCtrl->InsertString(-1,strText); this->SaveToFile(strText,pListCtrl); } return 0; } void CHookAppDlg::SaveToFile(CString strText,CListBox *pListCtrl) { char *content; CFile MyFile; if(!MyFile.Open(this->MyDocumentDir, CFile::modeRead | CFile::modeWrite)) { MyFile.Open(this->MyDocumentDir, CFile::modeCreate); pListCtrl->InsertString(-1,"失敗"); return; } MyFile.SeekToEnd(); content=strText.GetBuffer(strText.GetLength()); MyFile.Write(content,strText.GetLength()); CTime today=CTime::GetCurrentTime(); CString strTime=today.Format("/t/t%Y年%m月%d日 %H:%M:%S/r/n"); MyFile.Write(strTime.GetBuffer(strTime.GetLength()),strTime.GetLength()); MyFile.Close(); }

    上面的代碼就是實(shí)現(xiàn)將鼠標(biāo)消息和鍵盤消息的操作消息添加到一個(gè)列表框中和記錄到一個(gè)文件上的代碼.其中this->MyDocumentDir是你要將操作消息記錄到的文件路徑.

    在對話框初始化的時(shí)候
    if(!SetKeyHook(TRUE,0, m_hWnd))
    ?? MessageBox("安裝鉤子失敗!");
    if(!SetMouseHook(TRUE,0, m_hWnd))
    ?? MessageBox("安裝鉤子失敗!");

    最后在
    void CHookAppDlg::OnDestroy()?
    {
    ::SetKeyHook(FASLE);//取消安裝鉤子
    ::SetMouseHook(FALSE);//取消安裝鉤子
    }

    ? ? ? ? ?這是鼠標(biāo)和鍵盤消息的監(jiān)聽代碼,你也可以為應(yīng)用程序安裝其他類型的鉤子.

    總結(jié)

    以上是生活随笔為你收集整理的Windows 全局钩子 Hook 详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。