利用鍵盤鉤子捕獲Windows鍵盤動作

來源:互聯網
上載者:User

引言

  在科研生產中對研製、調試操作的記錄是非常有必要而且是有很重要價值的。通過對記錄資訊的分析,可以在事故發生後準確的分析出事故的起因、操作是否存在失誤等許多重要線索。通常需要記錄的資訊是多種多樣的,如環境溫度記錄、軟體運行記錄、檔案訪問記錄等等。這裡將以鍵盤資訊記錄為例來講述類似的實驗資訊自動記錄的一般實現方法。

  由於需要記錄當前系統下所有應用程式的鍵盤錄入記錄,因此必須採取某種特殊的技術來實現本進程(監視程式)對外部進程鍵盤操作資訊的擷取。這種技術便是本文將要論述的核心--系統全域鉤子。本文下面將對Win32平台下全域鉤子的運行機制進行介紹並給出了一個具體的由VC++6.0編寫的捕獲鍵盤動作的鍵盤鉤子樣本程式。 

  系統鉤子和DLL

  鉤子的本質是一段用以處理系統訊息的程式,通過系統調用,將其掛入系統。鉤子的種類有很多,每種鉤子可以截獲並處理相應的訊息,每當特定的訊息發出,在到達目的視窗之前,鉤子程式先行截獲該訊息、得到對此訊息的控制權。此時在鉤子函數中就可以對截獲的訊息進行加工處理,甚至可以強制結束訊息的傳遞。

  在本程式中我們需要捕獲在任意視窗上的鍵盤輸入,這就需要採用全域鉤子以便攔截整個系統的訊息,而全域鉤子函數必須以DLL(動態串連庫)為載體進行封裝,VC6中有三種形式的MFC DLL可供選擇,即Regular statically linked to MFC DLL(標準靜態連結MFC DLL)、Regular using the shared MFC DLL(標準動態連結MFC DLL)以及Extension MFC DLL(擴充MFC DLL)。 在本程式中為方便起見採用了標準靜態串連MFC DLL。

  鍵盤鉤子程式樣本

  本樣本程式用到全域鉤子函數,程式分兩部分:可執行程式KeyKook和動態串連庫LaunchDLL。首先建立一個MFC AppWizard(DLL)工程,並選擇Regular statically linked to MFC DLL(標準靜態連結MFC DLL)選項,以建立MFC擴充動態串連庫LaunchDLL.dll。之後,在相應的標頭檔中添加宏定義和待匯出函數的聲明: 

#define DllExport __declspec(dllexport)
……
DllExport void WINAPI InstallLaunchEv();
……
class CLaunchDLLApp : public CWinApp
{
 public:
  CLaunchDLLApp();
  //{{AFX_VIRTUAL(CLaunchDLLApp)
  //}}AFX_VIRTUAL
  //{{AFX_MSG(CLaunchDLLApp)
  // NOTE - the ClassWizard will add and remove member functions here.
  // DO NOT EDIT what you see in these blocks of generated code !
  //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};


  同時在實現檔案中添加全域變數Hook和全域函數LauncherHook()、SaveLog():

HHOOK Hook;
LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam);
void SaveLog(char* c);


  最後,完成以上提到的這幾個函數的具體編碼實現:

CLaunchDLLApp theApp;
……
DllExport void WINAPI InstallLaunchEv()
{
 Hook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)LauncherHook,theApp.m_hInstance,0);
}


  在此我們實現了Windows的系統鉤子的安裝,首先要調用SDK中的API函數SetWindowsHookEx()來安裝這個鉤子函數,其原型是: 

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


  其中,第一個參數指定鉤子的類型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等,在此我們只關心鍵盤操作所以設定為WH_KEYBOARD;第二個參數標識鉤子函數的入口地址,當鉤子鉤到任何訊息後便調用這個函數,即當不管系統的哪個視窗有鍵盤輸入馬上會引起LauncherHook的動作;第三個參數是鉤子函數所在模組的控制代碼,我們可以很簡單的設定其為本應用程式的執行個體控制代碼;最後一個參數是鉤子相關函數的ID用以指定想讓鉤子去鉤哪個線程,為0時則攔截整個系統的訊息,在本程式中鉤子需要為全域鉤子,故設定為0。

LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam)
{
 LRESULT Result=CallNextHookEx(Hook,nCode,wParam,lParam);
 if(nCode==HC_ACTION)
 {
  if(lParam & 0x80000000)
  {
   char c[1];
   c[0]=wParam;
   SaveLog(c);
  }
 }
 return Result;
}


  雖然調用CallNextHookEx()是可選的,但調用此函數的習慣是很值得推薦的;否則的話,其他安裝了鉤子的應用程式將不會接收到鉤子的通知而且還有可能產生不正確的結果,所以我們應盡量調用該函數除非絕對需要阻止其他程式擷取通知。 

void SaveLog(char* c)
{
 CTime tm=CTime::GetCurrentTime();
 CString name;
 name.Format("c:\\Key_%d_%d.log",tm.GetMonth(),tm.GetDay());
 CFile file;
 if(!file.Open(name,CFile::modeReadWrite))
 {
  file.Open(name,CFile::modeCreate|CFile::modeReadWrite);
 }
 file.SeekToEnd();
 file.Write(c,1);
 file.Close();
}


  當有鍵彈起的時候就通過此函數將剛彈起的鍵儲存到記錄檔案中從而實現對鍵盤進行監控記錄的目的。編譯完成便可得到運行時所需的鍵盤鉤子的動態串連庫和進行靜態連結時用到的lib庫。

  下面開始編寫調用此動態串連庫的主程式,並實現最後的整合。另外建立一個單文檔應用程式,把所需的動態連結程式庫標頭檔、lib庫複製到工程目錄中,將動態連結程式庫複製到Debug目錄下。然後連結DLL庫:在"Project","Settings…"的"Link"屬性頁面內,在"Object/librarymodules:"中填入"LaunchDLL.lib"。再通過"Project","Add To Project","Files…"將LaunchDLL.h添加到工程中來,最後在視類的源檔案KeyHook.cpp中加入對其的引用:

#include "LaunchDLL.h"


  這樣我們就可以象使用本工程內的 函數一樣使用動態串連庫LaunchDLL.dll中的所有匯出函數了。接下來在視類重載虛函數OnInitialUpdate(),並添加程式碼完成對鍵盤鉤子的安裝:

InstallLaunchEv();


  到此為止其實已經完成了所有的功能,但由於本程式是作為一個後台監視軟體運行,因此還應當採取其他措施以隱藏其程式介面。這隻需在應用程式類CkeyHookApp的InitInstance()函數中將m_pMainWnd->ShowWindow(SW_SHOW)改為m_pMainWnd->ShowWindow(SW_HIDE)即可。

  小結

  編譯運行程式,運行起來之後並無什麼現象,但通過Alt+Ctrl+Del在關閉程式對話方塊內可以找到我們剛編寫完畢的程式"KeyHook",隨便在什麼程式中通過鍵盤輸入字元,然後開啟記錄檔案,我們會發現:通過鍵盤鉤子,我們剛才輸入的字元都被記錄到記錄檔案中了。系統鉤子具有相當強大的功能,通過這種技術可以對幾乎所有的Windows系統訊息進行攔截、監視、處理。這種技術廣泛應用於各種自動監控系統中。本文所述程式在Windows 2000 Professional + SP4下由Microsoft Visual C++ 6.0編譯調試通過。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.