免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2071 | 回复: 0
打印 上一主题 下一主题

系统调用替换的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-15 19:29 |只看该作者 |倒序浏览
我编写了一个系统调用的替换的函数,sys_call_table在编译内核的时候已经用EXPORT_SYMBOL导出了,在2.6.20内核上这个模块可以正常工作,我这里不明白的是需不需要“set_fs(get_ds);”。
《Linux2.4.18内核下基于LKM的系统调用劫持》一文中写到:
-----------------------------------------------------------------------------------------------------------------
Linux使用了段选器来区分内核空间、用户空间等等。被系统调用所用到的而存放在用户空间中的参数应该在数据段选器(所指的)范围的某个地方。DS能够用asm/uaccess.h中的get_ds()函数得到。只要我们把被内核用来指向用户段的段选器设成所需要的 DS值,我们就能够在内核中访问系统调用所用到的(那些在用户地址空间中的)那些用做参数值的数据。这可以通过调用set_fs(...)来做到。但要小心,访问完系统调用的参数后,一定要恢复FS。下面是一段例子:
filename内核空间;比如说我们刚创建了一个字串

unsigned long old_fs_value=get_fs();
set_fs(get_ds);               /*完成之后就可以存取用户空间了*/
open(filename, O_CREAT|O_RDWR|O_EXCL, 0640);
set_fs(old_fs_value);         /*恢复 fs ...*/
-----------------------------------------------------------------------------------------------------------------

上面例子中“open”肯定是系统调用了,要用到“set_fs”。在下面代码“our_sys_open”函数中,“original_open”属不属于系统调用?它需不需要被set_fs包围起来?




syscall.c
-----------------------------------------------------------------------------------------------------------------
#include <linux/kernel.h>
#include <linux/module.h>

#define  __NR_open   5
#define  __NR_getuid 24  

extern void *sys_call_table[];

asmlinkage int (*original_open)(const char *, int, int);
asmlinkage int (*getuid_call)(void);

asmlinkage int our_sys_open(const char *filename, int flags, int mode)
{
    int uid;

    uid = getuid_call();
    printk("Opened file by %d.\n", uid);

    return original_open(filename, flags, mode);
}

int resyscall_init(void)
{   
    original_open = sys_call_table[__NR_open];
   
    sys_call_table[__NR_open] = our_sys_open;

    getuid_call = sys_call_table[__NR_getuid];

    return 0;
}

void resyscal_exit(void)
{
        
    if (sys_call_table[__NR_open] != our_sys_open)
    {
        printk("Aha,kernel hacking ");
    }

    sys_call_table[__NR_open] = original_open;
}

module_init(resyscall_init);
module_exit(resyscal_exit);
MODULE_LICENSE("GPL");
-----------------------------------------------------------------------------------------------------------------

makefile
-----------------------------------------------------------------------------------------------------------------
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
else
    obj-m := syscall.o
endif
-----------------------------------------------------------------------------------------------------------------
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP