运行环境:Ubuntu18.04 x64,Linux version 5.4.0-8,VMware 16 Pro
主要参考文章:,针对代码的整体
次要参考文章:,针对部分错误
创建 .c文件 和 Makefile,代码见底部。
编译好后,sudo insmod hello.ko 添加模块
可以看到,mkdir 原来的作用已经没了。输入 tail /var/log/kern.log 查看输出。
sudo rmmod hello 移除模块,mkdir 恢复原来的功能。
注意:
64位系统中:movl 改为 movq,eax 改为 rax
宏定义 SYS_TAB 值的前8位(ffffffff)要保留,并且每次重启系统后都要再次更改地址
.c 文件名要和 Makefile 的第一行输出 .o 文件名一致
hello.c 文件
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/syscalls.h>//若要打印相关目录,则需要包含以下的头文件
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/dcache.h>
#include <linux/path.h>
#include <linux/slab.h>//利用内核编程,必须包含该宏定义
MODULE_LICENSE("GPL");//用sudo cat /proc/kallsyms | grep sys_call_table 获取 sys_call_table 的内核地址
//注意:每次重启内核必须再次获取地址
#define SYS_TAB 0xffffffff9dc013c0//指向系统调用数组
unsigned long* sys_call_table = (unsigned long*)SYS_TAB;
int (*orig_mkdir)(void);unsigned int clear_and_return_cr0(void);
void setback_cr0(unsigned int val);
unsigned int orig_cr0;int my_mkdir(void)
{//获取当前进程的idint pid = current->pid;//获取当前进程的父进程idint 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 "Warnning Someone(PID=%d,parent=%d) attempts to mkdir!n",pid,ppid);printk(KERN_WARNING "ROOT:%s!n",ppwd);printk(KERN_WARNING "PWD:%s!n",pwd.dentry->d_name.name);return 0;
}unsigned int clear_and_return_cr0(void)
{unsigned int cr0 = 0;unsigned int ret;asm volatile ("movq %%cr0, %%rax": "=a"(cr0));ret = cr0;cr0 &= 0xfffeffff;asm volatile ("movq %%rax, %%cr0"::"a"(cr0));return ret;
}void setback_cr0(unsigned int val)
{asm volatile ("movq %%rax, %%cr0": : "a"(val));
}int hello_init(void)
{printk(KERN_INFO "Hello kernel!n"); //清cr0的WP位orig_cr0 = clear_and_return_cr0();//保存原系统调用orig_mkdir=(int (*)(void))sys_call_table[__NR_mkdir];//替换成我们自己的函数sys_call_table[__NR_mkdir]=(unsigned long)my_mkdir;//为了内核安全,恢复cr0的WP位setback_cr0(orig_cr0);return 0;
}void hello_exit(void)
{printk("Bye, kernel!");orig_cr0 = clear_and_return_cr0();sys_call_table[__NR_mkdir]=(unsigned long)orig_mkdir;setback_cr0(orig_cr0);
}module_init(hello_init);
module_exit(hello_exit);
Makefile
obj-m := hello.oall:$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
本文发布于:2024-02-04 20:52:40,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170716162159506.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |