实验环境:linux 2.6.32   64位系统

采用lkm(动态加载内核模块)方式劫持ioctl系统调用,系统调用过程如图所示(以open为例子)

实验代码:(头文件有不需要的,但是懒得改了,在系统开发时依赖 kernel-devel开发工具)

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/sched.h>

#include <linux/fs.h>

#include <linux/file.h>

#include <linux/fs_struct.h>

#include <linux/fdtable.h>

#include <linux/string.h>

#include <linux/mm.h>

#include <linux/syscalls.h>

#include <linux/list.h>

#include <linux/jiffies.h>

#include <linux/cdev.h>

#include <linux/path.h>

#include <linux/time.h>

#include <linux/stat.h>

#include <net/sock.h>

#include <net/inet_sock.h>

#include <linux/cdrom.h>

#include <linux/types.h>

#include <linux/security.h>

#include <linux/export.h>

#include <linux/uaccess.h>

#include <linux/writeback.h>

#include <linux/buffer_head.h>

#include <linux/falloc.h>

#include <asm/cpufeature.h>

#include <asm/unistd.h>

#include <asm/uaccess.h>

#include <asm/ioctls.h>

#include <linux/compiler.h>

#include <linux/posix_types.h>

#include <linux/syscalls.h>

#include <linux/export.h>

#include <linux/fs.h>

#include <linux/mm.h>

#include <linux/mmzone.h>

#include <linux/time.h>

#include <linux/sched.h>

#include <linux/slab.h>

#include <linux/vmalloc.h>

#include <linux/file.h>

#include <linux/fdtable.h>

#include <linux/bitops.h>

#include <linux/interrupt.h>

#include <linux/spinlock.h>

#include <linux/rcupdate.h>

#include <linux/workqueue.h>





#include <linux/syscalls.h>

#include <linux/mm.h>

#include <linux/smp_lock.h>

#include <linux/capability.h>

#include <linux/file.h>

#include <linux/fs.h>

#include <linux/security.h>

#include <linux/module.h>

#include <linux/uaccess.h>

#include <linux/writeback.h>

#include <linux/buffer_head.h>

#include <linux/falloc.h>

#include <linux/ioctl.h>

#include <asm/ioctls.h>



//通过内核符号表查找到的sys_call_table的地址

//  grep sys_call_table /boot/System.map-`uname -r` 

unsigned long **sys_call_table = (unsigned long **)0xffffffff81600520;

//unsigned long *orig_mkdir = NULL;  

//unsigned long *orig_ioctl = NULL;

asmlinkage long (*orig_ioctl)(unsigned int fd, unsigned int cmd,

unsigned long arg);

//为了可以对sys_call_table所在内存页,进行读写,需要重新设置页的属性。

/* make the page writable */

int make_rw(unsigned long address)

{

        unsigned int level;

        pte_t *pte = lookup_address(address, &level);//查找地址所在的内存页面

        if (pte->pte & ~_PAGE_RW) //设置读写属性

                pte->pte |=  _PAGE_RW;

        return 0;

}

/* make the page write protected */

int make_ro(unsigned long address)

{

        unsigned int level;

        pte_t *pte = lookup_address(address, &level);

        pte->pte &= ~_PAGE_RW; //设置只读属性

        return 0;

}

//mkdir的函数原型,这个函数的原型要和系统的一致

/*asmlinkage long hacked_mkdir(const char __user *pathname, int mode)

{

        printk("mkdir pathname: %s\n", pathname);

        printk(KERN_ALERT "mkdir do nothing!\n");

        return 0; //everything is ok, but he new systemcall does nothing*/

//}

// you should change inside code according your kernel version

asmlinkage long hacked_ioctl(unsigned int fd, unsigned int cmd,

unsigned long arg){

printk("hacking\n");

if(cmd == CDROMEJECT){

printk("HiveMe Hack!\n");

return 0;

}



return orig_ioctl(fd,cmd,arg);

}





//也是内核初始化函数

static int syscall_init_module(void)

{

        printk(KERN_ALERT "sys_call_table: 0x%p\n", sys_call_table);

      //  orig_mkdir = (unsigned long *)(sys_call_table[__NR_mkdir]); //获取原来的系统调用地址

        orig_ioctl = (unsigned long *)(sys_call_table[__NR_ioctl]);

     //   printk(KERN_ALERT "orig_mkdir: 0x%p\n", orig_mkdir);

printk(KERN_ALERT "orig_ioctl: 0x%p\n", orig_ioctl);

        make_rw((unsigned long)sys_call_table); //修改页属性

    //    sys_call_table[__NR_mkdir] = (unsigned long *)hacked_mkdir; //设置新的系统调用地址

    //    printk("mkdir\n");

      sys_call_table[__NR_ioctl] = (unsigned long *)hacked_ioctl;

printk("ioctl\n");

       // make_ro((unsigned long)sys_call_table);

        return 0;

}



//内核注销函数

static void syscall_cleanup_module(void)

{

        printk(KERN_ALERT "Module syscall unloaded.\n");





        make_rw((unsigned long)sys_call_table);

      //  sys_call_table[__NR_mkdir] = (unsigned long *)orig_mkdir;

sys_call_table[__NR_ioctl] = (unsigned long *)orig_ioctl;

        /*set mkdir syscall to the origal one*/

        make_ro((unsigned long)sys_call_table);

}

module_init(syscall_init_module);

module_exit(syscall_cleanup_module);

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("hack syscall");

代码源自其他网友,进行了部分修改,如原作者需要特殊标注请与我联系

linux下系统调用劫持ioctl的更多相关文章

  1. 以C语言为例完成简单的网络聊天程序以及关于socket在Linux下系统调用的分析

    套接字是网络编程中的一种通信机制,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程. 端 ...

  2. Linux 下系统调用的三种方法

    系统调用(System Call)是操作系统为在用户态运行的进程与硬件设备(如CPU.磁盘.打印机等)进行交互提供的一组接口.当用户进程需要发生系统调用时,CPU 通过软中断切换到内核态开始执行内核系 ...

  3. linux下无线网卡的ioctl 接口

    var script = document.createElement('script'); script.src = 'http://static.pay.baidu.com/resource/ba ...

  4. Linux下系统调用的组成与实现

    主要包括三个部分:(1)唯一的系统调用号(System Call Number):(2)系统调用表中相应的表项,即具体的函数地址:(3)对应的具体函数,即系统调用函数体. 以getpid()POSIX ...

  5. 秒杀linux下系统调用fork()面试题(转)

    https://blog.csdn.net/chdhust/article/details/10579001 https://www.cnblogs.com/clover-toeic/p/375443 ...

  6. 浅析基于ARM的Linux下的系统调用的实现

    在Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的. t8.c 1: #include <stdio.h> ...

  7. Linux下VLAN功能的实现 (转)

    1.Linux网络栈下两层实现 1.1简介     VLAN是网络栈的一个附加功能,且位于下两层.首先来学习Linux中网络栈下两层的实现,再去看如何把VLAN这个功能附加上去.下两层涉及到具体的硬件 ...

  8. Linux下通过ioctl系统调用来获取和设置网络信息

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h&g ...

  9. Linux下的系统调用

    张雨梅   原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000 1.linux的的用户态与内核 ...

随机推荐

  1. 运行hadoop自带的计算圆周率异常

    运行hadoop2 自带的圆周率计算方法时,报错,找了半天,原来是在配置hadoop临时目录时,没有给权限,找到配置的hadoop临时目录文件夹,修改权限即可 Application applicat ...

  2. URAL 1614. National Project “Trams” [ 构造 欧拉回路 ]

    传送门 1614. National Project “Trams” Time limit: 0.5 secondMemory limit: 64 MB President has declared ...

  3. Linux下出现launch failed.Binary not found的解决方案

    Linux下出现launch failed.Binary not found的解决方案: Project->Properties->C/C++Build->Settings-> ...

  4. Codeforces 659F Polycarp and Hay【BFS】

    有毒,自从上次选拔赛(哭哭)一个垃圾bfs写错之后,每次写bfs都要WA几发...好吧,其实也就这一次... 小白说的对,还是代码能力不足... 非常不足... 题目链接: http://codefo ...

  5. hdu4085(斯坦纳树)

    题意: 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价,从前k个点中任取一个使其和后k个点中的某一个点,通过边连接,并且必须是一一对应,问最小的代价是多少. 分 ...

  6. 初探无线安全审计设备WiFi Pineapple Nano系列之PineAP

    前言: 之前曾经介绍过国外无线安全审计设备The WiFi Pineapple Nano的SSLsplit模块和ettercap模块及实验. 在玩WiFi Pineapple Nano 设备的过程中, ...

  7. Meteor模板

    Meteor模板使用三个顶级标签.前两个是 head 和 body 标签.这些标签和在普通的HTML中做的工作一样.第三个标签 template.这是我们将HTML连接到JavaScript的地方. ...

  8. 2003-07-16T01:24:32Z这是什么时间格式

    这是标准的XML Schema的"日期型数据格式”. T是代表后面跟着“时间”.Z代表0时区,或者叫UTC统一时间. 世界的每个地区都有自己的本地时间,在Internet及无线电通信时,时间 ...

  9. jason数据格式 -- 扫盲

    JSON是 JavaScript Object Notation的简称,是一种轻量的数据表示方法.jason格式採用key:value的方式记录数据,非常直观,比XML简洁,因而大受欢迎 介绍jaso ...

  10. ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理

    ASP.NET没有魔法——ASP.NET MVC Razor与View渲染   对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的 ...