A key logger with windows hooks

There are many reasons why one might want to intercept the signals from the hardware (i.e. keyboard and mouse) before they reach the software in your computer, some of them completely legitimate, others, quite shady.

In this post we will use c++ and the Windows API to create a very simple console application that can intercept the keyboard messages and do something with them. Of course, you can do all kind of crazy an illegal things using the principles that are presented here, so be responsible (don’t make me quote Ben Parker).

Note: I’m using Visual Studio 2015 and Windows 8.1 . There might be additional required steps for different targets.

The Windows API offers a tool known as hooks which are defined in their documentation as ” 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”. In other words, hooks are a way to intercept system messages and react accordingly.

Cool, right? But how do you do it?

If we strip our application to its bare bones it would look something like this

#include <Windows.h>
#include <stdio.h>
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   PKBDLLHOOKSTRUCT key = (PKBDLLHOOKSTRUCT)lParam;
   //a key was pressed
  if (wParam == WM_KEYDOWN && nCode == HC_ACTION )
  {
    DoSomething(key);
  }
   return CallNextHookEx(keyboardHook, nCode, wParam, lParam);
}
HHOOK keyboardHook;
int main()
{
   keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, NULL);

   MSG msg{ 0 };
   //our application loop
   while (GetMessage(&msg, NULL, 0, 0) != 0);
   UnhookWindowsHookEx(keyboardHook);
   return 0;
}

The contents of the main function are quite simple, we only need to initialize a handle to a hook (HHOOK) using the  SetWindowsHookEx function. The first argument indicates the kind of message we will be monitoring. In this case WH_KEYBOARD_LL  means that we will be receiving Low Level (that’s what LL stands for) information  from the keyboard activity. You can see all available types of hooks on the MSDN documentation. The second argument is the hook procedure which is a user defined function defining what the hook will do. Typically, a hook is associated to a particular process and a DLL containing its procedure. Those are indicated by the third and fourth arguments. For simplicity we set both to NULL meaning that the hook procedure is started by the same application and it will be associated with all threads running on the same desktop.

In the end we call the UnhookWindowsHookEx to get everything cleaned up.

The most important part in an application like this is the definition of the hook procedure. As it’s common on the Windows API, this function can have any name as long it adheres to the appropriate function prototype. For instance, a procedure called KeyboardProc should look like this:

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

The variable nCode will contain a number smaller than 0 if there is no keyboard information currently available or  HC_ACTION otherwise.  If there is information, wParam will contain the type of message that was received and lParam will provide additional data. In this case  we’re interested in the key down message (wParam == WM_KEYDOWN) which triggers whenever the user presses a key.

When the WM_KEYDOWN message is received, lParam contains a PKBDLLHOOKSTRUCT which stores, among other things, the virtual-key code of the pressed key.

Once we extracted this data we can do whatever we want with it (hence the DoSomething() function). For this example we analyze the user’s keyboard activity and display a console message when the sequence LOVE (case insensitive) is typed. This is achieved using a standard FSM-based lexical analyzer. For completeness, the DoSomething function will look something like this:

enum STATES {NOTHING, TYPED_L, TYPED_O, TYPED_V,TYPED_E};

void DoSomething(PKBDLLHOOKSTRUCT key)

if (UserTypedLOVE(key->vkCode))
 {
 printf("\n\n\n love is the child of illusion and the parent of disillusion\n -Miguel de Unamuno-\n\n\n");

 }

//automata to identify a sequence
bool UserTypedLOVE(DWORD vkCode)
{
 switch (currentState)
 {
 case NOTHING:
 if (vkCode == 'L')
 currentState = TYPED_L;
 else
 currentState = NOTHING;
 break;
 case TYPED_L:
 if (vkCode == 'O')
 currentState = TYPED_O;
 else
 currentState = NOTHING;
 break;
 case TYPED_O:
 if (vkCode == 'V')
 currentState = TYPED_V;
 else
 currentState = NOTHING;
 break;
 case TYPED_V:
 if (vkCode == 'E')
 currentState = NOTHING;
 else
 currentState = NOTHING;
 return true;
 break;

 }
 return false;
}

 

A [somewhat fancier] Visual Studio Solution containing the whole code can be downloaded from this link.

You can see the program in action on this video

Happy coding!

 

 

 

Advertisements

4 responses to “A key logger with windows hooks

  1. Hi,
    This is exactly something I was looking for. Currently I’m preparing a demo for my presentation regarding smart malware and the last thing I was looking for was this.
    The studio project isn’t available at google anymore.
    Is there any chance you can send me the zip file?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s