即使在游戏中,C ++也能捕获键盘特定键

时间:2015-11-17 02:02:02

标签: c++ keyboard record keystroke

我编写了一个程序,以便在流式传输时更新我的​​k / d比率,我希望它易于使用,基本上可以按“shift + 1”来增加我的杀戮等。 现在它适用于我在谷歌浏览器和一些其他应用程序,但当我在游戏中,在这种情况下,Arma,当我按下这些键时,它只是没有这样做,我必须alt + tab而不是按键,它会工作。 有没有办法让它成为程序的关键捕获优先级是绝对的,也比Arma更重要,即使我在游戏中也会被捕获?

由于

代码:

#include <iostream>
#include <windows.h>

using namespace std;

int main(int argc, const char * argv[]) {
RegisterHotKey(NULL, 1, MOD_SHIFT, 0x31); // shift + 1
RegisterHotKey(NULL, 2, MOD_SHIFT, 0x32);// shift + 2
RegisterHotKey(NULL, 3, MOD_SHIFT, 0x33);// shift + 3
RegisterHotKey(NULL, 4, MOD_SHIFT, 0x30);// shift + 0
//shift + 1 = kill
//shift + 2 = death
//shift + 3 = reset
//shift + 0 = close;
int exit = 0;
int kill = 0;
int death = 0;

cout << "K: " << kill << endl;
cout << "D: " << death;

do
{
    int showKill = kill;
    int showDeath = death;
    do
    {
        MSG msg = {0};
        if (GetMessageA(&msg, NULL, 0, 0) != 0)
            if(msg.message == WM_HOTKEY)
            {
                if(msg.wParam == 1)
                    kill++;
                else if(msg.wParam == 2)
                    death++;
                else if(msg.wParam == 3)
                {
                    kill = 0;
                    death = 0;
                }
                else
                {
                    exit++;
                    break;
                }
            }
    }
    while(kill == showKill && death == showDeath);

    system("CLS");//clear the console
    cout << "K: " << kill << endl;
    cout << "D: " << death;
}
while(exit == 0);


UnregisterHotKey(NULL, 1);
UnregisterHotKey(NULL, 2);
UnregisterHotKey(NULL, 3);
UnregisterHotKey(NULL, 4);
return 0;
}

2 个答案:

答案 0 :(得分:1)

从我能想到的最开始,假设您在Windows上玩游戏,有两种非常简单的方法来解决这个问题:

  1. 你编写一个钩子并在运行时将其注入game.exe。
  2. 您使用SetWindowsHookEx并捕获键盘低级输入事件。
  3. 第一种方法要求你编写一个dll模块,并且你可以使用你已经编写的大部分代码,它应该是这样的:

    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    DWORD WINAPI KeyThread(LPVOID)
    {
        RegisterHotKey(NULL, 1, MOD_SHIFT, 0x31); // shift + 1
        RegisterHotKey(NULL, 2, MOD_SHIFT, 0x32);// shift + 2
        RegisterHotKey(NULL, 3, MOD_SHIFT, 0x33);// shift + 3
        RegisterHotKey(NULL, 4, MOD_SHIFT, 0x30);// shift + 0
        //shift + 1 = kill
        //shift + 2 = death
        //shift + 3 = reset
        //shift + 0 = close;
        int exit = 0;
        int kill = 0;
        int death = 0;
    
        // There's no console here so cout won't work, you'll need to use MessageBox or make a file log somewhere
        cout << "K: " << kill << endl;
        cout << "D: " << death;
    
        do
        {
            int showKill = kill;
            int showDeath = death;
            do
            {
                MSG msg = {0};
                if (GetMessageA(&msg, NULL, 0, 0) != 0)
                    if(msg.message == WM_HOTKEY)
                    {
                        if(msg.wParam == 1)
                            kill++;
                        else if(msg.wParam == 2)
                            death++;
                        else if(msg.wParam == 3)
                        {
                            kill = 0;
                            death = 0;
                        }
                        else
                        {
                            exit++;
                            break;
                        }
                    }
            }
            while(kill == showKill && death == showDeath);
    
            system("CLS");//clear the console
            cout << "K: " << kill << endl;
            cout << "D: " << death;
        }while(exit == 0);
    
    
        UnregisterHotKey(NULL, 1);
        UnregisterHotKey(NULL, 2);
        UnregisterHotKey(NULL, 3);
        UnregisterHotKey(NULL, 4);
    }
    
    BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpvReserved)
    {
        if (fdwReason == DLL_PROCESS_ATTACH)
        {
            CreateThread(NULL, NULL, KeyThread, NULL, NULL, NULL);
        }
        return TRUE;
    }
    

    编译dll后,您需要将其注入游戏过程,我建议WinjectExtreme Injector。如果你是一个胆大妄为的人,​​你可以自己去写一个。我必须注意,如果你的游戏是基于多人游戏并且它使用了反热,那么如果反热是使用白名单系统扫描游戏模块而不是黑名单,你可能会触发某种攻击。

    第二种方法是制作普通的可执行文件,SetWindowsHookEx监视低级键盘事件。我自己很久以前写过这篇文章,但由于我无法找到它,我会简单地为你提供一个使用这种方法的example of keylogger,稍微修改一下它应该完美地工作,我&#39;我们冒昧地为你布置了基本的东西:

    #include <windows.h>
    #include <stdio.h>
    
    HHOOK hKeyboardHook = NULL;
    LRESULT WINAPI LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if ((nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)))
        {
            KBDLLHOOKSTRUCT hooked_key = *((KBDLLHOOKSTRUCT*)lParam);
            DWORD dwMsg = 1;
            dwMsg += hooked_key.scanCode << 16;
            dwMsg += hooked_key.flags << 24;
            char lpszKeyName[1024] = { 0 };
            lpszKeyName[0] = '[';
            int i = GetKeyNameText(dwMsg, (lpszKeyName + 1), 0xFF) + 1;
            int key = hooked_key.vkCode;
            lpszKeyName[i] = ']';
    
            if (key >= 'A' && key <= 'Z')
            {
                if (GetAsyncKeyState(VK_SHIFT) >= 0)
                {
                    key += 0x20;
                }
                    printf("%c \n", key);
            }
    
            else
            {
                printf("%s \n", lpszKeyName);
            }
        }
        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
    }
    
    
    int main()
    {
        MSG message;
        HINSTANCE hins;
        hins = GetModuleHandle(NULL);
        hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)LowLevelKeyboardProc, hins, 0);
    
        // Message pump
        while (GetMessage(&message, NULL, 0, 0))
        {
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
        UnhookWindowsHookEx(hKeyboardHook);
        return 0;
    }
    

    第二种方法可能会被一些防病毒软件检测为恶意软件,但它可以将内容打印到控制台而不需要任何调整,并且对初学者来说不那么复杂和简单。

    我必须提到代码示例未经过测试,因此可能存在一些语法错误,但逻辑本身应该是正确的。

答案 1 :(得分:0)

对于Windows特定的,应该很容易做到:

GetAsyncKeyState()

阅读文档,因为这会给出密钥的状态,当密钥关闭/启动时,特定位会打开/关闭。