1. 程式人生 > >VB 載入winIO,實現驅動級鍵盤模擬

VB 載入winIO,實現驅動級鍵盤模擬



最近用VB做外掛,模擬滑鼠實現自動化操作。發現驅動級模擬,一直存在問題。今天終於解決了,記錄下.

---------------------------------------------------------------------------------

系統環境:win7 64位,VB 32位

winIO環境: 3.0環境

---------------------------------------------------------------------------------

WinIO是一款免費、開源的系統元件,你可以在www.internals.com上面免費下載它的
原始碼。在最新版本3.0中,增加了對64位 Windows作業系統的支援。我就是利用它的功能,
實現了驅動級模擬按鍵。在我使用的WinIO 3.0中,裡面有四個bin 檔案,分別是
WinIO32.dll、WinIO64.dll、WinIO32.sys、WinIO64.sys。sys檔案是實現核心功能的驅動,
dll檔案是封裝驅動功能的介面。由於我的系統是64 位系統,使用了VB做介面程式設計,所以
僅需要 WinIO32.dll和 WinIO64.sys。dll

  • VB除錯的時候,要把 WinIO32.dll和 WinIO64.sys 檔案拷貝到VB安裝目錄下
  • 生成exe檔案後,WinIO32.dll和 WinIO64.sys 跟exe檔案保持在同目錄下即可
  • 關於數字簽名:
         WinIO64.sys沒有正式的數字簽名,只有測試簽名。要使它能成功載入,
         必須開啟測試模式(cmd裡切換到 system32目錄再輸入 bcdedit /set testsigning on),
         然後根據以下步驟信任WinIO64.sys的測試簽名:
      1.開啟 WinIO64.sys的屬性框,翻到“數字簽名”選項卡,點選“詳細資訊”
      2.在新出來的對話方塊中點選“檢視證書”
      3.在又新出來的對話方塊中點選“安裝證書”
      4.點選“下一步”,然後選擇“將所有的證書放入下列儲存”
      5.點選瀏覽,選擇“受信任的根證書釋出機構”
      受信任的根證書釋出介面
      6.點選“下一步”,然後點選“完成”
      7.在彈出的“安全性警告”對話方塊中選擇“是”,才能匯入成功

實現方式:

呼叫:

  Private Sub Command6_Click()
    If InitializeWinIo = False Then
     '用InitializeWinIo函式載入驅動程式,如果成功會返回true,否則返回false
     MsgBox "驅動程式載入失敗!"
    Else
      Dim hwnd As Long
      hwnd = Shell("Notepad.exe", vbNormalFocus)
      Sleep 1000
      '模擬按下  alt+F 鍵
      MyKeyDownEx VK_MENU
      Sleep 200
      MyKeyDown VK_F
      MyKeyUp VK_F    '模擬按下並釋放A鍵
      MyKeyUpEx VK_MENU
    
      Sleep 500
      '模擬按下 ctl+O 鍵
      MyKeyDownEx VK_Control
      Sleep 200
      MyKeyDown VK_O
      MyKeyUp VK_O    '模擬按下並釋放A鍵
      MyKeyUpEx VK_Control
      
      ShutdownWinIo '程式結束時記得用ShutdownWinIo函式解除安裝驅動程式
    End If
End Sub

模組:

Option Explicit

Declare Function MapPhysToLin Lib "WinIo32.dll" (ByVal PhysAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As Long
Declare Function UnmapPhysicalMemory Lib "WinIo32.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean
Declare Function GetPhysLong Lib "WinIo32.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As Boolean
Declare Function SetPhysLong Lib "WinIo32.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As Boolean
Declare Function GetPortVal Lib "WinIo32.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function SetPortVal Lib "WinIo32.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function InitializeWinIo Lib "WinIo32.dll" () As Boolean
Declare Function ShutdownWinIo Lib "WinIo32.dll" () As Boolean
Declare Function InstallWinIoDriver Lib "WinIo32.dll" (ByVal DriverPath As String, ByVal Mode As Integer) As Boolean
Declare Function RemoveWinIoDriver Lib "WinIo32.dll" () As Boolean

Public Const KBC_KEY_CMD = &H64    '鍵盤命令埠
Public Const KBC_KEY_DATA = &H60   '鍵盤資料埠

Public Const VK_LButton = &H1 '滑鼠左鍵
Public Const VK_RButton = &H2 '滑鼠右鍵
Public Const VK_Cancel = &H3 'CANCEL鍵
Public Const VK_MButton = &H4 '滑鼠中鍵
Public Const VK_Back = &H8 '退格鍵
Public Const VK_Tab = &H9 'TAB鍵
Public Const VK_Clear = &HC 'CLEAR健
Public Const VK_RETURN = &HD '回車鍵
Public Const VK_Shift = &H10  'SHIFT鍵
Public Const VK_Control = &H11  'CTRL鍵
Public Const VK_MENU = &H12  'MENU鍵
Public Const VK_Pause = &H13  'PAUSE鍵
Public Const VK_Capital = &H14  'CAPS LOCK 鍵
Public Const VK_Escape = &H1B  'ESC鍵
Public Const VK_Space = &H20 ' 空格鍵
Public Const VK_PageUp = &H21  'Page Up 鍵
Public Const VK_PageDown = &H22  'Page Down 鍵
Public Const VK_End = &H23  'END鍵
Public Const VK_Home = &H24  'HOME鍵
Public Const VK_Left = &H25  '游標左鍵
Public Const VK_Up = &H26  '游標上鍵
Public Const VK_Right = &H27  '游標右鍵
Public Const VK_Down = &H28  '游標下鍵
Public Const VK_Select = &H29  'SELECT鍵
Public Const VK_Print = &H2A  'Print Screen 鍵
Public Const VK_Execute = &H2B  'EXECUTE鍵
Public Const VK_Snapshot = &H2C 'SnapShot鍵
Public Const VK_Insert = &H2D  'INSERT鍵
Public Const VK_Delete = &H2E  'DELETE鍵
Public Const VK_Help = &H2F  'HELP鍵
Public Const VK_Numlock = &H90 'NUM LOCK 鍵
Public Const VK_A = &H41 '字母A鍵
Public Const VK_B = &H42 '字母B鍵
Public Const VK_C = &H43 '字母C鍵
Public Const VK_D = &H44 '字母D鍵
Public Const VK_E = &H45 '字母E鍵
Public Const VK_F = &H46 '字母F鍵
Public Const VK_G = &H47 '字母G鍵
Public Const VK_H = &H48 '字母H鍵
Public Const VK_I = &H49 '字母I鍵
Public Const VK_J = &H4A '字母J鍵
Public Const VK_K = &H4B '字母K鍵
Public Const VK_L = &H4C '字母L鍵
Public Const VK_M = &H4D '字母M鍵
Public Const VK_N = &H4E '字母N鍵
Public Const VK_O = &H4F '字母O鍵
Public Const VK_P = &H50 '字母P鍵
Public Const VK_Q = &H51 '字母Q鍵
Public Const VK_R = &H52 '字母R鍵
Public Const VK_S = &H53 '字母S鍵
Public Const VK_T = &H54 '字母T鍵
Public Const VK_U = &H55 '字母U鍵
Public Const VK_V = &H56 '字母V鍵
Public Const VK_W = &H57 '字母W鍵
Public Const VK_X = &H58 '字母X鍵
Public Const VK_Y = &H59 '字母Y鍵
Public Const VK_Z = &H5A '字母Z鍵

Public Const VK_0 = &H30 '數字0鍵
Public Const VK_1 = &H31 '數字1鍵
Public Const VK_2 = &H32 '數字2鍵
Public Const VK_3 = &H33 '數字3鍵
Public Const VK_4 = &H34 '數字4鍵
Public Const VK_5 = &H35 '數字5鍵
Public Const VK_6 = &H36 '數字6鍵
Public Const VK_7 = &H37 '數字7鍵
Public Const VK_8 = &H38 '數字8鍵
Public Const VK_9 = &H39 '數字9鍵

Public Const VK_F1 = &H70  'F1功能鍵
Public Const VK_F2 = &H71  'F2功能鍵
Public Const VK_F3 = &H72  'F3功能鍵
Public Const VK_F4 = &H73  'F4功能鍵
Public Const VK_F5 = &H74  'F5功能鍵
Public Const VK_F6 = &H75  'F6功能鍵
Public Const VK_F7 = &H76  'F7功能鍵
Public Const VK_F8 = &H77  'F8功能鍵
Public Const VK_F9 = &H78  'F9功能鍵
Public Const VK_F10 = &H79 'F10功能鍵
Public Const VK_F11 = &H7A 'F11功能鍵
Public Const VK_F12 = &H7B 'F12功能鍵
Public Const VK_F13 = &H7C 'F13功能鍵
Public Const VK_F14 = &H7D 'F14功能鍵
Public Const VK_F15 = &H7E 'F15功能鍵
Public Const VK_F16 = &H7F 'F16功能鍵
Public Const VK_Numpad0 = &H60 '小鍵盤0鍵
Public Const VK_Numpad1 = &H61 '小鍵盤1鍵
Public Const VK_Numpad2 = &H62 '小鍵盤2鍵
Public Const VK_Numpad3 = &H63 '小鍵盤3鍵
Public Const VK_Numpad4 = &H64 '小鍵盤4鍵
Public Const VK_Numpad5 = &H65 '小鍵盤5鍵
Public Const VK_Numpad6 = &H66 '小鍵盤6鍵
Public Const VK_Numpad7 = &H67 '小鍵盤7鍵
Public Const VK_Numpad8 = &H68 '小鍵盤8鍵
Public Const VK_Numpad9 = &H69 '小鍵盤9鍵
Public Const VK_Multiply = &H6A '小鍵盤*鍵
Public Const VK_Add = &H6B '小鍵盤+鍵
Public Const VK_Separator = &H6C '小鍵盤迴車鍵
Public Const VK_Subtract = &H6D '小鍵盤-鍵
Public Const VK_Decimal = &H6E '小鍵盤.鍵
Public Const VK_Divide = &H6F '小鍵盤/鍵



'**************************
'   等待鍵盤緩衝區為空
'**************************
Sub KBCWait4IBE()
    Dim dwVal As Long
    Do
    GetPortVal &H64, dwVal, 1
    '這句表示從&H64埠讀取一個位元組並把讀出的資料放到變數dwVal中
    'GetPortVal函式的用法是GetPortVal 埠號,存放讀出資料的變數,讀入的長度
    Loop While (dwVal And &H2)
End Sub




'**************************************
'
'這個用來模擬按下鍵,引數vKeyCoad傳入按鍵的虛擬碼
'
'**************************************
Sub MyKeyDown(ByVal vKeyCoad As Long) '
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)
    KBCWait4IBE     '傳送資料前應該先等待鍵盤緩衝區為空
    SetPortVal KBC_KEY_CMD, &HD2, 1     '傳送鍵盤寫入命令
    'SetPortVal函式用於向埠寫入資料,它的用法是SetPortVal 埠號,欲寫入的資料,寫入資料的長度
    KBCWait4IBE
    SetPortVal KBC_KEY_DATA, btScancode, 1 '寫入按鍵資訊,按下鍵
End Sub


'**************************************
'
'這個用來模擬釋放鍵,引數vKeyCoad傳入按鍵的虛擬碼
'
'**************************************
Sub MyKeyUp(ByVal vKeyCoad As Long)
'
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)
    KBCWait4IBE   '等待鍵盤緩衝區為空
    SetPortVal KBC_KEY_CMD, &HD2, 1 '傳送鍵盤寫入命令
    KBCWait4IBE
    SetPortVal KBC_KEY_DATA, (btScancode Or &H80), 1 '寫入按鍵資訊,釋放鍵
End Sub


'*********************************************************************
' 從擴充套件鍵轉換到普通鍵,那麼普通鍵的KeyDown事件應該傳送兩次。
' 也就是說,如果我想模擬先按下一個擴充套件鍵,再按下一個普通鍵,
' 那麼就應該向埠傳送 兩次 該普通鍵被按下的資訊

' MyKeyDownEx VK_LEFT   '按下左方向鍵
' Sleep 200             '延時200毫秒
' MyKeyUpEx VK_LEFT     '釋放左方向鍵
' Sleep 500
' MyKeyDown VK_SPACE   '按下空格鍵,注意要傳送兩次
' MyKeyDown VK_SPACE
' Sleep 200
' MyKeyUp VK_SPACE     '釋放空格鍵

'**********************************************************************
Sub MyKeyDownEx(ByVal vKeyCoad As Long)   '模擬擴充套件鍵按下,引數vKeyCoad是擴充套件鍵的虛擬碼
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)
    KBCWait4IBE   '等待鍵盤緩衝區為空
    SetPortVal KBC_KEY_CMD, &HD2, 1     '傳送鍵盤寫入命令
    KBCWait4IBE
    SetPortVal KBC_KEY_DATA, &HE0, 1    '寫入擴充套件鍵標誌資訊
    
    
    KBCWait4IBE   '等待鍵盤緩衝區為空
    SetPortVal KBC_KEY_CMD, &HD2, 1     '傳送鍵盤寫入命令
    KBCWait4IBE
    SetPortVal KBC_KEY_DATA, btScancode, 1 '寫入按鍵資訊,按下鍵
End Sub




 '***********************************************
 '模擬擴充套件鍵彈起
 '**********************************************
Sub MyKeyUpEx(ByVal vKeyCoad As Long)
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)
    KBCWait4IBE   '等待鍵盤緩衝區為空
    SetPortVal KBC_KEY_CMD, &HD2, 1     '傳送鍵盤寫入命令
    KBCWait4IBE
    SetPortVal KBC_KEY_DATA, &HE0, 1 '寫入擴充套件鍵標誌資訊
    
    
    KBCWait4IBE   '等待鍵盤緩衝區為空
    SetPortVal KBC_KEY_CMD, &HD2, 1     '傳送鍵盤寫入命令
    KBCWait4IBE
    SetPortVal KBC_KEY_DATA, (btScancode Or &H80), 1 '寫入按鍵資訊,釋放鍵
    
End Sub

'----------------------------------------------------------------------------------------------------------------------------------------------------------


Sub MySendKey(bkey As Long)
    '引數bkey傳入要模擬按鍵的虛擬碼即可模擬按下指定鍵
    Dim GInput(0 To 1) As GENERALINPUT
    Dim KInput As KEYBDINPUT
    KInput.wVk = bkey  '你要模擬的按鍵
    KInput.dwFlags = 0 '按下鍵標誌
    GInput(0).dwType = INPUT_KEYBOARD
    CopyMemory GInput(0).xi(0), KInput, Len(KInput) '這個函式用來把記憶體中KInput的資料複製到GInput
    KInput.wVk = bkey
    KInput.dwFlags = KEYEVENTF_KEYUP  ' 釋放按鍵
    GInput(1).dwType = INPUT_KEYBOARD ' 表示該訊息為鍵盤訊息
    CopyMemory GInput(1).xi(0), KInput, Len(KInput) '以上工作把按下鍵和釋放鍵共2條鍵盤訊息加入到GInput資料結構中
    SendInput 2, GInput(0), Len(GInput(0))    '把GInput中存放的訊息插入到訊息列隊
End Sub


Function MakeKeyLparam(ByVal VirtualKey As Long, ByVal flag As Long) As Long
    Dim s As String
    Dim Firstbyte As String     'lparam引數的24-31位
    If flag = WM_KEYDOWN Then   '如果是按下鍵
        Firstbyte = "00"
    Else
         Firstbyte = "C0"        '如果是釋放鍵
    End If
    Dim Scancode As Long
     '獲得鍵的掃描碼
    Scancode = MapVirtualKey(VirtualKey, 0)
    Dim Secondbyte As String    'lparam引數的16-23位,即虛擬鍵掃描碼
    Secondbyte = Right("00" & Hex(Scancode), 2)
    s = Firstbyte & Secondbyte & "0001"   '0001為lparam引數的0-15位,即傳送次數和其它擴充套件資訊
    MakeKeyLparam = Val("&H" & s)
 End Function

參考連結: