winio模擬鍵盤鼠標的輸入

winio模擬鍵盤鼠標的輸入


做一個遊戲外掛,發現其屏蔽了sendinput消息。
但是按鍵精靈能夠實現。得知其原理是使用winio.dll,僞裝硬件消息。

網上winio關於鼠標鍵盤模擬極少。

void CIotestDlg::KbcWait4IBE()
{
  DWORD dwRegVal=0;
  do
  { 
    GetPortVal(0x64,&dwRegVal,1);
  }
  while(dwRegVal & 0x00000001);
}

void CIotestDlg::KeyPress(BYTE byScancode)
{
  KbcWait4IBE();//Wait for KBC input buffer empty
  SetPortVal(0x64,0xD2,1);//Send data back to the system command
 
  KbcWait4IBE();//Wait for KBC input buffer empty
  SetPortVal(0x60,(ULONG)byScancode,1);//Send the key down scancode
 
  KbcWait4IBE();//Wait for KBC input buffer empty
  SetPortVal(0x64,0xD2,1);//Send data back to the system command
 
  KbcWait4IBE();//Wait for KBC input buffer empty
  SetPortVal(0x60,(ULONG)(byScancode | 0x80),1);//Send the key up scancode
}

這是找到的鍵盤模擬片斷。
做了一個測試程序,發現沒有成功響應虛擬的按鍵消息。

進行keypress(VK_LBUTTON)的時候,測試的dialog直接自動退出,未知原因。
其他keypress(VK_TAB)則沒有響應。
 
以下是採用WinIo直接向ps2鍵盤(或鼠標)緩衝區寫數據的方法。
winxpsp2下測試通過!

procedure SetKey(SCanCode: byte);
begin
  asm
    //無論向0x60,還是0x64寫東西前都要等狀態寄存器OBF變0
    @Loop1:
    in al, $64
    and al, 01b
    jnz @Loop1
    //向$64端口寫命令
    mov al, $D2//寫鍵盤輸出緩存命令
    out $64, al

    //無論向0x60,還是0x64寫東西前都要等狀態寄存器OBF變0
    @Loop2:
    in al, $64
    and al, 01b
    jnz @Loop2
    //向$60端口寫參數
    mov al, SCanCode
    out $60, al
  end;
end;

模擬非擴展鍵:
SetKey($1F);//make codes
Sleep(25);
SetKey($9F);//break code

模擬擴展鍵:
SetKey($E0);//因爲這是一個擴展鍵
SetKey($4B);//make codes
Sleep(25);
SetKey($E0);//因爲這是一個擴展鍵
SetKey($CB);//break code
模擬鼠標的類似。

不管什麼遊戲,SendInput不太可能被屏蔽!

不建議採用winio自身的SetPortVal函數,這樣效率太慢,而是直接用匯編寫端口,當載入winio驅動後就可以直接操作端口了。
載入驅動:InitializeWinIo
卸下驅動:ShutdownWinIo

發佈了108 篇原創文章 · 獲贊 1 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章