首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 驱动开发 >

linux内核绑票 系统调用sys_write出现死机现象 请高手分析原因

2013-07-16 
linux内核劫持 系统调用sys_write出现死机现象请高手分析原因#include linux/kernel.h#include linux/i

linux内核劫持 系统调用sys_write出现死机现象 请高手分析原因
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/dirent.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/kallsyms.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
MODULE_LICENSE("Dual BSD/GPL");
#define _DEBUG
#ifdef _DEBUG
#define kprintk(fmt,args...) printk(KERN_EMERG fmt,##args)
#define kprintf(fmt,args...) printf(fmt,##args)
#define kperror(str) perror(str)
#else
#define kprintk
#define kprintf
#define kperror
#endif


long * g_sys_call_table=NULL;
long g_oldcr0=0;
asmlinkage long (*g_old_sys_write)(unsigned int fd, const char __user *buf, size_t count)=NULL;


struct _idtr{
    unsigned short  limit;
    unsigned int    base;
} __attribute__ ( ( packed ) );

struct _idt_descriptor
{
    unsigned short offset_low;
    unsigned short sel;
    unsigned char  none, flags;
    unsigned short offset_high;
} __attribute__((packed));

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

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

    /*clear the 20th bit of CR0,*/
    cr0 &= 0xfffeffff;
    asm volatile ("movl %%eax, %%cr0"
            :
            : "a"(cr0)
            );
    return ret;
}

void  open_cr(unsigned int oldval)


{
    asm volatile ("movl %%eax, %%cr0"
            :
            : "a"(oldval)
            );
}

long * get_sys_call_table(void)
{

    struct _idt_descriptor * idt;
    struct _idtr idtr;
    unsigned int sys_call_off;
    int sys_call_table=0;
    unsigned char* p;
    int i;

    asm("sidt %0":"=m"(idtr));
    printk("addr of idtr: 0x%x\n", (unsigned int)&idtr);
    idt=(struct _idt_descriptor *)(idtr.base+8*0x80);
    sys_call_off=((unsigned int )(idt->offset_high<<16)|(unsigned int )idt->offset_low);
    printk("addr of idt 0x80: 0x%x\n", sys_call_off);
    p=(unsigned char *)sys_call_off;
    for (i=0; i<100; i++)
    {
        if (p[i]==0xff && p[i+1]==0x14 && p[i+2]==0x85)
        {
            sys_call_table=*(int*)((int)p+i+3);
            kprintk("addr of sys_call_table: 0x%x\n", sys_call_table);
            return (long*)sys_call_table;
        }
    }
    return 0;
}
 
asmlinkage long my_sys_write(unsigned int fd, const char __user *buf, size_t count)
{
    g_old_sys_write(fd,buf,count);           
    return 0;

}


void start_hook(void)
{
    g_sys_call_table=get_sys_call_table();
 
    if(!g_sys_call_table)
    {
        kprintk ("get sys_call_table error");
        return;
    }
    if (g_sys_call_table[__NR_close] != (unsigned long)sys_close)


    {   
        kprintk("Incorrect sys_call_table address.\n");
        return ;
    }
    g_old_sys_write=g_sys_call_table[__NR_write];
    //hoot it
    g_oldcr0=close_cr();
    g_sys_call_table[__NR_write]= my_sys_write;
    open_cr(g_oldcr0);

}


int raider_init(void)
{

    kprintk("raider init\n");

    start_hook();
    return  0;
}

int restorehook(void)
{
    if(g_sys_call_table &&(long)g_old_sys_write)
    {
        g_oldcr0=close_cr();
        g_sys_call_table[__NR_write]=(long)g_old_sys_write;
        open_cr(g_oldcr0);
        g_old_sys_write=NULL;
        g_sys_call_table=NULL;
    }
    return 0;

}

void raider_exit(void)
{
    restorehook(); 
    kprintk("raider exit");



module_init(raider_init);
module_exit(raider_exit);



[解决办法]
有无backtrace看看?
[解决办法]
看可否打开内核kgdb支持,然后通过kgdb调试下,或者最简单的办法一句一句排除,看哪一句会导致死机。

热点排行