-2

I'm trying to code a little "virus" (just a fun joke program which messes around with the cursor and makes some beep sounds). However, I want to close this process with my F9 key.

Here's what I have so far:

void executeApp()
{
    while (true)
    {
        if (GetAsyncKeyState(VK_F9) & 0x8000)
        {
            exit(0);
        }
        Sleep(200);
    }
}

I made a thread that runs this function. However, when I run my entire code and press F9, the process still runs. Only when I press it 2-3 times, it comes up with an Error: "Debug Error! abort() has been called."

It would be nice if someone knows how I can kill my process via a hotkey.

Here is the whole code of the program:

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <ctime>
#include <thread>
#include <random>

using namespace std;

//random number gen for while loops in cursor/beep functions.
random_device rd;
mt19937 eng(rd());
uniform_int_distribution<> distr(1, 100);

//variables used for this program.
int random, Dur, X, Y, Freq;
HWND mywindow, Steam, CMD, TaskMngr;
char Notepad[MAX_PATH] = "notepad.exe";
char Website[MAX_PATH] = "http:\\www.google.de";

//functions
void RandomCursor(), Beeper(), OpenStuff(), executeApp();

//threads
thread cursor(RandomCursor);
thread beeps(Beeper);
thread openstuff(OpenStuff);
thread appexecute(executeApp);

int main()
{
    srand(time(0));
    random = rand() % 3;
    system("title 1337app");

    cursor.join();
    beeps.join();
    appexecute.join();

    return 0;
}

//void SetUp()
//{
//  mywindow = FindWindow(NULL, "1337app");
//  cout << "oh whats that? let me see.\n";
//  Sleep(1000);
//  ShowWindow(mywindow, false);
//}

void Beeper()
{
    while (true)
    {
        if (distr(eng) > 75)
        {
            Dur = rand() % 206;
            Freq = rand() % 2124;
            Beep(Dur, Freq);
        }
        Sleep(1500);
    }
}

//void OpenStuff()
//{
//  ShellExecute(NULL, "open", Notepad, NULL, NULL, SW_MAXIMIZE);
//  ShellExecute(NULL, "open", Website, NULL, NULL, SW_MAXIMIZE);
//}

void RandomCursor()
{
    while (true)
    {
        if (distr(eng) < 50)
        {
            X = rand() % 302;
            Y = rand() % 202;
            SetCursorPos(X, Y);
        }
        Sleep(500);
    }
}

void executeApp()
{
    while (true)
    {
        if (GetAsyncKeyState(VK_F9) & 0x8000)
        {
            exit(0);
        }
        Sleep(200);
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
krobeN
  • 5
  • 2
  • 2
    Welcome to Stack Overflow. Please take the time to read [The Tour](http://stackoverflow.com/tour) and refer to the material from the [Help Center](http://stackoverflow.com/help/asking) what and how you can ask here. – πάντα ῥεῖ Jun 26 '17 at 17:31
  • 1
    Most of the time you will be pressing the key when your process is asleep. You should investigate processing Windows messages. –  Jun 26 '17 at 17:32
  • You should check the behavior of your thread to see what is happening. As @NeilButterworth said, the thread might be asleep most of the time. Depending on what else you've added, it might be doing some other task and cannot process your input at the time causing an error like you saw. Or you could have made a mistake in creation of thread. – Javia1492 Jun 26 '17 at 17:34
  • It would also help to show the other code, ideally the thread, since you already tested your function and said it works. This means your issue is most likely related to the thread. – Javia1492 Jun 26 '17 at 17:36
  • @Javia1492 my other threads (randomCursorMovement, Beeps) are not interrupting the kill thread. i think it has something to do with the function "exit(0);". But i dont know much, because im just beginning with c++. – krobeN Jun 26 '17 at 17:40
  • @krobeN Why are you `anding` the result with `0x8000`? – Javia1492 Jun 26 '17 at 17:50
  • @Javia1492 i dont know, i've searched around here for a bit and found that quite often, thought its neccessary somehow. – krobeN Jun 26 '17 at 17:53
  • @Javia1492 because the return value is a bit mask, so use `AND` to check the individual bits – Remy Lebeau Jun 26 '17 at 18:14

1 Answers1

4

GetAsyncKeyState() returns two pieces of information, but you are looking at only one of them and it is the one that is not very useful to your code.

Per the documentation:

If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.

When you AND the return value with 0x8000, you are testing only the most significant bit, which means you are testing only if the key is currently down at the exact moment that GetAsyncKeyState() is called. Which is why it usually takes several presses, or holding down the key for awhile, for your code to detect the key press. You have a race condition in your code.

You should also AND the return value with 0x0001 to check if the key has been pressed and released in between the times that you call GetAsyncKeyState():

if (GetAsyncKeyState(VK_F9) & 0x8001) 

Or simply:

if (GetAsyncKeyState(VK_F9) != 0)

That being said, what you really should do instead is actually monitor the keyboard and let it tell you when the key is pressed. Either:


Update: Since your code does not have an HWND of its own, try SetWindowsHookEx(), eg:

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <ctime>
#include <thread>
#include <random>

using namespace std;

//random number gen for while loops in cursor/beep functions.
random_device rd;
mt19937 eng(rd());
uniform_int_distribution<> distr(1, 100);

//variables used for this program.
int random, Dur, X, Y, Freq;
HWND mywindow, Steam, CMD, TaskMngr;
char Notepad[MAX_PATH] = "notepad.exe";
char Website[MAX_PATH] = "http://www.google.de";
HANDLE hExitApp = NULL;

//functions

//void SetUp()
//{
//  mywindow = FindWindow(NULL, "1337app");
//  cout << "oh whats that? let me see.\n";
//  Sleep(1000);
//  ShowWindow(mywindow, false);
//}

void Beeper()
{
    if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT)
    {
        do
        {
            if (distr(eng) > 75)
            {
                Dur = rand() % 206;
                Freq = rand() % 2124;
                Beep(Dur, Freq);
            }
        }
        while (WaitForSingleObject(hExitApp, 1500) == WAIT_TIMEOUT);
    }
}

//void OpenStuff()
//{
//  ShellExecute(NULL, NULL, Notepad, NULL, NULL, SW_MAXIMIZE);
//  ShellExecute(NULL, NULL, Website, NULL, NULL, SW_MAXIMIZE);
//}

void RandomCursor()
{
    if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT)
    {
        do
        {
            if (distr(eng) < 50)
            {
                X = rand() % 302;
                Y = rand() % 202;
                SetCursorPos(X, Y);
            }
        }
        while (WaitForSingleObject(hExitApp, 500) == WAIT_TIMEOUT);
    }
}

LRESULT CALLBACK MyLowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HC_ACTION)
    {
        switch (wParam)
        {
            case WM_KEYDOWN:
            case WM_KEYUP:
                if (reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam)->vkCode == VK_F9)
                    SetEvent(hExitApp);
                break;
        }
    }
    return CallNextHookEx(0, nCode, wParam, lParam);
}

void executeApp()
{
    PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);

    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &MyLowLevelKeyboardProc, NULL, 0);
    if (hook)
    {
        MSG msg;

        do
        {
            if (MsgWaitForMultipleObjects(1, &hExitApp, FALSE, INFINITE, QS_ALLINPUT) != (WAIT_OBJECT_0+1))
                break;

            while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        while (true);

        UnhookWindowsHookEx(hook);
    }

    SetEvent(hExitApp);
}

int main()
{
    hExitApp = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!hExitApp) return -1;

    srand(time(0));
    random = rand() % 3;
    system("title 1337app");

    //threads
    thread cursor(RandomCursor);
    thread beeps(Beeper);
    thread openstuff(OpenStuff);
    thread appexecute(executeApp);

    cursor.join();
    beeps.join();
    openstuff.join();
    appexecute.join();

    CloseHandle(hExitApp);
    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770