+ -
当前位置:首页 → 问答吧 → 用sys_call_table拦截进程读写操作cpu100%而且有些进程拦不到

用sys_call_table拦截进程读写操作cpu100%而且有些进程拦不到

时间:2011-11-03

来源:互联网

C/C++ code

#include <linux/init.h>
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/time.h>

#include <asm/unistd.h>
#include <linux/dcache.h>
#include <linux/fdtable.h>

#include <linux/limits.h>//for PATH_MAX
#include <linux/slab.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lorenzo Colitti <[email protected]>");

unsigned long *sys_call_table=0;

typedef asmlinkage ssize_t (*__routine)(int f, const void *buf, size_t n);
__routine old, new;

unsigned int clear_and_return_cr0(void);
void setback_cr0(unsigned int val);
int orig_cr0;



unsigned long* find_sys_call_table(void)
{
        struct {
                unsigned short  limit;
                unsigned int    base;
        } __attribute__ ( ( packed ) ) idtr;

        struct {
                unsigned short  offset_low;
                unsigned short  segment_select;
                unsigned char   reserved,   flags;
                unsigned short  offset_high;
        } __attribute__ ( ( packed ) ) * idt;

        unsigned long system_call = 0;        // x80中断处理程序system_call 地址
        char *call_hex = "\xff\x14\x85";        // call 指令
        char *code_ptr = NULL;
        char *p = NULL;
        unsigned long sct = 0x0;
        int i = 0;

        __asm__ ( "sidt %0": "=m" ( idtr ) );
        idt = ( void * ) ( idtr.base + 8 * 0x80 );
        system_call = ( idt->offset_high << 16 ) | idt->offset_low;

        code_ptr = (char *)system_call;
        for(i = 0;i < ( 100 - 2 ); i++) {
                if(code_ptr[i] == call_hex[0]
                                && code_ptr[i+1] == call_hex[1]
                                && code_ptr[i+2] == call_hex[2] ) {
                        p = &code_ptr[i] + 3;
                        break;
                }
        }
        if ( p ){
                sct = *(unsigned long*)p;
        }
        return (unsigned long*)sct;
}

unsigned int clear_and_return_cr0(void)
{
        unsigned int cr0 = 0;
        unsigned int ret;

        asm volatile("movl %%cr0, %%eax"
                        :"=a"(cr0)
                    );
        ret = cr0;
        cr0 &= 0xfffeffff;

        asm volatile("movl %%eax, %%cr0"
                        :
                        :"a"(cr0)
                    );
        return ret;
}
//恢复cr0
void setback_cr0(unsigned int val)
{
        asm volatile("movl %%eax, %%cr0"
                        :
                        :"a"(val)
                    );
}

asmlinkage ssize_t loggingread(int fd, const void *buf, size_t n) {
        int result = 0;
        struct task_struct *task = NULL;
        char *path = NULL,*ptr = NULL;
        char *read_buf = NULL;
        struct file* filp = NULL;
        mm_segment_t old_fs;


        task = current;
        read_buf = kmalloc(PATH_MAX,GFP_KERNEL);
        if (!read_buf)
        {
                printk("KK Read Buf Alloc Error!\r\n");
                return 0;
        }
        path = kmalloc(PATH_MAX,GFP_KERNEL);
        if (!path)
        {
                printk("KK Allocate Error\r\n");
                return 0;
        }

        
                //if (task && task->mm && task->mm->exe_file && task->mm->exe_file->f_path)
                if (task && task->mm && task->mm->exe_file) // && (task->mm->exe_file->f_path))
                {
                        //if (task->mm->exe_file->f_path)
                        {
                                ptr = d_path(&task->mm->exe_file->f_path,path,PAGE_SIZE);
                        }
                        //else
                        //{
                        // printk("KK path is NULL");
                        //}
                }
                else
                {
                        printk("task list NULL \r\n");
                }
                //task->mm->exe_file->f_path;
                printk("ProcName:%s PID:[%d]\n",task->comm,task->pid);
                printk(KERN_ALERT"PATH:%s\r\n",IS_ERR(ptr)?"NULL":ptr);    //此时ptr就是进程全路径名

                if (!IS_ERR(ptr))
                {
                        printk("Read FileName:%s \n",ptr);
                        filp = filp_open(ptr,O_RDONLY,0);  //打开进程文件
                        if (!filp)
                        {
                                printk("Open File:%s  Failture \n",ptr);
                        }  
                        else
                        {
                                printk("Open File:%s Successful \n",ptr);

                                old_fs = get_fs();
                                set_fs(get_ds());

                                if (filp->f_op && filp->f_op->read)
                                {
                                        result = filp->f_op->read(filp,read_buf,PAGE_SIZE,&filp->f_pos);  //读进程文件
                                }

                                if (0 == result)
                                {
                                        printk("Read File:%s Error \n",ptr);
                                }
                                else
                                {
                                        printk("Read File:%s Length:%d Success \n",ptr,result);

                                }



                                set_fs(old_fs);

                                filp_close(filp,NULL);
                                //read(filp,read_buf,PAGE_SIZE)
                        }
                }
                //printk("%x",task->thread);

                //printk("%d %d ",current->pid,t);


        kfree(read_buf);
        read_buf = NULL;
        kfree(path);
        path = NULL;

        printk(KERN_INFO"Loading the module ...KK\n");


        return ((__routine)old)(fd, buf, n);
}

static int __init readlog_init(void) {


        if (( sys_call_table = find_sys_call_table())) {
                printk(KERN_INFO "Loading readlog module, sys call table at %p\n", sys_call_table);

                old = (__routine)(sys_call_table[__NR_read]);
                new = &loggingread;
                orig_cr0 = clear_and_return_cr0();
                sys_call_table[__NR_read] = (ssize_t)new;
                setback_cr0(orig_cr0);
        }

        printk(KERN_INFO "Loading second readlog module, sys call table at %p\n", sys_call_table);

        return 0;
}

static void __exit readlog_exit(void) {
        printk(KERN_INFO "Unloading readlog module\n");
        orig_cr0 = clear_and_return_cr0();
        sys_call_table[__NR_read] = (ssize_t) old;
        setback_cr0(orig_cr0);

}

module_init(readlog_init);
module_exit(readlog_exit);


obj-m := linux_log.o
linux_log-objs := readlog.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
EXTRA_CFLAGS = -D__KERNEL__ -DMODULE -Wall 
#EXTRA_CFLAGS = -O2

PWD := $(shell pwd)
modules:
  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  rm -f *.o *.mod.c .*.cmd sysenter.h Module.symvers *.order
modules_install:
  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
  rm -rf *.o .*.cmd *.ko *.mod.c .tmp_vesions *.order *.symvers

我想对新的进程如vim读取某个的操作进程阻断。
这个测试的代码,读取不到vim 的操作,而且程序一运行cpu 100%。

作者: jameszhanglei123   发布时间: 2011-11-03

C/C++ code

#include <linux/init.h>
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/time.h>

#include <asm/unistd.h>
#include <linux/dcache.h>
#include <linux/fdtable.h>

#include <linux/limits.h>//for PATH_MAX
#include <linux/slab.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lorenzo Colitti <[email protected]>");

unsigned long *sys_call_table=0;

//typedef asmlinkage ssize_t (*__routine)(int f, const void *buf, size_t n);
typedef asmlinkage ssize_t (*__routine)(const char *pathname);
__routine old, new;

unsigned int clear_and_return_cr0(void);
void setback_cr0(unsigned int val);
unsigned int orig_cr0;



unsigned long* find_sys_call_table(void)
{
        struct {
                unsigned short  limit;
                unsigned int    base;
        } __attribute__ ( ( packed ) ) idtr;

        struct {
                unsigned short  offset_low;
                unsigned short  segment_select;
                unsigned char   reserved,   flags;
                unsigned short  offset_high;
        } __attribute__ ( ( packed ) ) * idt;

        unsigned long system_call = 0;        // x80中断处理程序system_call 地址
        char *call_hex = "\xff\x14\x85";        // call 指令
        char *code_ptr = NULL;
        char *p = NULL;
        unsigned long sct = 0x0;
        int i = 0;

        orig_cr0 = clear_and_return_cr0();
        __asm__ ( "sidt %0": "=m" ( idtr ) );
        setback_cr0(orig_cr0);
        idt = ( void * ) ( idtr.base + 8 * 0x80 );
        system_call = ( idt->offset_high << 16 ) | idt->offset_low;

        code_ptr = (char *)system_call;
        for(i = 0;i < ( 100 - 2 ); i++) {
                if(code_ptr[i] == call_hex[0]
                                && code_ptr[i+1] == call_hex[1]
                                && code_ptr[i+2] == call_hex[2] ) {
                        p = &code_ptr[i] + 3;
                        break;
                }
        }
        if ( p ){
                sct = *(unsigned long*)p;
        }
        return (unsigned long*)sct;
}

unsigned int clear_and_return_cr0(void)
{
        unsigned int cr0 = 0;
        unsigned int ret;

        asm volatile("movl %%cr0, %%eax"
                        :"=a"(cr0)
                    );
        ret = cr0;
        cr0 &= 0xfffeffff;

        asm volatile("movl %%eax, %%cr0"
                        :
                        :"a"(cr0)
                    );
        return ret;
}
//恢复cr0
void setback_cr0(unsigned int val)
{
        asm volatile("movl %%eax, %%cr0"
                        :
                        :"a"(val)
                    );
}

//asmlinkage ssize_t loggingread(int fd, const void *buf, size_t n) {
asmlinkage ssize_t loggingread(const char *pathname){
        int result = 0;
        struct task_struct *task = NULL;
        char *path = NULL,*ptr = NULL;
        char *read_buf = NULL;
        struct file* filp = NULL;
        mm_segment_t old_fs;


        //printk(KERN_ALERT"PATH:%s\n",buf);    //此时ptr就是进程全路径名

        printk("zhang \n");
        return -1;

        //return ((__routine)old)(fd, buf, n);
}

static int __init readlog_init(void) {


        if (( sys_call_table = find_sys_call_table())) {
                printk(KERN_INFO "Loading readlog module, sys call table at %p\n", sys_call_table);

                old = sys_call_table[__NR_unlink];
                //old = (__routine)(sys_call_table[__NR_unlink]);
                printk(KERN_INFO "Loading readlog module, old at %p\n", old);
                new = &loggingread;
                orig_cr0 = clear_and_return_cr0();
                sys_call_table[__NR_unlink] = (ssize_t)new;
                setback_cr0(orig_cr0);
        }

        printk(KERN_INFO "Loading second readlog module, sys call table at %p\n", sys_call_table);

        return 0;
}

static void __exit readlog_exit(void) {
        printk(KERN_INFO "Unloading readlog module\n");
        orig_cr0 = clear_and_return_cr0();
        sys_call_table[__NR_unlink] = (ssize_t) old;
        setback_cr0(orig_cr0);

}

module_init(readlog_init);
module_exit(readlog_exit);


sys_call_table地址求对了,截获不了unlink操作

touch ./abc.txt
rm -f abc.txt
没有作用,仍然能删除,而且dmesg没有zhang这个字符串

作者: jameszhanglei123   发布时间: 2011-11-03