- 编写驱动模块进行
sys_call_table
hook 替换sys_open
和sys_openat
系统调用为自定义函数,需要注意sys_call_table
是只读的,修改前需要前修改其内存属性为可写。 - 直接修改内核源码,并编写驱动模块实现filter function进行过滤。
sys_call_table
hook只能对系统调用函数进行hook。而第二种方式,直接修改内核源码并为其编写一个内核模块可以实现对内核中任意函数的hook(实际就是在源码的基础上实现内核inline hook)。因为实现文件重定位需要对sys_open
和sys_openat
这两个系统调用进行hook,而这两个函数都会调用do_sys_open
函数,所以可以直接对此函数进行修改。
hook sys_do_file
定义一个函数指针filter_do_sys_open
并导出,然后在sys_do_file
函数头部插入代码调用此函数,如果filter_do_sys_open
函数返回-1则直接返回,否则正常调用sys_do_file
函数。
编写驱动模块的代码(hook_do_sys_hook.c),利用kallsyms_lookup_name
函数获取导出的filter_do_sys_open
,然后修改其为自定义的filter函数my_filter_do_sys_open
。my_filter_do_sys_open
函数判断当前打开的文件是否为/data/local/tmp/as
,如果是就直接返回-1阻止此文件被打开。也可以通过修改参数pathname
的值实现文件的重定位。
#include "asm/pgtable-types.h"
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cred.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/kallsyms.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
MODULE_LICENSE("GPL");
long my_filter_do_sys_open(int dirfd, const char __user* pathname, int flags,umode_t modex)
{
long ret = -1;
char *kbuf = (char*)kmalloc(256,GFP_KERNEL);
strncpy_from_user(kbuf, pathname, 255);
printk("do_sys_open : %s\n", kbuf);
if (strcmp(kbuf, "/data/local/tmp/as") == 0) {
printk("hide file : /data/local/tmp/as\n");
return ret;
}
kfree(kbuf);
return 0;
}
static void** p_filter_do_sys_open;
static int __init hook_init(void){
printk("hook_openat is load success\n");
p_filter_do_sys_open = (void*)kallsyms_lookup_name("filter_do_sys_open");
*(unsigned long*)p_filter_do_sys_open = (unsigned long)my_filter_do_sys_open;
return 0;
}
static void hook_exit(void)
{
*p_filter_do_sys_open = 0;
printk("hook_openat is unload\n");
}
module_init(hook_init);
module_exit(hook_exit);
驱动模块编译
首先编译内核源码https://www.cnblogs.com/revercc/p/17250070.html,然后在内核源码路径private\msm-google\drivers
文件夹中新建一个文件夹用来存放自己的内核模块源码,这里创建文件夹名称为my_ko_module
,然后在此文件中在新建一个文件夹hook_do_sys_open
文件夹用来存放hook do_sys_open
函数的驱动模块源码。
在hook_do_sys_open
中添加驱动模块的源文件hook_do_sys_hook.c
,并且增加Kconfig
和Makefile
文件,两个文件内容如下。
# Kconfig
config HOOK_DO_SYS_OPEN
tristate "hook do_sys_open"
help
in kernel
# Makefile
obj-$(CONFIG_HOOK_DO_SYS_OPEN)+=hook_do_sys_open.o
修改my_ko_module
的上层目录中的Kconfig
文件,增加source "drivers/my_ko_module/hook_do_sys_open/Kconfig"
修改my_ko_module
的上层目录中的Makefile
文件,增加obj-y += my_ko_module/hook_do_sys_open/"
如果想将驱动编译成外部模块(ko)的话需要在内核编译时使用的配置文件中(这里是floral_defconfig文件)增加CONFIG_HOOK_DO_SYS_OPEN=m
配置,如果想将驱动模块编译进内核就需要修改配置为CONFIG_HOOK_DO_SYS_OPEN=y
。
然后重新编译内核即可得到驱动模块hook_do_sys_open.ko
。
测试
insmod hook_do_sys_open.ko
加载驱动模块后,cat /data/local/tmp/as
查看文件返回Operation not permitted拒绝操作,查看内核日志可以看到此次文件打开操作已被阻止。