Click here to Skip to main content
15,885,914 members
Articles / Desktop Programming / Win32

Minimal Key Logger Using RAWINPUT

Rate me:
Please Sign up or sign in to vote.
4.71/5 (7 votes)
8 Mar 2013CPOL5 min read 38.6K   2.6K   18  
This is a VB.NET and C# version of "Minimal Key Logger Using RAWINPUT".

public class RawInputHook : RawInputNativeMethods
{
	private SimpleMessageOnlyWindow m_SimpleMessageWindow = new SimpleMessageOnlyWindow();
	public event OnRawInputFromMouseEventHandler OnRawInputFromMouse;
	public delegate void OnRawInputFromMouseEventHandler(RAWINPUTHEADER riHeader, RAWMOUSE riMouse);
	public event OnRawInputFromKeyboardEventHandler OnRawInputFromKeyboard;
	public delegate void OnRawInputFromKeyboardEventHandler(RAWINPUTHEADER riHeader, RAWKEYBOARD riKeyboard);
	public event OnRawInputFromHIDEventHandler OnRawInputFromHID;
	public delegate void OnRawInputFromHIDEventHandler(RAWINPUTHEADER riHeader, RAWHID riHID);
	public event OnRawInputFromUnknownEventHandler OnRawInputFromUnknown;
	public delegate void OnRawInputFromUnknownEventHandler(RawInput riUnknownType);
	private static string[] key_names = {
		"",
		"Left mouse button",
		"Right mouse button",
		"Control-break processing",
		"Middle mouse button",
		"2000/XP: X1 mouse button",
		"2000/XP: X2 mouse button",
		"",
		"BACKSPACE",
		"TAB",
		"",
		"",
		"CLEAR",
		"ENTER",
		"",
		"",
		"SHIFT",
		"CTRL",
		"ALT",
		"PAUSE",
		"CAPS LOCK",
		"Kana/Hangul/Hanguel mode",
		"",
		"Junja mode",
		"Final mode",
		"Hanja/Kanji mode",
		"",
		"ESC",
		"IME Convert",
		"IME Nonconvert",
		"IME Accept",
		"IME Mode Change Request",
		"SPACEBAR",
		"PAGE UP",
		"PAGE DOWN",
		"END",
		"HOME",
		"LEFT ARROW",
		"UP ARROW",
		"RIGHT ARROW",
		"DOWN ARROW",
		"SELECT",
		"PRINT",
		"EXECUTE",
		"PRINT SCREEN",
		"INSERT",
		"DELETE",
		"HELP",
		"0 key",
		"1 key",
		"2 key",
		"3 key",
		"4 key",
		"5 key",
		"6 key",
		"7 key",
		"8 key",
		"9 key",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"A key",
		"B key",
		"C key",
		"D key",
		"E key",
		"F key",
		"G key",
		"H key",
		"I key",
		"J key",
		"K key",
		"L key",
		"M key",
		"N key",
		"O key",
		"P key",
		"Q key",
		"R key",
		"S key",
		"T key",
		"U key",
		"V key",
		"W key",
		"X key",
		"Y key",
		"Z key",
		"Left Windows/Start",
		"Right Windows key",
		"Applications OR Context-Menu",
		"",
		"Computer Sleep key",
		"Numeric keypad 0 key",
		"Numeric keypad 1 key",
		"Numeric keypad 2 key",
		"Numeric keypad 3 key",
		"Numeric keypad 4 key",
		"Numeric keypad 5 key",
		"Numeric keypad 6 key",
		"Numeric keypad 7 key",
		"Numeric keypad 8 key",
		"Numeric keypad 9 key",
		"Multiply key",
		"Add key",
		"Separator key",
		"Subtract key",
		"Decimal key",
		"Divide key",
		"F1 key",
		"F2 key",
		"F3 key",
		"F4 key",
		"F5 key",
		"F6 key",
		"F7 key",
		"F8 key",
		"F9 key",
		"F10 key",
		"F11 key",
		"F12 key",
		"F13 key",
		"F14 key",
		"F15 key",
		"F16 key",
		"F17 key",
		"F18 key",
		"F19 key",
		"F20 key",
		"F21 key",
		"F22 key",
		"F23 key",
		"F24 key",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"NUM LOCK key",
		"SCROLL LOCK key",
		"OEM OR NUMPAD EQUAL OR 'Dictionary'",
		"OEM OR 'Unregister word' key",
		"OEM OR 'Register word' key",
		"OEM OR 'Left OYAYUBI' key",
		"OEM OR 'Right OYAYUBI' key",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"Left SHIFT key",
		"Right SHIFT key",
		"Left CONTROL key",
		"Right CONTROL key",
		"Left MENU key",
		"Right MENU key",
		"2000/XP: Browser Back key",
		"2000/XP: Browser Forward key",
		"2000/XP: Browser Refresh key",
		"2000/XP: Browser Stop key",
		"2000/XP: Browser Search key",
		"2000/XP: Browser Favorites key",
		"2000/XP: Browser Start and Home key",
		"2000/XP: Volume Mute key",
		"2000/XP: Volume Down key",
		"2000/XP: Volume Up key",
		"2000/XP: Next Track key",
		"2000/XP: Previous Track key",
		"2000/XP: Stop Media key",
		"2000/XP: Play/Pause Media key",
		"2000/XP: Start Mail key",
		"2000/XP: Select Media key",
		"2000/XP: Start Application 1 key",
		"2000/XP: Start Application 2 key",
		"",
		"",
		"OEM_1, the ';:' key",
		"OEM_PLUS",
		"OEM_COMMA",
		"OEM_MINUS",
		"OEM_PERIOD",
		"OEM_2, the '/?' key",
		"OEM_3, the '~' key",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"2000/XP, the '[{' key",
		"2000/XP, the '\\|' key",
		"2000/XP, the ']}' key",
		"2000/XP, the 'single/double-quote' key",
		"OEM_8",
		"ICO_F17 reserved",
		"OEM_AX key on Japanese AX kbd (OEM specific)",
		"OEM_102 OR OEM102 '<>' or '\\|' on RT 102-key kbd.",
		"Help key on ICO (OEM specific)",
		"00 key on ICO (OEM specific)",
		"95/98/Me/NT4/2000/XP: IME PROCESS key",
		"ICO_CLEAR OEM specific",
		"2000/XP: Unicode, VK_PACKET = low 32-bits VKey",
		"",
		"OEM_RESET",
		"OEM_JUMP",
		"OEM_PA1",
		"OEM_PA2",
		"OEM_PA3",
		"OEM_WSCTRL",
		"OEM_CUSEL",
		"OEM_ATTN",
		"OEM_FINISH OEM_FINNISH",
		"OEM_COPY",
		"OEM_AUTO",
		"OEM_ENLW",
		"OEM_BACKTAB",
		"Attn key",
		"CrSel key",
		"ExSel key",
		"Erase EOF key",
		"Play key",
		"Zoom key",
		"Reserved",
		"PA1 key",
		"Clear key",
		""
	};
    public RawInputHook()
    {
        m_SimpleMessageWindow.OnWindowsMessageCreate += new SimpleMessageOnlyWindow.OnWindowsMessageCreateEventHandler(SimpleMessageWindowCreate);
        m_SimpleMessageWindow.OnWindowsMessageInput += new SimpleMessageOnlyWindow.OnWindowsMessageInputEventHandler(SimpleMessageWindowInput);      
    //
    }
	public string FriendlyKeyname(int KeyCode)
	{
		return key_names[KeyCode & 255];
	}
	public void SimpleMessageWindowCreate(System.IntPtr hWnd, int msg, System.IntPtr wParam, System.IntPtr lParam)
	{
		//Dim AllRawInputDevices As New RawInputDevices
		//Dim pages() As UShort = AllRawInputDevices.UniqueUsagePages
		//'Dim pages() As UShort = New UShort() {12}
		//Dim rid(2 + pages.Length) As RAWINPUTDEVICE ' = RAWINPUTDEVICE(x)'{New RAWINPUTDEVICE, New RAWINPUTDEVICE, New RAWINPUTDEVICE, New RAWINPUTDEVICE}
		//For i As Integer = 0 To rid.Length - 1
		//    rid(i) = New RAWINPUTDEVICE
		//Next
		//rid(0).dwFlags = RawInputDeviceFlags.PageOnly Or RawInputDeviceFlags.InputSink 'all usages flags
		//rid(0).usUsagePage = HIDUsagePage.Generic
		//rid(0).usUsage = 0 '0 because of PageOnly (all Usage(s) under HIDUsagePage.Generic)
		//rid(0).hwndTarget = hWnd
		//rid(1).dwFlags = RawInputDeviceFlags.NoLegacy Or RawInputDeviceFlags.InputSink Or RawInputDeviceFlags.NoHotKeys 'keyboard flags
		//rid(1).usUsagePage = HIDUsagePage.Generic
		//rid(1).usUsage = HIDUsage.Keyboard
		//rid(1).hwndTarget = hWnd
		//rid(2).dwFlags = RawInputDeviceFlags.NoLegacy Or RawInputDeviceFlags.InputSink Or RawInputDeviceFlags.CaptureMouse 'mouse flags
		//rid(2).usUsagePage = HIDUsagePage.Generic
		//rid(2).usUsage = HIDUsage.Mouse
		//rid(2).hwndTarget = hWnd
		//For i As Integer = 3 To rid.Length - 1
		//    rid(i).dwFlags = RawInputDeviceFlags.PageOnly Or RawInputDeviceFlags.InputSink 'all usages flags
		//    rid(i).usUsagePage = pages(i - 3)
		//    rid(i).usUsage = 0 '0 because of PageOnly (all Usage(s) under rid(i).usUsagePage)
		//    rid(i).hwndTarget = hWnd
		//Next
		RAWINPUTDEVICE[] rid = { new RAWINPUTDEVICE() };
		rid[0].dwFlags = (int)RawInputDeviceFlags.InputSink | (int)RawInputDeviceFlags.NoHotKeys;
		//keyboard flags     RawInputDeviceFlags.NoLegacy Or 
		rid[0].usUsagePage = (ushort)HIDUsagePage.Generic;
		rid[0].usUsage = (ushort)HIDUsage.Keyboard;
		rid[0].hwndTarget = hWnd;
		RegisterRawInputDevices(rid, rid.Length, System.Runtime.InteropServices.Marshal.SizeOf(rid[0]));
	}

	public void SimpleMessageWindowInput(System.IntPtr hWnd, int msg, System.IntPtr wParam, System.IntPtr lParam)
	{
		RawInput ri = new RawInput();
		int blen = 0;
		int hlen = System.Runtime.InteropServices.Marshal.SizeOf(typeof(RAWINPUTHEADER));
		int bytesRead = -1;

		bytesRead = GetRawInputData(lParam, RawInputCommand.Input, System.IntPtr.Zero, ref blen, hlen);
		if (((bytesRead == -1) || (blen < 1))) {
            System.Diagnostics.Debug.WriteLine("GetRawInputData Error Retreiving Buffer size.");
		} else {
            System.IntPtr riBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(blen);
			bytesRead = GetRawInputData(lParam, RawInputCommand.Input, riBuffer, ref blen, hlen);
			if (bytesRead != blen) {
                System.Diagnostics.Debug.WriteLine("GetRawInputData Error Retreiving Buffer data.");
			} else {
				byte[] bb = new byte[bytesRead];
				try {
					ri = (RawInput)System.Runtime.InteropServices.Marshal.PtrToStructure(riBuffer, typeof(RawInput));
					System.Runtime.InteropServices.Marshal.Copy(riBuffer, bb, 0, bb.Length);
				} catch (System.Exception ex) {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
				}
				if (ri.Equals(null)) {
                    System.Diagnostics.Debug.WriteLine("Error Casting Marshalled Buffer into RawInput structure.");
				} else {
                    //string deviceType = null;
                    switch (ri.Header.dwType)
                    {
                        case 0:
                            //deviceType = "MOUSE";
                            if ((((OnRawInputFromMouse != null)) && (OnRawInputFromMouse.GetInvocationList().Length > 0)))
                            {
                                RaiseEventUtility.RaiseEventAndExecuteItInTheTargetThread(OnRawInputFromMouse, new object[] {
				ri.Header,
				ri.Data.Mouse
			});
                            }
                            break;
                        case 1:
                            //deviceType = "KEYBOARD";
                            if ((((OnRawInputFromKeyboard != null)) && (OnRawInputFromKeyboard.GetInvocationList().Length > 0)))
                            {
                                RaiseEventUtility.RaiseEventAndExecuteItInTheTargetThread(OnRawInputFromKeyboard, new object[] {
				ri.Header,
				ri.Data.Keyboard
			});
                            }
                            break;
                        case 2:
                            //deviceType = "HID";
                            if ((((OnRawInputFromHID != null)) && (OnRawInputFromHID.GetInvocationList().Length > 0)))
                            {
                                RaiseEventUtility.RaiseEventAndExecuteItInTheTargetThread(OnRawInputFromHID, new object[] {
				ri.Header,
				ri.Data.HID
			});
                            }
                            break;
                        default:
                            //deviceType = "UNKNOWN";
                            if ((((OnRawInputFromUnknown != null)) && (OnRawInputFromUnknown.GetInvocationList().Length > 0)))
                            {
                                RaiseEventUtility.RaiseEventAndExecuteItInTheTargetThread(OnRawInputFromUnknown, new object[] { ri });
                            }
                            break;
                    }
				}
			}
			try {
				System.Runtime.InteropServices.Marshal.FreeHGlobal(riBuffer);
			} catch (System.Exception ex) {
                System.Diagnostics.Debug.WriteLine("Error Freeing Marshalled Buffer for RawInput data.");
                System.Diagnostics.Debug.WriteLine(ex.ToString());
			}
		}
	}
	public int lastWin32Error {
		get { return m_lastWin32Error; }
	}
	public string errorMessage {
		get { return m_errorMessage; }
	}






















}


//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: @telerik, @toddanglin
//Facebook: facebook.com/telerik
//=======================================================

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions