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调试下,或者最简单的办法一句一句排除,看哪一句会导致死机。