偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

網(wǎng)絡(luò)安全編程:模擬鼠標(biāo)鍵盤按鍵的操作

安全
鼠標(biāo)和鍵盤的操作也會(huì)被轉(zhuǎn)換為相應(yīng)的系統(tǒng)消息,窗口過程中在接收到鼠標(biāo)或鍵盤消息后會(huì)進(jìn)行相應(yīng)的處理。

 [[377212]]

鼠標(biāo)和鍵盤的操作也會(huì)被轉(zhuǎn)換為相應(yīng)的系統(tǒng)消息,窗口過程中在接收到鼠標(biāo)或鍵盤消息后會(huì)進(jìn)行相應(yīng)的處理??梢酝ㄟ^SendMessage()和PostMessage()發(fā)送消息到指定的窗口過程中,那么使用這兩個(gè)函數(shù)來發(fā)送鼠標(biāo)和鍵盤的相關(guān)消息就可以進(jìn)行鼠標(biāo)和鍵盤的模擬操作。除了SendMessage()和PostMessage()外,還可以通過keybd_event()和mouse_event()兩個(gè)專用的函數(shù)進(jìn)行鼠標(biāo)和鍵盤按鍵的模擬操作。

01 基于發(fā)送消息的模擬

Windows的應(yīng)用程序是基于消息機(jī)制的,對(duì)于鼠標(biāo)和鍵盤的操作也會(huì)被系統(tǒng)轉(zhuǎn)化為相應(yīng)的消息。首先來學(xué)習(xí)如何通過發(fā)送消息進(jìn)行鼠標(biāo)和鍵盤的模擬操作。

1. 鼠標(biāo)、鍵盤按鍵常用的消息

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

圖1  鼠標(biāo)相關(guān)消息

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

圖2  鍵盤相關(guān)消息

2. PostMessage()函數(shù)對(duì)鍵盤按鍵的模擬

PostMessage()和SendMessage()這兩個(gè)函數(shù)可以對(duì)指定的窗口發(fā)送消息。既然鼠標(biāo)和鍵盤按鍵的操作被系統(tǒng)轉(zhuǎn)換為相應(yīng)的消息,那么就可以使用PostMessage()和SendMessage()通過按鼠標(biāo)和鍵盤按鍵發(fā)送的消息來模擬它們的操作。對(duì)于模擬鍵盤按鍵消息,最好使用PostMessage()而不要使用SendMessage()。在很多情況下,SendMessage()是不會(huì)成功的。

現(xiàn)在編寫一個(gè)簡(jiǎn)單的小工具,它通過PostMessage()函數(shù)模擬鍵盤發(fā)送(發(fā)送F5鍵的消息來模擬網(wǎng)頁的刷新)的信息來刷新網(wǎng)頁。首先打開VC6.0,創(chuàng)建一個(gè)MFC對(duì)話框工程,按照?qǐng)D3所示設(shè)置界面。

圖3  模擬鍵盤刷新網(wǎng)頁界面布局

按照?qǐng)D3所示的界面進(jìn)行布局,然后為“開始”按鈕設(shè)置控件變量。這個(gè)小程序在“IE瀏覽器標(biāo)題”處輸入要刷新的頁面的標(biāo)題,在“刷新頻率”處輸入一個(gè)刷新的時(shí)間間隔,單位是秒。

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

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

  1. void CKeyBoardDlg::OnBtnStart()  
  2.  
  3.   // TODO: Add your control notification handler code here  
  4.   CString strBtn;  
  5.   int nInterval = 0 
  6.   // 獲取輸入的瀏覽器標(biāo)題  
  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.   // 獲取按鈕的標(biāo)題  
  16.   m_Start.GetWindowText(strBtn);  
  17.   if ( strBtn == "開始" )  
  18.   {  
  19.     // 設(shè)置定時(shí)器  
  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.     // 結(jié)束定時(shí)器  
  28.     KillTimer(1);  
  29.     m_Start.SetWindowText("開始");  
  30.     GetDlgItem(IDC_EDIT_CAPTION)->EnableWindow(TRUE);  
  31.     GetDlgItem(IDC_EDIT_INTERVAL)->EnableWindow(TRUE);  
  32.   }  

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

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

MFC中的定義如下: 

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

API函數(shù)的定義如下: 

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

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

在按鈕事件中添加定時(shí)器,那么定時(shí)器會(huì)按照指定的時(shí)間間隔進(jìn)行相應(yīng)的處理。定時(shí)器部分的代碼如下: 

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

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

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

到此,通過PostMessage()函數(shù)發(fā)送按F5鍵進(jìn)行鍵盤按鍵模擬的程序就完成了。使用PostMessage()函數(shù)的好處是目標(biāo)窗口可以在后臺(tái),而不需要窗口處于激活狀態(tài)??梢詫⒈凰⑿碌臑g覽器最小化,然后運(yùn)行刷新網(wǎng)頁的小程序,在任務(wù)欄可以看到瀏覽器仍然在不斷刷新。

02 通過API函數(shù)模擬鼠標(biāo)鍵盤按鍵的操作

在開發(fā)程序時(shí),總是依靠發(fā)送消息是非常辛苦的事情,因?yàn)橄⒌念愋头浅6?,并且不同消息的附件參?shù)也因不同的消息類型而異。Windows幾乎為每個(gè)常用的消息都提供了相應(yīng)的API函數(shù)。為了不必記憶過多的消息,使用API函數(shù)進(jìn)行開發(fā)是相對(duì)比較直觀的。

1. 鼠標(biāo)鍵盤按鍵模擬函數(shù)

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

下面介紹兩個(gè)函數(shù),分別用來模擬鼠標(biāo)和鍵盤的輸入,它們分別是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. ); 

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

2. 網(wǎng)頁刷新工具

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

圖4  模擬鼠標(biāo)鍵盤

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

知道了程序要實(shí)現(xiàn)的功能,先來完成將目標(biāo)窗口設(shè)置到最前面并處于激活狀態(tài)的部分,代碼如下: 

  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.   // 該函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺(tái)  
  11.   // 并且激活該窗口  
  12.   ::SetForegroundWindow(m_hWnd);  

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

“模擬鍵盤”按鈕對(duì)應(yīng)的代碼如下: 

  1. void CSimInputDlg::OnBtnSimkeybd()  
  2.  
  3.   // 在此處添加處理程序代碼  
  4.   // 找到窗口  
  5.   // 將其設(shè)置到前臺(tái)并激活  
  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);  

在進(jìn)行模擬鍵盤按鍵前,首先要調(diào)用自定義函數(shù)FindAndFocus()將瀏覽器設(shè)置到最前面并處于激活狀態(tài)(在“模擬鼠標(biāo)”按鈕中同樣要先調(diào)用FindAndFocus()自定義函數(shù))。通過調(diào)用keybd_event()函數(shù)來模擬F5鍵進(jìn)行了3次網(wǎng)頁的刷新。

“模擬鼠標(biāo)”按鈕對(duì)應(yīng)的代碼如下: 

  1. void CSimInputDlg::OnBtnSimmouse()  
  2.  
  3.   // 在此處添加處理程序代碼  
  4.   FindAndFocus();  
  5.   // 得到窗口在屏幕的坐標(biāo)(x, y) 
  6.   POINT pt = { 0 };  
  7.   ::ClientToScreen(m_hWnd, &pt);  
  8.   // 設(shè)置鼠標(biāo)位置  
  9.   SetCursorPos(pt.x + 36, pt.y + 395);  
  10.   // 模擬單擊鼠標(biāo)右鍵  
  11.   // 單擊鼠標(biāo)右鍵后,瀏覽器會(huì)彈出快捷菜單  
  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.   // 會(huì)刷新頁面  
  19.   keybd_event(0x52, 0, 0, 0);  

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

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

ClientToScreen()函數(shù)的作用是將窗口區(qū)域的坐標(biāo)轉(zhuǎn)換為屏幕的坐標(biāo)。更直接的解釋是,得到指定窗口在屏幕中的坐標(biāo)位置。 

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

SetCursorPos()函數(shù)的作用是將鼠標(biāo)光標(biāo)移動(dòng)到指定的坐標(biāo)位置。

在程序中為什么不使用mouse_event()來移動(dòng)鼠標(biāo)光標(biāo)的位置,而是使用SetCursorPos()的位置呢?在API函數(shù)中,與SetCursorPos()對(duì)應(yīng)的一個(gè)函數(shù)是GetCursorPos(),而SetCursorPos()函數(shù)往往會(huì)與GetCursorPos()函數(shù)一起使用。因?yàn)樵诤芏嗲闆r下,程序設(shè)置鼠標(biāo)光標(biāo)位置進(jìn)行一系列操作后,仍需要將鼠標(biāo)光標(biāo)的位置設(shè)置回原來的位置,那么在調(diào)用SetCursorPos()前,就需要調(diào)用GetCursorPos()得到鼠標(biāo)光標(biāo)的當(dāng)前位置,這樣才可以在操作完成后把鼠標(biāo)光標(biāo)設(shè)置為原來的位置。由此也可以看出,很多API函數(shù)是成對(duì)出現(xiàn)的,有Set也有Get,這樣在記憶的時(shí)候非常的方便。

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

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

 

責(zé)任編輯:龐桂玉 來源: 計(jì)算機(jī)與網(wǎng)絡(luò)安全
相關(guān)推薦

2021-03-03 12:20:42

網(wǎng)絡(luò)安全DLL編程

2021-02-07 10:55:01

網(wǎng)絡(luò)安全文件API

2021-01-26 13:45:03

網(wǎng)絡(luò)安全Winsock編程

2021-03-05 13:46:56

網(wǎng)絡(luò)安全遠(yuǎn)程線程

2009-09-02 18:11:24

C#鼠標(biāo)

2021-02-21 18:19:43

網(wǎng)絡(luò)安全網(wǎng)絡(luò)安全編程創(chuàng)建進(jìn)程

2021-02-23 10:20:07

網(wǎng)絡(luò)安全進(jìn)程代碼

2016-10-10 00:18:27

2021-02-15 15:23:03

網(wǎng)絡(luò)安全注冊(cè)表API

2009-06-04 09:05:59

2021-06-18 09:55:09

網(wǎng)絡(luò)安全目錄監(jiān)控

2021-03-01 11:38:15

網(wǎng)絡(luò)安全進(jìn)程代碼

2021-06-11 13:40:17

網(wǎng)絡(luò)安全專殺工具病毒

2021-02-05 15:20:06

網(wǎng)絡(luò)安全套接字命令

2011-03-17 13:32:45

2021-03-01 11:20:13

網(wǎng)絡(luò)安全多線程代碼

2021-01-18 10:35:18

網(wǎng)絡(luò)安全Windows代碼

2022-08-01 06:52:23

數(shù)據(jù)中心網(wǎng)絡(luò)安全

2023-02-06 00:24:12

網(wǎng)絡(luò)安全裁員

2021-02-04 10:50:11

網(wǎng)絡(luò)安全非阻塞模Winsock編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)