linux中导出sys_call_table解决方法

来源:互联网 发布:侯景之乱 知乎 编辑:程序博客网 时间:2024/05/19 21:00

最近在学linux-kernel编程,刚看到改写系统函数。

文章介绍说,在2.4内核中,可以直接导出sys_call_table,这样的话,很容易在改变系统函数从而做邪恶的事。

但是从2.6开始,sys_call_table便不再可以导出了。这样就带来了问题。于是就解决吧。。。

查了很多网址,有的说可以通过/dev/kmem文件查找。但是在我的

>>>uname -a

>>> Linux localhost.localdomain 2.6.18-308.4.1.el5 #1 SMP Tue Apr 17 17:08:10 EDT 2012 i686 i686 i386 GNU/Linux

中,根本就没有该文件。

于是google之。


终于找到了,通过/boot/System.map-2.6.18-308.4.1.el5文件查找。

>>>grep sys_call_table System.map-2.6.18-308.4.1.el5

>>>c06294e0 R sys_call_table

开头的第一列就是sys_call_table在内核中的地址。

于是就有了第一版的代码。


但是。。。

insmod模块时,系统oops了。


仔细看

>>>grep sys_call_table System.map-2.6.18-308.4.1.el5

>>>c06294e0 R sys_call_table

R,是只读属性。

想办法改之,继续google之。

终于有了现有的代码。

http://stackoverflow.com/questions/2103315/linux-kernel-system-call-hooking-example

在上述url中,有一处与我的centos不一致,

那就是我的centos中没有set_memory_rw/set_memory_ro函数,

但是我从/usr/src/...include中查到了change_page_attr函数。

试试,好使。

于是有了最终版本,测试OK

=====================================================================================

代码:

test.c

      1 #include <linux/kernel.h>
      2 #include <linux/module.h>
      3 #include <linux/moduleparam.h>
      4 #include <linux/unistd.h>
      5 #include <asm/cacheflush.h>
      6
      7 #include <linux/sched.h>
      8 #include <asm/uaccess.h>
      9
     10 #ifdef KERN_2_6_24
     11 #include <asm/semaphore.h>
     12 #else
     13 #include <asm-i386/cacheflush.h>
     14 #endif
     15
     16 static int set_page_rw(long unsigned int _addr)
     17 {
     18         struct page* pg;
     19         pgprot_t prot;
     20         pg = virt_to_page(_addr);
     21         prot.pgprot = VM_READ| VM_WRITE;
     22         return change_page_attr(pg, 1, prot);
     23 }
     24
     25 static int set_page_ro(long unsigned int _addr)
     26 {
     27         struct page* pg;
     28         pgprot_t prot;
     29         pg = virt_to_page(_addr);
     30         prot.pgprot = VM_READ;
     31         return change_page_attr(pg, 1, prot);
     32 }
     33
     34 static unsigned long **sys_call_table;
     35 static int uid;
     36 module_param(uid, int, 0644);
     37
     38 asmlinkage int (*original_call)(const char*, int, int);
     39
     40 asmlinkage int our_sys_open(const char* filename, int flags, int mode)
     41 {
     42         int i = 0;
     43         char ch;

     44         printk("\n\n\n\n\n\n\n\n\n\n\n\n\n");
     45         if(uid == current->uid){
     46                 printk("Opened file by %d\n", uid);
     47                 do{
     48                         get_user(ch, filename+i);
     49                         i++;
     50                         printk("%c",ch);
     51                 }while(ch != 0);
     52         }
     53         return original_call(filename, flags, mode);
     54 }
     55
     56 int init_module()
     57 {
     58         int ret = 0;
     59         printk(KERN_ALERT "I'm dangerous. I hope you did a ");
     60         printk(KERN_ALERT "sync before you insmod'ed me.\n");
     61         printk(KERN_ALERT "My counterpart, cleanup_module(), is even");
     62         printk(KERN_ALERT "more dangerous. If\n");
     63         printk(KERN_ALERT "you value your file system, it will ");
     64         printk(KERN_ALERT "be \"sync; rmmod\" \n");
     65         printk(KERN_ALERT "when you remove this module.\n");
     66
     67         sys_call_table = (unsigned long **)0xc06294e0;
     68         ret = set_page_rw((long unsigned int)sys_call_table);
     69         original_call = (int(*)(const char*, int,int))sys_call_table[__NR_open];
     70         sys_call_table[__NR_open] = (long*)our_sys_open;
     71
     72         printk(KERN_INFO "Spying on UID:%d\n", uid);
     73         ret = 0;
     74         return ret;
     75 }
     76
     77 void cleanup_module()
     78 {
     79         if (sys_call_table[__NR_open] != our_sys_open) {
     80                 printk(KERN_ALERT "Somebody else also played with the ");
     81                 printk(KERN_ALERT "open system call\n");
     82                 printk(KERN_ALERT "The system may be left in ");
     83                 printk(KERN_ALERT "an unstable state.\n");
     84         }
     85
     86         sys_call_table[__NR_open] = original_call;
     87         set_page_ro(sys_call_table);
     88 }

=====================================================================================

Makefile:

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 18
EXTRAVERSION = -238.19.1.el5
RHEL_MAJOR = 5
RHEL_MINOR = 6
NAME=Avast! A bilge rat!

obj-m += test.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

=====================================================================================

原创粉丝点击