我一直在尝试使用数据结构创建一个键盘记录器,我在网站上看到了这段代码。
我不明白"字符"是ASCII值还是什么? 另外,为什么我们在最后一个条件下将字符值增加32。
for (character = 8;character <= 222;character++)
{
if (GetAsyncKeyState(character) == -32767)
{
FILE *file;
file = fopen(FileName, "a+");
if (file != NULL)
{
if ((character >= 39) && (character <= 64))
{
fputc(character, file);
fclose(file);
break;
}
else if ((character>64) && (character<91))
{
character += 32;
fputc(character, file);
fclose(file);
break;
}
/* ... */
}
}
}
答案 0 :(得分:1)
关注GetAsyncKeyState
的{{3}}后,character
的类型为int
:
SHORT WINAPI GetAsyncKeyState(
_In_ int vKey
)
您会注意到GetAsyncKeyState
的返回值是short
,显然是一个16位有符号整数值。
对于返回值,
如果设置了最高有效位,则键已关闭。
意味着SHORT
上的负位将被设置,或者如果一个键关闭则返回值-32767
(因此,如果这是返回值,则输入if分支) ;代码想记录按键)。
日志记录的代码非常清楚IMO,但您想知道为什么32
增加了这里:
// ...
else if ((character>64) && (character<91))
{
character += 32;
// ...
character
即使它是int
,实际上也是documentation。虚拟密钥代码最多为0xFE(254)
当您查看表格中的虚拟键码时,大于64且小于91的值是英文字母的字母。增量为32将使它们成为小写字符(65为'A'
,但97为'a'
)在ASCII 中。也就是说,代码正在利用“A&#39; A&#39;在虚拟键代码中,与ASCII中的大写'A'
字符相同,然后在打印到文件之前执行ASCII的小写转换。
关于循环背后的推理似乎存在争议:
for (character = 8;character <= 222;character++)
虚拟键码中的值8对应于退格键,或者实际上是可打印字符的开头,因为前7个(实际上从1开始)是按钮。这并不是说8-222范围内的所有字符都是可打印的。
222(0xDE)的值对应 VK_OEM_7 :
对于美国标准键盘,&#39;单引号/双引号&#39;键。
换句话说,几乎是英文键盘上用于虚拟键码的最后一个可打印键盘字符。显然,记录器针对讲英语的Windows用户。实际代码可能会重复运行循环,询问哪个键已关闭,然后记录它。