探究为何vbs脚本无法模拟PrintScreen按键

2009-3-7 Nie.Meining Debug

今天群里有个人问为什么vbs脚本无法模拟截取屏幕的按键,我试了一下,果然不行,而模拟其它常规按键(如abcdefg)都是没有问题的。但是微软官方的帮助文档上明确说明了PRINT SCREEN这个键可以用{PRTSC}参数模拟……
我又用C++写了一个模拟PRINT SCREEN键的程序做实验,代码很简单:

#define UNICODE

#define _UNICODE

#include <windows.h>

#include <tchar.h>

int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {

    keybd_event(VK_SNAPSHOT,0,0,0);

    return 0;

}

 

这回OK了,能够实现截屏……
想不明白,决定仔细研究一下。先写个测试用脚本:

set shell=createobject("wscript.shell")

wscript.sleep 10000

shell.sendkeys "{PRTSC}"

 

代码也很简单,休息10秒,然后模拟截取屏幕的按键。为什么要休息10秒?这样才有足够的时间attach进去呀!
双击运行,用windbg attach到脚本宿主wscritp.exe里去,进程就断下来了,看看模块lm:
点击查看原图
确实有USER32。试着下断吧:bp USER32!keybd_event,我始终觉得vbs的模拟按键也是用keybd_event函数实现的。F5跑起来,果然断下来了:
点击查看原图
现在是在USER32模块中的keybd_event函数开始处,我们去看参数!转到memory中去看堆栈dd @esp:
点击查看原图
前4个字节是返回地址,后面是参数,其中第一个参数,即virtual-key code是2a。为了验证我们的想法,打开memory view将其改成41,即字母‘a’的ascii码:
点击查看原图
将光标放到接受命令的地方,按F5执行,果然出现了个a:
点击查看原图
那么也就是说,vbs通过如此调用函数实现了模拟按键:

keybd_event0x2a,0,0,0);

 

跟我们的C++程序里的keybd_event(VK_SNAPSHOT,0,0,0)基本一致,难道0x2a并不是VK_SNAPSHOT??转到WinUser.h里去:

#define VK_PRINT          0x2A

#define VK_EXECUTE        0x2B

#define VK_SNAPSHOT       0x2C

 

果然VK_SNAPSHOT是0x2C,而0x2A是VK_PRINT……
再用C++做实验,把VK_SNAPSHOT改成VK_PRINT后果然就不能截屏了……
VK_PRINT是个什么键?搞不懂了……上网查了查也没什么结果,还望路过的高手不吝赐教啊!

发表评论:

Powered by emlog