系统调用和快速系统调用

来源:互联网 发布:ugui源码调试 编辑:程序博客网 时间:2024/05/23 11:25
欢迎访问小站,阅读原文http://www.yandong.org/archives/519

介绍

 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。

从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——它好比一个中间人,把用户进程的请求传达给内核,待内核把请求处理完毕后再将处理结果送回给用户空间。

什么是快速系统调用

    在产生一个中断(广义的中断,包括硬中断、软中断、异常)后,处理器中控制器会进行一系列权限检查,只有得到核实后,控制单元才设置中断处理所需要的执行环境。基于软中断int 0×80的系统调用同样也需要作一系列的检查,才能进入内核态进行系统调用的处理工作。

    由于系统调用的特点,这一系列权限检查变得多余。为此Intel在Pentium II处理器中引入了一对新的指令SYSENTER/SYSEXIT,用于实现快速系统调用;其中指令SYSENTER用于进入内核态,而指令SYSEXIT用于从内核态返回。这两条该指令避免了权限检查,直接将处理器置为预定义的运行级别(基于软中断的系统调用需要从门描述符中获得运行级别信息)。同时,通过将系统调用所需的执行环境信息保存在一组型号相关寄存器(Model Specific Register,简称MSR)中,避免了访问内存,进一步提高进入内核态的速度。下面分小节对快速系统调用进行全面的介绍和分析。

如何检查系统是否支持快速系统调用呢?

static int my_init_module(void){if (!boot_cpu_has(X86_FEATURE_SEP))        {                printk(KERN_ERR "NOT SUPPORT \n");return 0;}printk(KERN_ERR "SUPPORT \n");        return 0;} 



修改linux系统调用

原理: 系统调用都在sys_call_table的表里面,修改这个表里面的东西可以达到修改系统调用的目的,

另外获取sys_call_table地址的一个简单方式是在/boot/system.map里面查找

#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/file.h>#include <linux/fs_struct.h>#include <linux/fdtable.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/syscalls.h>#include <linux/list.h>#include <linux/jiffies.h>#include <linux/cdev.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include <linux/path.h>#include <linux/time.h>#include <linux/stat.h>#include <net/sock.h>#include <net/inet_sock.h>#include <asm/cpufeature.h>#define MY_FILE "/root/linux_kernel_info"static int my_init_module(void);static void my_cleanup_module(void);unsigned int clear_and_return_cr0(void);void setback_cr0(unsigned int val);unsigned long **sys_call_table = (unsigned long **)0xc0509940;int orig_mkdir;unsigned int orig_cr0;/** * 清除写保护*/unsigned int clear_and_return_cr0(void){    unsigned int cr0 = 0;    unsigned int ret;    asm volatile ("movl %%cr0, %%eax"              : "=a"(cr0)              );    ret = cr0;    /* clear the 20 bit of CR0, a.k.a WP bit */    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)              );}int hacked_mkdir(const char __user *pathname, int mode){printk(KERN_ALERT "mkdir do nothing\n", MY_FILE);return 0; /*everything is ok, but he new systemcall does nothing*/}static int my_init_module(void){printk(KERN_ALERT "sys_call_table %x\n", sys_call_table);orig_mkdir=(int)(sys_call_table[__NR_mkdir]);printk(KERN_ALERT "sys_call_table %x\n", orig_mkdir);orig_cr0 = clear_and_return_cr0();   //清除写保护 sys_call_table[__NR_mkdir]=(void *)hacked_mkdir;    setback_cr0(orig_cr0);    return 0;}static void my_cleanup_module(void){    printk(KERN_ALERT "Module %s unloaded.\n", MY_FILE);orig_cr0 = clear_and_return_cr0(); sys_call_table[__NR_mkdir]=(void *)orig_mkdir; /*set mkdir syscall to the origal one*/setback_cr0(orig_cr0);}module_init(my_init_module);module_exit(my_cleanup_module);MODULE_LICENSE("GPL");MODULE_AUTHOR("Nilushan Silva");MODULE_DESCRIPTION("task_struct offset Finder");

屏幕截图_060313_070553_PM

获取sys_call_table的方式

链接

http://www.ibm.com/developerworks/cn/linux/kernel/l-k26ncpu/

http://book.51cto.com/art/200810/93833.htm

http://blog.csdn.net/misterliwei/article/details/4351592

待续。。。

原创粉丝点击