测试系统:
curtis@curtis-virtual-machine:~/Desktop$ uname -a
Linux curtis-virtual-machine 4.2.0-42-generic #49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Hook 系统调用我们先要知道sys_call_table地址,这个可以看之前文章,同时我们要了解sys_open的函数原型:
asmlinkage int (*original_open)( const char __user *, int , mode_t);
这次我们的目的是hook住sys_open并且打印被Hook sys_open被调用的路径和copy 路径的长度。
open_hook.c
/*
** hook_open.c for this function
**
**
*/
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Hook sys_call_open by change sys_open entry");
MODULE_AUTHOR("curtis");
void **sys_call_table_ptr;
unsigned long copied;
asmlinkage int (*original_open)( const char __user *, int , mode_t);
asmlinkage int new_open( const char __user * pathname, int flags, mode_t mode )
{
char user_msg[256];
printk("%s\n",__FUNCTION__);
memset(user_msg,0,sizeof(user_msg));
copied = strncpy_from_user(user_msg, pathname, sizeof(user_msg));
printk("copied:%ld\n", copied);
printk("pathname%s\n",user_msg);
printk("------\n");
return ( *original_open )( pathname, flags, mode );
}
static int __init open_hook_init(void)
{
write_cr0(read_cr0() & (~0x10000));
sys_call_table_ptr = (void**)kallsyms_lookup_name("sys_call_table");
original_open = sys_call_table_ptr[__NR_open];
sys_call_table_ptr[__NR_open] = new_open;
write_cr0(read_cr0() | (0x10000));
return 0;
}
static void __exit open_hook_exit(void)
{
write_cr0(read_cr0() & (~0x10000));
sys_call_table_ptr[__NR_open] = original_open;
write_cr0(read_cr0() | (0x10000));
printk("Bye bye open_hook\n");
}
module_init(open_hook_init);
module_exit(open_hook_exit);
Makefile:
ifeq ($(KERNELRELEASE),)
# Assume the source tree is where the running kernel was built
# You should set KERNELDIR in the environment if it's elsewhere
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
# The current directory is passed to sub-makes as argument
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
help:
$(MAKE) -C $(KERNELDIR) M=$(PWD) help
.PHONY: modules modules_install clean
else
# called from kernel build system: just declare our module
obj-m := open_hook.o
yolo-objs :=
endif
Hook 效果如下,dmesg打印文件路径
[ 1421.715076] new_open
[ 1421.715077] copied:31
[ 1421.715077] pathname/lib/x86_64-linux-gnu/libc.so.6
[ 1421.715077] ------
[ 1421.715219] new_open
[ 1421.715220] copied:13
[ 1421.715220] pathname/proc/cmdline
[ 1421.715221] ------
[ 1421.715239] new_open
[ 1421.715240] copied:31
[ 1421.715241] pathname/sys/module/open_hook/initstate
[ 1421.715241] ------
[ 1421.715257] new_open
[ 1421.715257] copied:28
[ 1421.715258] pathname/sys/module/open_hook/refcnt
[ 1421.715258] ------
[ 1421.715269] Bye bye open_hook
以此类推,我们可以添加hook sys_read sys_write 函数Hook的功能
asmlinkage int ( *original_write ) ( unsigned int, const char __user *, size_t );
asmlinkage int ( *original_read ) ( unsigned int, const char __user *, size_t );
asmlinkage int new_write( unsigned int fd, const char __user *buf, size_t count )
{
printk("%s\n",__FUNCTION__);
printk("------\n");
return ( *original_write )( fd, buf, count );
}
asmlinkage int new_read( unsigned int fd, const char __user *buf, size_t count )
{
printk("%s\n",__FUNCTION__);
printk("------\n");
return ( *original_read )( fd, buf, count );
}
本来是想要把系统调用所对应的buf也打印出来,发现会有问题。