编写自己的系统调用 替换系统调用 已open()为例
hello.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
#include <asm/current.h>
#include <linux/syscalls.h>
#include <linux/fs.h>
#include <linux/fcntl.h>
#include <linux/file.h>
#include <asm/unistd.h>
#include <linux/fs_struct.h>
#include <linux/dcache.h>
#include <linux/path.h>
static char readbuf[100];
static char writebuf[100];
static unsigned long * sys_call_table ;
asmlinkage int (*original_open) (const char*, int, int);
asmlinkage int custom_open (const char* __user file_name, int flags, int mode);
static int __init hello_init ( void )
{
sys_call_table = NULL;
sys_call_table = (unsigned long *)kallsyms_lookup_name("sys_call_table");
write_cr0 (read_cr0 () & (~ 0x10000));
original_open = (void *)sys_call_table[__NR_open];
sys_call_table[__NR_open] = custom_open;
write_cr0 (read_cr0 () | 0x10000);
printk ( KERN_INFO "hello module loaded successfully \n");
return 0;
}
static void __exit hello_exit ( void )
{
write_cr0 (read_cr0 () & (~ 0x10000));
sys_call_table[__NR_open] = original_open;
write_cr0 (read_cr0 () | 0x10000);
printk ( KERN_INFO "hello module unloaded\n" );
}
asmlinkage int custom_open (const char* __user file_name, int flags, int mode)
{
copy_from_user(writebuf, file_name, 80);
printk ( KERN_INFO "hello %s\n", writebuf);
printk ( KERN_INFO "hello custom_open successfully %d- %d \n",flags, mode);
//获取当前进程的id
int pid = current->pid;
//获取当前进程的父进程id
int ppid = current->real_parent->real_parent->pid;
//获取当前进程的根目录
const char *ppwd = (current->fs->root).dentry->d_name.name;
struct path pwd;
//获取当前目录
get_fs_pwd(current->fs,&pwd);
printk(KERN_WARNING "helloa PID=%d,parent=%d attempts to open!\n",pid,ppid);
printk(KERN_WARNING "helloa ROOT:%s!\n",ppwd);
printk(KERN_WARNING "helloa PWD:%s!\n",pwd.dentry->d_name.name);
return original_open( file_name , flags, mode);
}
MODULE_LICENSE ( "GPL" );
module_init ( hello_init );
module_exit ( hello_exit );
Makefile 文件
obj-m:=hello.o
PWD:= $(shell pwd)
KERNELDIR:= /usr/src/linux-3.10.0-957.el7
EXTRA_CFLAGS= -O0
CONFIG_MODULE_SIG=n
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
把文件放在/opt/hello目录
cd /opt/hello 目录
执行 make...
报错 *** 没有规则可以创建“/opt/hello/hello.o”需要的目标“tools/objtool/objtool”。 停止。
切换 /usr/src/linux-3.10.0-957.el7 执行如下指令
yum install elfutils-libelf-devel
make mrproper
make oldconfig
make prepare
make scripts
继续 进入 /opt/hello 执行 make clean & make
生成hello.ko 文件
执行 insmod hello.ko 注册模块
执行 dmesg | tail 可以查看 日志
执行rmmod hello 卸载模块