Linux hook系统调用open/read/write

测试系统:

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 <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>

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也打印出来,发现会有问题。

猜你喜欢

转载自blog.csdn.net/qq_42931917/article/details/108887284