最刺激的添加内核系统调用的方法就是hack sys_call_table 了 ^_^

它的基本思想就是

1 找到 sys_call_table 的地址; 

2 保存其中某项内容,比如 sys_call_table[__NR_mkdir]
  以便hack后恢复;
3 修改 sys_call_table[__NR_mkdir]
  使其指向自己实现的系统调用函数

这样做之后,系统调用mkdir就被你hack了 呵呵 是不是很爽 

来来来 
咱们实现一下

代码 

hack_sys_call.c

 #include <linux/kernel.h> 

 #include <linux/module.h> 
 #include <linux/init.h> 
 #include <linux/sched.h> 
 #include <asm/unistd.h>

 MODULE_LICENSE("GPL");  

 MODULE_DESCRIPTION("Different from others, this module automatically locate the entry of sys_call_table !");

 unsigned long *sys_call_table=NULL; 

 asmlinkage int (*orig_mkdir)(const char *,int);

 struct _idt 

 {
 
   unsigned short offset_low;
   unsigned short segment_sel; 
   unsigned char  reserved;
   unsigned char  flags; 
   unsigned short offset_high; 
 };

 unsigned long *getscTable()

 {
 
         unsigned char idtr[6],*shell,*sort; 
         struct _idt *idt; 
         unsigned long system_call,sct; 
         unsigned short offset_low,offset_high; 
         char *p; 
         int i;                                                                                                                 
         
               /* get the interrupt descriptor table */ 
                                                                                                                              
         __asm__("sidt %0" : "=m" (idtr)); 
                                                                                                                              
         /* get the address of system_call */ 
         idt=(struct _idt*)(*(unsigned long*)&idtr[2]+8*0x80); 
         offset_low = idt->offset_low; 
         offset_high = idt->offset_high; 
         system_call=(offset_high<<16)|offset_low; 
                                                                                                                              
         shell=(char *)system_call; 
         sort="/xff/x14/x85"; 
                                                                                                                              
         /* get the address of sys_call_table */ 
    
         for(i=0;i<(100-2);i++) 
                 if(shell[i]==sort[0]&&shell[i+1]==sort[1]&&shell[i+2]==sort[2]) 
                         break;                                                                                                

                            

         p=&shell[i]; 
         p+=3; 
         sct=*(unsigned long*)p; 
        
         return (unsigned long*)(sct); 
 }

 asmlinkage int hacked_mkdir(const char * pathname, int mode)

 {
 
         printk("PID %d called sys_mkdir !/n",current->pid); 
         return orig_mkdir(pathname,mode); 
 }

 static int __init find_init(void)

 {
 
         sys_call_table = getscTable(); 
         orig_mkdir=(int(*)(const char*,int))sys_call_table[__NR_mkdir]; 
         sys_call_table[__NR_mkdir]=(unsigned long)hacked_mkdir; 
         return 0; 
 }

 static void __exit find_cleanup(void)

 {
 
         sys_call_table[__NR_mkdir]=(unsigned long)orig_mkdir; 
 }

 module_init(find_init); 

 module_exit(find_cleanup);

  
Makefile

CC=gcc

INCLUDEDIR = /usr/src/linux-2.4/include
MODCFLAGS :=-Wall -O -DMODULE -D__KERNEL__ -DLINUX -I$(INCLUDEDIR)
hack_sys_call.o: hack_sys_call.c 
 $(CC) $(MODCFLAGS) -c hack_sys_call.c

 

  getscTable()是在内存中查找sys_call_table地址的函数。
  每一个系统调用都是通过int 0x80中断进入核心,中断描
  述符表把中断服务程序和中断向量对应起来。对于系统调
  用来说,操作系统会调用system_call中断服务程序。
  system_call函数在系统调用表中根据系统调用号找到并
  调用相应的系统调用服务例程。idtr寄存器指向中断描述
  符表的起始地址,用sidt[asm ("sidt %0" : "=m" (idtr));]
  指令得到中断描述符表起始地址,从这条指令中得到的指针
  可以获得int 0x80中断服描述符所在位置,然后计算出
  system_call函数的地址。反编译一下system_call函数可以
  看到在system_call函数内,是用call sys_call_table指令
  来调用系统调用函数的。因此,只要找到system_call里
  的call sys_call_table(,eax,4)指令的机器指令就可以获得
  系统调用表的入口地址了
  
  在2.4和2.6之前的内核中,sys_call_table是可以直接导出的
  挺危险的 ^_^