views:

413

answers:

2

Hi All,

I've written an app with a simple textbox which attempts to identify a user from their typing habits (interval between key presses, duration key is held, time between key strokes ie a->s is quicker than a->v for some users, shorter for others depending on typing style). It's far from perfect but it does correctly identify moderate-large differences in style.

I'm hoping to use this as a form of security monitor - If the typing style of the user doesn't fit a recognised pattern, report to a central server.

Of course, the next step in testing this is to begin to capture "regular" typing habits - ie when browsing, switching between apps, etc.

What I can't figure out how to do is capture keyboard input for all applications (excluding the login/welcome screen, alternate desktops, etc. - I have no reason to parse that and there's probably not enough input to analyse anyway)

Disclaimer: Yes, I know this comes dangerously close to writing a keylogger which is verboten but if I wanted to do that, I'd write a keyboard driver in C++ - I'm sure it would be far more streamlined and easier to obfuscate than a hulking .Net MSIL assembly. I have no doubt I'll be fending off "That's a keylogger" comments but I've hit a wall and need to ask somewhere...

I don't need the app to be hidden - but would ideally like to be able to capture input without explicit user confirmation (beyond installation by an admin) - If user confirmation is required, I can live with that (just) if it can be one-off and I have some way to monitor and report denials.

Is this even possible in .Net? The only examples I've been able to find either operate by adding an event hook to every key which seems clunky and I'd imagine is error-prone. -or- They poll the keyboard state to determine pressed keys. This is no good for me as a) I need exact timings of keypresses so key up/down events are a must and b) it's nasty.

It wouldn't surprise me if the framework is designed to specifically prohibit this in which case I'll have to fall back to some unmanaged code to provide the events. I'd obviously prefer to use managed code all the way.

Any help appreciated.

Edit: Thanks to Hans Passant's answer, this is the best resource I've found so far: http://www.codeguru.com/columns/vb/article.php/c4831

A: 

.net doesn't provide any services of that sort, so you will have to go lower and use p/invoke. Options are:

  • Win hooks
  • Polling using GetAsyncKeyState
Andrey
As mentioned, I don't think polling will be sufficient as I need key event info with the most accurate timing possible - and I either poll REALLY FAST (ie unreasonable CPU for a small background task) or more sedately in which case I lose timing resolution. With regards to Win Hooks, what exactly are you referring to? Global key hooks?
Basiclife
+3  A: 

Google SetWindowsHookEx + WH_KEYBOARD_LL, keywords that google well. That sets a low-level keyboard hook. It is not a global hook so can work in a VB.NET program.

Hans Passant
Thanks, that looks promising - Reading now :)
Basiclife
Many thanks, looks like exactly what I need - Do you happen to know if that would also pick up "simulated" keystrokes eg from a barcode scanner or card reader? I'd ideally like to avoid capturing those (but I can probably work around it if so as they "type" very quickly and at a consistent speed)
Basiclife
As long as they use SendInput (like they should) then, yes, you'll see that too.
Hans Passant