首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

螢幕數據攔截與修改技術:API Hook、訊息鉤子、枚舉子視窗與系統熱鍵綜合實戰

     編輯:關於VC++

專案背景

客戶需臨時修改某數據庫程式顯示的數據以應付檢查,要求不更改真實數據庫。初嘗試「螢幕取詞」:攔截顯示數據、乘以基數、回寫螢幕。後客戶追加要求「列印修改後數據」,導致方案失效,最終改修改資料庫。但螢幕攔截技術本身有獨立價值,故整理分享。

核心技術棧:API 攔截、訊息鉤子、枚舉子視窗、系統熱鍵註冊。DLL 實作前三者,EXE 實作熱鍵與自訂訊息/系統托盤圖示。

一、API 攔截 (HookAPI.h/cpp)

繁體中文版,代碼精簡。核心步驟:

  1. 取得目標函數位址:GetProcAddress 取被攔截函數與替換函數位址。
  2. 構造 JMP 指令:__asm 組裝跳轉機器碼。
  3. 設定記憶體可寫:VirtualProtect 修改頁面屬性。
  4. 執行替換函數:跳轉至自訂處理邏輯。
  5. 恢復記憶體保護。

三大注意點:

  • 確認目標 DLL 與函數名稱正確。
  • 替換函數簽名 (參數/呼叫慣例) 必須完全一致。
  • 記憶體讀寫順序嚴禁出錯。

比喻:潛入老闆辦公室 → 替換獎金單 → 還原現場 → 撤離。

二、訊息鉤子

核心 API:SetWindowsHookEx / UnhookWindowsHookEx。建議初學者:

  • 深入理解 Windows 訊息機制。
  • 嘗試寫一個純 SDK 程式 (不依賴 MFC)。
  • 善用 MSDN 文檔。

SetWindowsHookEx 四參數,重點關注第 1 (鉤子類型) 與第 4 (執行緒 ID/DLL 實例)。少用 WH_CALLWNDPROC 除非必要。通常 WH_KEYBOARD/WH_MOUSE/WH_GETMESSAGE 即夠用。

三、枚舉子視窗

兩種主流方法:

方法 1:EnumChildWindows 回呼函數


// 呼叫
EnumChildWindows(g_hWndTag, EnumChildWindowsProc, 0);

// 回呼
BOOL CALLBACK EnumChildWindowsProc(HWND hWnd, LPARAM lParam) {
  char buff[256] = {'\0'};
  if (::GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE) {
    ::GetWindowText(hWnd, buff, 256);
    // 過濾特定按鈕/視窗
    if (strstr(buff, "列印") || strstr(buff, "Excel") || strstr(buff, "導出")) {
      // EnableWindow(hWnd, FALSE); // 僅禁用
      DestroyWindow(hWnd); // 徹底銷毀
    }
  }
  return TRUE; // 繼續枚舉
}

方法 2:GetWindow 迴圈 (百試不爽)


HWND hWndChild = ::GetWindow(g_hWnd, GW_CHILD);
while (NULL != hWndChild) {
  // styleXP.CreateClassXP(hWndChild); // 如換膚用途
  hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT);
}

警示:迴圈條件嚴謹,防止無限迴圈。換膚程式常用此法子類化視窗重繪,但工作量極大、易崩潰,作者嘗試重繪按鈕後放棄。

四、系統熱鍵註冊

三步曲:

1. 定義熱鍵 ID


#define ID_A 1501
#define ID_B 1502
#define ID_C 1503
#define ID_D 1504
#define ID_E 1505

2. 初始化時註冊


void CTestDlg::RegSysHotkey() {
  HWND hWnd = this->m_hWnd;
  RegisterHotKey(hWnd, ID_A, MOD_ALT, 65); // Alt+A
  RegisterHotKey(hWnd, ID_B, MOD_ALT, 66); // Alt+B
  RegisterHotKey(hWnd, ID_C, MOD_ALT, 67); // Alt+C
  RegisterHotKey(hWnd, ID_D, MOD_ALT, 68); // Alt+D
  RegisterHotKey(hWnd, ID_E, MOD_ALT, 69); // Alt+E
}

3. 重載 PreTranslateMessage 攔截 WM_HOTKEY


BOOL CTestDlg::PreTranslateMessage(MSG* pMsg) {
  switch (pMsg->message) {
    case WM_HOTKEY:
      switch (pMsg->wParam) {
        case ID_A: OnAppShow(); break;      // 顯示視窗
        case ID_B: HideMe(); break;         // 徹底隱藏
        case ID_C: ... break;               // 其他功能
      }
      break;
  }
  return CDialog::PreTranslateMessage(pMsg);
}

五、自訂訊息與系統托盤圖示

代碼中已實作,此處不贅述,請參考原始碼註解。

執行與說明

  • 代碼無版權限制,自由使用。
  • 已重新編譯,放置於 demo 目錄,似為靜態鏈結,望能在各機器運行。
  • 若無法運行請勿怪罪,請查閱目錄下 readme、代碼註解,或至 VCKBASE 論壇發問。

相關介面截圖

總結

本文整合四大核心 Windows 進階技術,雖源於「作弊」需求,但技術本身中性,廣泛應用於自動化測試、螢幕閱讀器、視窗管理工具、熱鍵增強軟體等。掌握底層機制、注重邊界條件與錯誤處理,方能寫出穩健程式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved