程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 鉤子的應用:程序運行監視

鉤子的應用:程序運行監視

編輯:C語言基礎知識
 作者:Victor Chen
   來自:C++ 愛好者
   http://www.cppfans.com
  
   --------------------------------------------------------------------------------
  
   程序介紹:
  
   利用這個程序:
   1.可以監視在你的電腦運行的程序, 把在你的電腦運行過的程序的時間和名字記錄下來;
   2.可以阻止你規定的禁用程序的執行, 比如不讓玩游戲。
   3.這個程序需要加入注冊表, 在系統啟動時就運行, 達到監視的目的。注冊表大概都不生疏,就是這裡:
   HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun
  
   程序的記錄格式:
  
   2003-02-03 17:31:25 - [System Startup - Windows XP 5.01.2600]
   2003-02-03 17:31:29 "CabinetWClass" -> "我的電腦"
   2003-02-03 17:31:59 "Red Alert" -> "Red Alert" (關閉禁用程序)
   2003-02-03 17:32:19 "掃雷" -> "掃雷" (關閉禁用程序)
   2003-02-03 17:32:35 "OpusApp" -> "Microsoft Word"
   2003-02-03 17:32:50 - [System Shutdown - 0 days, 0 hrs, 1 mins, 25 secs]
  
   2003-02-03 17:35:37 - [System Startup - Windows 98 SE 4.10.2222]
   2003-02-03 17:35:53 "掃雷" -> "掃雷" (關閉禁用程序)
   2003-02-03 17:36:05 "CabinetWClass" -> ""
   2003-02-03 17:36:31 "Red Alert" -> "Red Alert" (關閉禁用程序)
   2003-02-03 17:36:56 "ExploreWClass" -> ""
   2003-02-03 17:37:07 - [System Shutdown - 0 days, 0 hrs, 1 mins, 30 secs]
  
   程序運行只需要3個文件:
   hwhpapp.exe 可執行文件
   hwhpdrv.dll 安裝鉤子的動態鏈接庫
   hwhpapp.cfg 禁用軟件黑名單, 可用記事本修改
   程序運行會自動產生記錄文件:
   hwhpapp.sys 可以用記事本打開看
  
   程序原理:
  
   一.鉤子
   利用 API 函數 SetWindowsHookEx() 安裝一個全局鉤子, 鉤子類型為 WH_SHELL。
   WH_SHELL 鉤子可監視所有應用程序的主窗口創建或者關閉。
   最典型的應用就是 Windows 的狀態欄,當程序運行時,把主窗口的標題加入狀態欄,程序退出時,從狀態欄刪除。
   假如你截獲這個鉤子,可以做到禁止狀態欄的顯示,也可以自己作一個狀態欄,或者作一個歷史記錄,把所有在你電腦曾經運行的程序記錄下來。假如運行的程序不是你希望的,你可以直接關閉這個程序,達到禁止運行的目的。
  
   二.動態鏈接庫
   由於鉤子是全局的,必須把這個鉤子定義到 .DLL 的動態鏈接庫裡,這就涉及到建立動態鏈接庫。
  
   三.共享內存
   由於鉤子是安裝到系統裡的,鉤子的運行是在操作系統裡面,因此這個鉤子不能使用你的程序所定義的任何全局變量!
   既然如此,有什麼辦法解決呢?在本程序裡利用共享內存技術,利用 API 函數 CreateFileMapping() 可創建共享內存,這個內存可以在任何運行的程序中使用,也就是說任何運行的 .EXE、.DLL 和其他程序都可以使用這塊內存。在本程序中直接使用了 Victor 串口 VCL 控件裡的 TSharedMemory 共享內存類。
  
  
   四.記錄文件和軟件黑名單文件
   把所有在你的電腦執行的程序記錄保存在一個文本文件裡, 因為擴展名為 .txt 很輕易被發現,因此采用擴展名 .sys
   軟件黑名單文件保存在 .cfg 文件裡,同樣因為 .ini 文件很輕易發現並且打開修改。
   這兩個文件都保存在與你的 .exe 文件的相同文件夾裡,並且與 .exe 文件同名.
  
   五.保證你的程序只能同時運行一個
   假如你同時運行兩個程序,記錄文件就會亂套,所以必須保證只能運行一個。
   當你的程序剛開始運行的時候,就是在 WinMain() 函數的最開始,就要判定是否已經運行了,假如已經運行,就直接退出。
   判定的方法很簡單,就是檢查程序共享的內存是否存在,假如檢查到共享的內存已經存在,那就是已經運行了。
  
   六.程序隱身, 不能顯示在任務欄和任務治理器裡面
   這個也很簡單,只要在主程序的 Application->Run(); 前面加一句話:
   SetWindowLong(Application->Handle, GWL_EXSTYLE, GetWindowLong(Application->Handle, GWL_EXSTYLE)WS_EX_TOOLWINDOW);
   就可以了。
  
  
   --------------------------------------------------------------------------------
  
   程序介紹
   .DLL 文件:這是最要害的鉤子的代碼:
  
   #include <vcl.h>
   #include "yb_base.h" //Victor 串口控件裡面的一個頭文件
  
   #define MYAPPMARK "VICTOR_APPMONI_20010612" //共享內存標志
  
   class __export THookedProcs
   {
       public:
           THookedProcs();
           ~THookedProcs();
           void WINAPI InitFuncs(void);
           void WINAPI UninitFuncs(void);
       private:
           HHOOK hThisHook; //保存鉤子的句柄
           static LRESULT CALLBACK HookedShellProc(int nCode, WPARAM wParam, LPARAM lParam);
   };
  
   //定義共享的數據結構
   typedef strUCt
   {
      HHOOK hHook; //當前使用的 HOOK
   //... 此處可增加其他共享的數據
   } THookSharedData;
  
   THookedProcs::THookedProcs()
   {
      hThisHook = NULL;
   }
  
   THookedProcs::~THookedProcs()
   {
       UninitFuncs();
   }
  
   void WINAPI THookedProcs::InitFuncs(void)
   {
       UninitFuncs();
       hThisHook = SetWindowsHookEx(WH_SHELL, (HOOKPROC) HookedShellProc, HInstance, 0);
       TSharedMemory AppMem(MYAPPMARK,4096); //在 EXE 文件裡共享的內存
       THookSharedData *HookSharedData = ((THookSharedData*)(AppMem.AppInfo->Data)); //共享的數據
       HookSharedData->hHook = hThisHook; //把 hThisHook 保存到共享內存裡
   }
  
   void WINAPI THookedProcs::UninitFuncs(void)
   {
       if(hThisHook)
       {
          
   UnhookWindowsHookEx(hThisHook);
           hThisHook = NULL;
       }
   }
  
   LRESULT CALLBACK THookedProcs::HookedShellProc(int nCode, WPARAM wParam, LPARAM lParam)
   {
       TSharedMemory AppMem(MYAPPMARK, 4096); //使用在 .EXE 文件裡共享的內存
       if(AppMem.Valid)if(AppMem.Exists) //假如共享內存存在
       {
           HWND hMainWnd = AppMem.AppInfo->hMainForm;
  
           if(hMainWnd)
           {
               if(nCode==HSHELL_WINDOWCREATED)
               {
                   PostMessage(hMainWnd, WM_USERCMD, UC_WINHOOK, wParam);
               }
           }
       }
       //在 Hook 裡無法調用 hThisHook, 必須用共享內存裡面的 hHook
       THookSharedData *HookSharedData = ((THookSharedData*)(AppMem.AppInfo->Data)); //共享的數據
       return CallNextHookEx(HookSharedData->hHook, nCode, wParam, lParam);
   }
  
   --------------------------------------------------------------------------------
  
   EXE文件主程序的代碼:
  
   WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR lpCmdLine, int)
   {
       if(!AppMem.Valid)
       {
           return 1;
       }
       if(AppMem.Exists) //已經存在 (程序以前已經運行過了,
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved