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.
- Creating the Project
- Running the Key Logger at Windows Startup
- You've Got Mail
- Intercepting Keystrokes
- The HookCallback Method
- API Methods
- Possible Errors
API Methods
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
- idHook: This number determines the type of hook to be set up. For example, SetWindowsHookEx can also be used to hook into mouse events. In this case, we're only interested in number 13, which is the keyboard hook's id. This has been assigned to the constant WH_KEYBOARD_LL.
- lpfn: A long pointer to the function that will handle the keyboard events. In C#, the "pointer" is achieved by passing an instance of a delegate type, referring to the appropriate method. This is the method that will be called every time the hook is used.
An important point to note here is that the delegate instance needs to be stored in a member variable in the class. This is to prevent it being garbage collected as soon as the first method call ends. - hMod: An instance handle for the application which is setting up the hook. We've set this to IntPtr.Zero (in the beginning of this article section), because it is unlikely that there will be more than one instance of the application. However, this code uses GetModuleHandle from kernel32.dll (see below) to identify the exact instance to make the class potentially more flexible.
- dwThreadId: The ID of the current thread. Setting this to 0 makes the hook global, which is the appropriate setting for a low-level keyboard hook.
Here we import the UnhookWindowsHookEx function which removes the hook when called.
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk);
Below is the code necessary for importing the CallNextHookEx function which passes the hook information to the next hook procedure.
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
Whenever a keyboard event occurs, the following parameters will be passed to HookCallback:
- ncode: the callback function should return the result of CallNextHookEx if this value is less than zero. Normal keyboard events will return an nCode of 0 or more.
- wParam: this value indicates what type of event occurred: key up or key down
- lParam: a structure to store precise information on the keystroke, such as the code of the key which was pressed.
GetModuleHandle is used by SetWindowsHookEx function (see a)?"hmod").
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName);
There are two more braces to close, one for the InterceptKeys class and the other one for the Keylogger namespace.