Linux:内核模块实现替换系统调用的简单例子
来源:互联网 发布:排八字软件 编辑:程序博客网 时间:2024/04/30 11:04
原文链接:http://blog.csdn.net/ddk3001/article/details/51485135
编写Linux内核模块,可以实现替换系统调用功能。
本文提供一个替换open系统调用的样例代码,功能和说明见代码。
参考代码:https://github.com/ricardoteixas/hook
在 https://github.com 中搜索 hook、kernel等,可以搜到很多可参考的代码。
/***************************************************************************文件 : hook_open.c功能 : 这是一个简单的内核模块,功能是替换了系统调用oepn,实现自定义open功能。关键函数 :my_sys_open // 自定义的open系统调用处理函数syscall_init // 内核模块初始化函数syscall_release // 内核模块退出函数源代码参考 : https://github.com/ricardoteixas/hook***************************************************************************/#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/syscalls.h>#include <linux/delay.h> #include <linux/sched.h>#include <linux/version.h>/**************************************************************************////**************************************************************************/// Write Protect Bit (CR0:16)#define CR0_WP 0x00010000 MODULE_LICENSE("GPL");void **syscall_table;unsigned long **find_sys_call_table(void);// !!!!!asmlinkage long (*orig_sys_open)(const char __user *filename, int flags, umode_t mode);/*************************************************************************** * /boot/System.map-3.13.0-43-generic: * * ffffffff811bb230 T sys_close * ffffffff81801400 R sys_call_table * ffffffff81c15020 D loops_per_jiffy * **************************************************************************/unsigned long **find_sys_call_table(){ unsigned long ptr; unsigned long *p; for (ptr = (unsigned long) sys_close; ptr < (unsigned long) &loops_per_jiffy; ptr += sizeof(void *)) { p = (unsigned long *) ptr; if (p[__NR_close] == (unsigned long) sys_close) { return (unsigned long **) p; } } return NULL;}/**************************************************************************///// 自定的open系统调用函数: 如果要打开的是 /home/test1.txt,则改为打开 /home/test2.txt//// 关键函数: strncpy_from_user 、 set_fs 、set_fs///**************************************************************************/asmlinkage long my_sys_open( const char __user *filename, int flags, umode_t mode ){ char temp[256] = { 0 }; char *test2 = "/home/test2.txt"; // 需要把用户空间的数据拷贝到内核空间,才能使用 (void)strncpy_from_user( temp, filename, PATH_MAX ); if ( !strcmp( temp, "/home/test1.txt" ) ) { mm_segment_t fs_save; long ret; // get_fs 和 set_fs 是为了使系统调用函数能够访问内核空间数据(本来参数应该是用户空间数据) // 关于 get_fs 和 set_fs,参考: http://blog.chinaunix.net/uid-27717694-id-4076498.html fs_save = get_fs(); set_fs( get_ds() ); ret = orig_sys_open( (const char __user *)test2, flags, mode ); set_fs( fs_save ); return ret; } return orig_sys_open(filename, flags, mode);}/**************************************************************************///// 内核模块初始化函数///**************************************************************************/static int __init syscall_init(void){ unsigned long cr0; printk(KERN_DEBUG "Let's do some magic!\n"); syscall_table = (void **) find_sys_call_table(); if (! syscall_table) { printk(KERN_DEBUG "ERROR: Cannot find the system call table address.\n"); return -1; } printk(KERN_DEBUG "Found the sys_call_table at %16lx.\n", (unsigned long) syscall_table); cr0 = read_cr0(); write_cr0(cr0 & ~CR0_WP); printk(KERN_DEBUG "Houston! We have full write access to all pages. Proceeding...\n"); orig_sys_open = syscall_table[__NR_open]; syscall_table[__NR_open] = my_sys_open; write_cr0(cr0); return 0;}/**************************************************************************///// 内核模块退出函数///**************************************************************************/static void __exit syscall_release(void){ unsigned long cr0; printk(KERN_DEBUG "I hate you!\n"); cr0 = read_cr0(); write_cr0(cr0 & ~CR0_WP); syscall_table[__NR_open] = orig_sys_open; //syscall_table[__NR_access] = orig_sys_access; write_cr0(cr0);}/**************************************************************************////**************************************************************************/module_init(syscall_init);module_exit(syscall_release);
下面是Makefile文件内容:
# Makefileobj-m:=hook_open.o KERNELBUILD:=/lib/modules/$(shell uname -r)/build default: make -C $(KERNELBUILD) M=$(shell pwd) modulesclean: rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers .tmp_versions
编译模块 : make
编译清除:make clean
安装模块 : sudo insmod hook_open.ko
卸载模块 : sudo rmmod hook_open
查看模块 : lsmod | grep hook_open
0 0
- Linux:内核模块实现替换系统调用的简单例子
- Linux:内核模块实现替换系统调用的简单例子
- linux内核模块替换系统调用
- 一个简单的Linux内核模块实现
- 【Linux】【Kernel】一个简单的内核模块例子
- 模块替换方式实现添加系统调用
- Linux内核:getpid系统调用的实现
- Linux内核模块编程--系统调用
- Linux内核模块编程-系统调用拦截
- Linux内核中 如何动态替换系统调用函数
- linux内核文件IO的系统调用实现分析
- Linux内核的设计与实现 读书笔记(5)系统调用
- linux内核文件IO的系统调用实现分析(open)
- 《Linux内核设计与实现》--系统调用
- linux内核设计与实现:系统调用
- 简单的Linux内核模块示例
- 一个简单的Linux内核模块
- 编写一个简单的linux内核模块
- leetcode 318. Maximum Product of Word Lengths-最长单词积|位运算
- View的三大流程之View的测量
- azure云上 在线将oracle单实例扩展成oracle dataguard高可用集群的详细过程
- MySQL学习
- Android6.0 权限申请封装
- Linux:内核模块实现替换系统调用的简单例子
- C# 调用TTS 并输出WAV
- cookie案例-显示用户上次访问网站的时间
- 垃圾收集器与内存分配策略
- 滴滴打车2015-2016
- Android 5.x(一) 新控件之RecyclerView,CardView,Palette的使用
- malloc realloc失败原因解析
- C++实验六—矩阵求和
- java基础 -- 多线程总结(一)--基本概念