- 论坛徽章:
- 0
|
我编写了一个系统调用的替换的函数,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
----------------------------------------------------------------------------------------------------------------- |
|