第一种方案:
用sys_open,sys_read,sys_close
需要包含头文件:
#include <linux/types.h>
#include <linux/syscalls.h> /* sys_open, sys_read; sys_close */
#include <linux/module.h>
#include <linux/init.h>
编译 通过,但在insmod模块的时候,却提示:
Unknown symbol sys_open. (有可能在内核空间,看不到这个导出的函数,怎么办?)
师兄告诉一种方法:
在本模块中,自己声明相应的函数指针。比如
asmlinkage long (*sys_open1)(const char __user *filename, int flags, int mode);
在/proc/kallsyms中
找到sys_open对应的函数地址 fffffffffff8000088887
在代码中 直接 sys_open1 = (void*)fffffffffff8000088887 这样就可以调用那个函数了。
测试,提示返回的文件描述符有问题。 提示错误:EFAULT(bad address),也就是说这个地址就不能在内核空间使用。
补充: 后来师兄自己用这种方法调用了内核的另外一个函数,可以使用。
原因分析: “asdmlinkage” 这个标记说明这个函数的参数,必须来自栈。而师兄使用的那个函数,参数来自寄存器,所以。。。
利用objdump -D 文件名 > dump.txt反汇编看一下,就可以知道,参数来自寄存器,还是来自栈
在网上找到一种方法 “Linux下实现劫持系统调用”。网址如下:
http://doc.chinaunix.net/linux/201008/773478.shtml
第二种方案:
利用filp_open, filp_close。实例代码如下:(来自http://hi.chinaunix.net/?11868/viewspace-31223)
nt test(void){
char buf[100];
int i;
int count=0;
// do{
printk(”mmc_blk_remove() Open /var/run/SD_mount_record!”);
struct file *phMscd_Filp = NULL;
for(i=0;i<100;i++)
buf[i] = 0;
phMscd_Filp = filp_open(”/var/run/SD_mount_record”, O_RDWR | O_LARGEFILE, 0);
if (phMscd_Filp == NULL)
{
printk(KERN_ALERT “filp_open error!!./n”);
}
mm_segment_t old_fs=get_fs();
set_fs(get_ds());
phMscd_Filp->f_op->read(phMscd_Filp, buf, 2, &phMscd_Filp->f_pos);
set_fs(old_fs);
printk(”buf:%s/n”,buf);
filp_close(phMscd_Filp,NULL);
return 1;
}