成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

網絡安全編程:模擬鼠標鍵盤按鍵的操作

安全
鼠標和鍵盤的操作也會被轉換為相應的系統消息,窗口過程中在接收到鼠標或鍵盤消息后會進行相應的處理。

 [[377212]]

鼠標和鍵盤的操作也會被轉換為相應的系統消息,窗口過程中在接收到鼠標或鍵盤消息后會進行相應的處理。可以通過SendMessage()和PostMessage()發送消息到指定的窗口過程中,那么使用這兩個函數來發送鼠標和鍵盤的相關消息就可以進行鼠標和鍵盤的模擬操作。除了SendMessage()和PostMessage()外,還可以通過keybd_event()和mouse_event()兩個專用的函數進行鼠標和鍵盤按鍵的模擬操作。

01 基于發送消息的模擬

Windows的應用程序是基于消息機制的,對于鼠標和鍵盤的操作也會被系統轉化為相應的消息。首先來學習如何通過發送消息進行鼠標和鍵盤的模擬操作。

1. 鼠標、鍵盤按鍵常用的消息

無論是鼠標指針(或光標)的移動、單擊,還是鍵盤的按鍵,通常在Windows應用程序中都會轉換成相應的消息。在操作鼠標時,使用最多的是移動鼠標和單擊鼠標鍵。比如,在教新手使用計算機時會告訴他,將鼠標指針(或光標)移動到“我的電腦”上,然后單擊鼠標右鍵,在彈出的快捷菜單中用鼠標左鍵單擊選擇“屬性”對話框。當移動鼠標光標的時候,系統中對應的消息是WM_MOUSEMOVE消息,按下鼠標左鍵時的對應的消息是WM_LBUTTONDOWN,釋放鼠標左鍵時,對應的消息是WM_LBUTTONUP。在系統中,鼠標的消息有很多。在MSDN中查詢到的鼠標消息如圖1所示。

圖1  鼠標相關消息

同樣,在系統中也定義了鍵盤的按下與抬起的消息。鍵盤按下的消息是WM_KEY DOWN,與之對應的鍵盤抬起的消息是WM_KEYUP。除了這兩個消息外,還有一個消息是比較常用的,就是WM_CHAR消息。鍵盤的消息相對于鼠標要少很多,在MSDN中查詢到的鍵盤消息如圖2所示。

圖2  鍵盤相關消息

2. PostMessage()函數對鍵盤按鍵的模擬

PostMessage()和SendMessage()這兩個函數可以對指定的窗口發送消息。既然鼠標和鍵盤按鍵的操作被系統轉換為相應的消息,那么就可以使用PostMessage()和SendMessage()通過按鼠標和鍵盤按鍵發送的消息來模擬它們的操作。對于模擬鍵盤按鍵消息,最好使用PostMessage()而不要使用SendMessage()。在很多情況下,SendMessage()是不會成功的。

現在編寫一個簡單的小工具,它通過PostMessage()函數模擬鍵盤發送(發送F5鍵的消息來模擬網頁的刷新)的信息來刷新網頁。首先打開VC6.0,創建一個MFC對話框工程,按照圖3所示設置界面。

圖3  模擬鍵盤刷新網頁界面布局

按照圖3所示的界面進行布局,然后為“開始”按鈕設置控件變量。這個小程序在“IE瀏覽器標題”處輸入要刷新的頁面的標題,在“刷新頻率”處輸入一個刷新的時間間隔,單位是秒。

當了解程序的功能并且將程序的界面布置好以后,就可以開始編寫程序的代碼了。程序的代碼分為兩部分,第一部分是程序要處理“開始”按鈕的事件,第二部分是要按照指定的時間間隔對指定的瀏覽器發送按F5鍵的消息來刷新網頁。

首先來編寫響應“開始”按鈕事件的代碼,雙擊“開始”按鈕來編寫它的響應事件。代碼如下: 

  1. void CKeyBoardDlg::OnBtnStart()  
  2.  
  3.   // TODO: Add your control notification handler code here  
  4.   CString strBtn;  
  5.   int nInterval = 0 
  6.   // 獲取輸入的瀏覽器標題  
  7.   GetDlgItemText(IDC_EDIT_CAPTION, m_StrCaption);  
  8.   // 獲取輸入的刷新頻率  
  9.   nInterval = GetDlgItemInt(IDC_EDIT_INTERVAL, FALSE, TRUE);  
  10.   // 判斷輸入的值是否非法  
  11.   if ( m_StrCaption ==""|| nInterval == 0 )  
  12.   {  
  13.     return ;  
  14.   }  
  15.   // 獲取按鈕的標題  
  16.   m_Start.GetWindowText(strBtn);  
  17.   if ( strBtn == "開始" )  
  18.   {  
  19.     // 設置定時器  
  20.     SetTimer(1, nInterval * 1000, NULL);  
  21.     m_Start.SetWindowText("停止");  
  22.     GetDlgItem(IDC_EDIT_CAPTION)->EnableWindow(FALSE);  
  23.     GetDlgItem(IDC_EDIT_INTERVAL)->EnableWindow(FALSE);  
  24.   }  
  25.   else  
  26.   {  
  27.     // 結束定時器  
  28.     KillTimer(1);  
  29.     m_Start.SetWindowText("開始");  
  30.     GetDlgItem(IDC_EDIT_CAPTION)->EnableWindow(TRUE);  
  31.     GetDlgItem(IDC_EDIT_INTERVAL)->EnableWindow(TRUE);  
  32.   }  

在代碼中,首先判斷按鈕的文本,如果是“開始”,則通過SetTimer()函數設置一個定時器;如果按鈕的文本不是“開始”,則通過KillTimer()函數關閉定時器。

這里的SetTimer()和KillTimer()是MFC中CWnd類的兩個成員函數,不是API函數。很多MFC中的類成員函數和API函數的寫法是一樣的,但是它們還是有區別的。比較一下SetTimer()在MFC中的定義和API函數的定義的差別。

MFC中的定義如下: 

  1. UINT SetTimer(  
  2.  UINT nIDEvent,  
  3.  UINT nElapse,  
  4.  void (CALLBACK EXPORT* lpfnTimer)(  
  5.  HWND, UINT, UINT, DWORD) ); 

API函數的定義如下: 

  1. UINT_PTR SetTimer(  
  2.  HWND hWnd,  
  3.  UINT_PTR nIDEvent,  
  4.  UINT uElapse,  
  5.  TIMERPROC lpTimerFunc  
  6. ); 

從定義中可以看出,MFC中SetTimer()函數的定義比API中SetTimer()函數的定義少了一個參數,即HWND的窗口句柄的參數。在MFC中,窗口相關的成員函數都不需要指定窗口句柄,在MFC的內部已經維護了一個m_hWnd的句柄變量(如果想要查看或使用MFC內部維護的m_hWnd成員變量,可以直接使用它,也可以通過調用GetSafeHwnd()成員函數來得到它,推薦使用第二種方法)。

在按鈕事件中添加定時器,那么定時器會按照指定的時間間隔進行相應的處理。定時器部分的代碼如下: 

  1. void CKeyBoardDlg::OnTimer(UINT nIDEvent)  
  2.  
  3.   // 在此處添加處理程序代碼  
  4.   HWND hWnd = ::FindWindow(NULL, m_StrCaption.GetBuffer(0));  
  5.   // 發送鍵盤按下消息  
  6.   ::PostMessage(hWnd, WM_KEYDOWN, VK_F5, 1);  
  7.   Sleep(50);  
  8.   // 發送鍵盤抬起消息  
  9.   ::PostMessage(hWnd, WM_KEYUP, VK_F5, 1);  
  10.   CDialog::OnTimer(nIDEvent);  

關于定時器的處理非常簡單,通過FindWindow()函數得到要刷新窗口的句柄,然后發送WM_KEYDOWN和WM_KEYUP消息來模擬鍵盤按鍵即可。其實在模擬的過程中,可以省去WM_KEYUP消息的發送,但是為了模擬效果更接近真實性,建議在模擬時將消息成對發送。

將寫好的程序編譯連接后運行起來看效果,在“IE瀏覽器標題”處輸入瀏覽器的標題,這個標題可以通過Spy++獲得,然后在“刷新頻率”處輸入1。然后單擊“開始”按鈕,觀察瀏覽器每個1秒進行刷新一次。當單擊“停止”按鈕后,程序不再對瀏覽器進行刷新按鍵模擬。

到此,通過PostMessage()函數發送按F5鍵進行鍵盤按鍵模擬的程序就完成了。使用PostMessage()函數的好處是目標窗口可以在后臺,而不需要窗口處于激活狀態。可以將被刷新的瀏覽器最小化,然后運行刷新網頁的小程序,在任務欄可以看到瀏覽器仍然在不斷刷新。

02 通過API函數模擬鼠標鍵盤按鍵的操作

在開發程序時,總是依靠發送消息是非常辛苦的事情,因為消息的類型非常多,并且不同消息的附件參數也因不同的消息類型而異。Windows幾乎為每個常用的消息都提供了相應的API函數。為了不必記憶過多的消息,使用API函數進行開發是相對比較直觀的。

1. 鼠標鍵盤按鍵模擬函數

在使用Windows的系統消息進行模擬鼠標或鍵盤按鍵操作時,可能顯得不直觀,也不方便。微軟公司在進行設計時已經考慮到了這點,因此在Windows下的大部分消息都可以直接使用對應的等價API函數,不必直接通過發送消息。比如可以用WM_GETTEXT消息去獲取文本的內容,對應的函數有GetWindowText()。試想一下,如果程序中一眼看去都是SendMessage()與PostMessage()之類的函數,豈不是很嚇人。

下面介紹兩個函數,分別用來模擬鼠標和鍵盤的輸入,它們分別是keybd_event()和mouse_event(),定義如下: 

  1. VOID keybd_event(  
  2.  BYTE bVk,  
  3.  BYTE bScan,  
  4.  DWORD dwFlags,  
  5.  ULONG_PTR dwExtraInfo  
  6. );  
  7. VOID mouse_event(  
  8.  DWORD dwFlags,  
  9.  DWORD dx,  
  10.  DWORD dy,  
  11.  DWORD dwData,  
  12.  ULONG_PTR dwExtraInfo  
  13. ); 

從函數的名稱就能看出,這兩個API函數分別對應的是鍵盤事件和鼠標事件,在程序里使用時,對于閱讀代碼的人來說就比較直觀了。下面使用keybd_event()和mouse_event()兩個函數來完成上面刷新網頁的小工具。

2. 網頁刷新工具

keybd_event()和 mouse_event()這兩個 API 函數,從函數的參數上來看,不需要給它們傳遞窗口句柄當作參數。那么這兩個函數在進行鼠標和鍵盤的模擬時就必須將目標窗口激活并處于所有窗口的最前端。因此在程序中首先要完成的是將目標窗口設置到最前面,并且處于激活狀態。先來看一下程序的界面部分,如圖4所示。

圖4  模擬鼠標鍵盤

這次的窗口相比上個程序的窗口要簡單些。在界面上有兩個按鈕,第1個按鈕“模擬鍵盤”是通過keybd_event()來模擬按F5鍵從而刷新網頁,第2個按鈕“模擬鼠標”是通過mouse_event()來模擬鼠標右鍵,從而彈出瀏覽器的快捷菜單,再通過keybd_event()模擬按R鍵來刷新網頁。

知道了程序要實現的功能,先來完成將目標窗口設置到最前面并處于激活狀態的部分,代碼如下: 

  1. VOID CSimInputDlg::FindAndFocus()  
  2.  
  3.   GetDlgItemText(IDC_EDIT_CAPTION, m_StrCaption);  
  4.   // 判斷輸入是否為空 
  5.   if ( m_StrCaption == "" )  
  6.   {  
  7.     return ;  
  8.   }  
  9.   m_hWnd = ::FindWindow(NULL, m_StrCaption.GetBuffer(0));  
  10.   // 該函數將創建指定窗口的線程設置到前臺  
  11.   // 并且激活該窗口  
  12.   ::SetForegroundWindow(m_hWnd);  

這個自定義函數非常簡單,分別調用了FindWindow()和SetForegroundWindow()兩個API函數。SetForegroundWindow()函數的使用比較簡單,它會將指定的窗口設置到最前面并處于激活狀態,該函數只有1個參數,是目標窗口的窗口句柄(這里的窗口句柄變量m_hWnd就是由MFC提供的變量,該值也可以使用GetSafeHwnd()函數來進行獲取。)

“模擬鍵盤”按鈕對應的代碼如下: 

  1. void CSimInputDlg::OnBtnSimkeybd()  
  2.  
  3.   // 在此處添加處理程序代碼  
  4.   // 找到窗口  
  5.   // 將其設置到前臺并激活  
  6.   FindAndFocus();  
  7.   Sleep(1000);  
  8.   // 模擬 F5 三次  
  9.   keybd_event(VK_F5, 0, 0, 0);  
  10.   Sleep(1000);  
  11.   keybd_event(VK_F5, 0, 0, 0);  
  12.   Sleep(1000);  
  13.   keybd_event(VK_F5, 0, 0, 0);  

在進行模擬鍵盤按鍵前,首先要調用自定義函數FindAndFocus()將瀏覽器設置到最前面并處于激活狀態(在“模擬鼠標”按鈕中同樣要先調用FindAndFocus()自定義函數)。通過調用keybd_event()函數來模擬F5鍵進行了3次網頁的刷新。

“模擬鼠標”按鈕對應的代碼如下: 

  1. void CSimInputDlg::OnBtnSimmouse()  
  2.  
  3.   // 在此處添加處理程序代碼  
  4.   FindAndFocus();  
  5.   // 得到窗口在屏幕的坐標(x, y) 
  6.   POINT pt = { 0 };  
  7.   ::ClientToScreen(m_hWnd, &pt);  
  8.   // 設置鼠標位置  
  9.   SetCursorPos(pt.x + 36, pt.y + 395);  
  10.   // 模擬單擊鼠標右鍵  
  11.   // 單擊鼠標右鍵后,瀏覽器會彈出快捷菜單  
  12.   mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);  
  13.   Sleep(100);  
  14.   mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);  
  15.   Sleep(1000);  
  16.   // 0x52 = R  
  17.   // 在彈出右鍵菜單后按下 R 鍵  
  18.   // 會刷新頁面  
  19.   keybd_event(0x52, 0, 0, 0);  

代碼中用到了兩個陌生的API函數,分別是ClientToScreen ()和SetCursorPos()。它們的定義如下: 

  1. BOOL ClientToScreen(  
  2.  HWND hWnd, // handle to window  
  3.  LPPOINT lpPoint // screen coordinates  
  4. ); 

ClientToScreen()函數的作用是將窗口區域的坐標轉換為屏幕的坐標。更直接的解釋是,得到指定窗口在屏幕中的坐標位置。 

  1. BOOL SetCursorPos(  
  2.  int X, // horizontal position  
  3.  int Y // vertical position  
  4. ); 

SetCursorPos()函數的作用是將鼠標光標移動到指定的坐標位置。

在程序中為什么不使用mouse_event()來移動鼠標光標的位置,而是使用SetCursorPos()的位置呢?在API函數中,與SetCursorPos()對應的一個函數是GetCursorPos(),而SetCursorPos()函數往往會與GetCursorPos()函數一起使用。因為在很多情況下,程序設置鼠標光標位置進行一系列操作后,仍需要將鼠標光標的位置設置回原來的位置,那么在調用SetCursorPos()前,就需要調用GetCursorPos()得到鼠標光標的當前位置,這樣才可以在操作完成后把鼠標光標設置為原來的位置。由此也可以看出,很多API函數是成對出現的,有Set也有Get,這樣在記憶的時候非常的方便。

在程序中調用SetCursorPos()函數時,參數中的x坐標和y坐標分別加了兩個整型的常量,這里可能比較費解。這兩個整型常量的作用是通過ClientToScreen()函數得到的是瀏覽器左上角的x和y坐標,而瀏覽器的鼠標右鍵菜單必須在瀏覽器的客戶區中才能激活,因此需要在左上角坐標的基礎上增加兩個偏移,代碼里的兩個整型常量就是一個偏移(這里的偏移值可以自己隨意修改,只要保證鼠標能夠落在瀏覽器窗口中即可)。

對于鼠標和鍵盤按鍵的模擬在很多地方都會使用,比如有的病毒用模擬鼠標單擊殺毒軟件的警告提示,比如游戲輔助工具通過模擬鼠標進行快速單擊……對于鼠標和鍵盤按鍵的模擬并不簡單。在常規的情況下,可以通過上面介紹的內容來進行鼠標和鍵盤按鍵的模擬操作。但是對于有些情況就不行了,比如有些游戲過濾了PostMessage()函數發送來的消息,有些游戲hook了keybd_event()和mouse_event()函數,有些游戲使用了DX來響應鼠標和鍵盤…… 

 

責任編輯:龐桂玉 來源: 計算機與網絡安全
相關推薦

2021-03-03 12:20:42

網絡安全DLL編程

2021-02-07 10:55:01

網絡安全文件API

2021-03-05 13:46:56

網絡安全遠程線程

2021-01-26 13:45:03

網絡安全Winsock編程

2009-09-02 18:11:24

C#鼠標

2021-02-23 10:20:07

網絡安全進程代碼

2021-02-21 18:19:43

網絡安全網絡安全編程創建進程

2016-10-10 00:18:27

2021-02-15 15:23:03

網絡安全注冊表API

2021-06-18 09:55:09

網絡安全目錄監控

2009-06-04 09:05:59

2011-03-17 13:32:45

2021-03-01 11:38:15

網絡安全進程代碼

2021-06-11 13:40:17

網絡安全專殺工具病毒

2021-02-05 15:20:06

網絡安全套接字命令

2023-02-06 00:24:12

網絡安全裁員

2022-08-01 06:52:23

數據中心網絡安全

2021-02-04 10:50:11

網絡安全非阻塞模Winsock編程

2021-05-12 14:57:13

網絡安全密碼代碼

2021-04-19 10:26:41

網絡安全PE文件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久精品 | 久久免费国产 | 天天综合网91 | 黄色毛片在线看 | 国产日产精品一区二区三区四区 | 精品一区二区av | 国产精品久久久久久久免费大片 | 久久免费精品视频 | 亚洲一区二区久久 | 亚洲网址在线观看 | 日韩高清av | 亚洲欧美一区二区三区在线 | 九九热在线免费观看 | 日本a视频 | 亚洲欧美v | 久久噜噜噜精品国产亚洲综合 | 成人免费视频 | 日韩欧美三级电影 | 欧美日韩国产一区二区三区不卡 | 国产第一页在线观看 | 2018天天干天天操 | 在线观看国产h | www.99re5.com| 精品视频一区二区三区在线观看 | www.久久艹 | 美女视频黄色片 | 日韩视频观看 | 国产美女黄色 | 国产区精品视频 | 国产69精品久久久久777 | 中文字字幕一区二区三区四区五区 | 欧美亚洲国产一区二区三区 | 99久久久久久久 | 午夜免费观看体验区 | 亚洲精品乱码 | 欧美夜夜| 激情网站在线观看 | 久草免费在线视频 | 日本久久精品 | 久久久久久成人 | 蜜臀久久 |