Linux hook system call open/read/write

Test system:

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

For the Hook system call, we must first know the sys_call_table address, this can be seen in the previous article, and we must understand the function prototype of sys_open:

asmlinkage int (*original_open)( const char __user *, int , mode_t);

This time our purpose is to hook sys_open and print the path called by Hook sys_open and the length of the copy path.

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 effect is as follows, dmesg prints the file path

[ 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

By analogy, we can add the function of hook sys_read sys_write function 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 );
}

I wanted to print out the buf corresponding to the system call, but found that there would be problems.

Guess you like

Origin blog.csdn.net/qq_42931917/article/details/108887284