模块添加法添加系统调用(CentOS7)

提示:本文章是本人课程实验过程中的步骤,若在相同环境下配置应该可以复原整个实验,若有错误欢迎指正!


一、实验环境

PC机1台,Windows操作系统和其上的虚拟Linux操作系统。
注意:本实验基于**CentOS7**下

二、实验环境及步骤

1.查询syscall_table的地址

在这里插入图片描述

2.查看可用的系统调用号

在这里插入图片描述

显然,从下图可知383可用。

在这里插入图片描述

3.创建执行文件(Lhd.c)源码见附录

在这里插入图片描述

4.创建Makefile文件

  • 1.创建Makefile文件

在这里插入图片描述

  • 2.编写结果如下:

在这里插入图片描述

5.安装内核模块

  • 1.执行命令make

在这里插入图片描述

  • 2.查看make是否成功,执行命令(看到有ko,mod.c,mod.o文件就说明成功了)

在这里插入图片描述

  • 3.使用insmod插入模块,执行命令

在这里插入图片描述

  • 4.使用lsmod查看模块是否插入成功(Module出现Lhd,表示模块插入成功),执行命令

在这里插入图片描述

6.测试系统调用

  • 1.使用vim创建ModuleAddTest.c文件

在这里插入图片描述

  • 2.运行结果如下(系统调用的printk不会打印在基本输出上,所以我们在sys.c中实现的printk效果不会打印出来,但是我们可以使用dmesg查看内核态打印的信息):

在这里插入图片描述


附录

Lhd.c源码

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/unistd.h>
#include <linux/sched.h>

MODULE_LICENSE("Dual BSD/GPL");

#define SYS_CALL_TABLE_ADDRESS 0xffffffffaee00220 //sys_call_table对应的地址
#define NUM 383 //系统调用号为383
int orig_cr0; //用来存储cr0寄存器原来的值
unsigned long *sys_call_table_my=0;
static int(*anything_saved)(void); //定义一个函数指针,用来保存一个系统调用

static int clear_cr0(void) //使cr0寄存器的第17位设置为0(内核空间可写)
{
  unsigned int cr0=0;
  unsigned int ret;
  asm volatile("movq %%cr0,%%rax":"=a"(cr0));//将cr0寄存器的值移动到eax寄存器中,同时输出到cr0变量中
  ret=cr0;
  cr0&=0xfffffffffffeffff;//将cr0变量值中的第17位清0,将修改后的值写入cr0寄存器
  asm volatile("movq %%rax,%%cr0"::"a"(cr0));//将cr0变量的值作为输入,输入到寄存器eax中,同时移动到寄存器cr0中
  return ret;
}

static void setback_cr0(int val) //使cr0寄存器设置为内核不可写
{
  asm volatile("movq %%rax,%%cr0"::"a"(val));
}

asmlinkage long sys_mycall(void) //定义自己的系统调用
{
  printk("模块系统调用-当前pid:%d,当前comm:%s\n",current->pid,current->comm);
  printk("Hello,LiuHongde!jk1901-201908010118!\n");
  return current->pid;
}

static int __init call_init(void)
{
  sys_call_table_my=(unsigned long*)(SYS_CALL_TABLE_ADDRESS);
  printk("call_init......\n");
  anything_saved=(int(*)(void))(sys_call_table_my[NUM]);//保存系统调用表中的NUM位置上的系统调用
  orig_cr0=clear_cr0();//使内核地址空间可写
  sys_call_table_my[NUM]=(unsigned long) &sys_mycall;//用自己的系统调用替换NUM位置上>的系统调用
  setback_cr0(orig_cr0);//使内核地址空间不可写
  return 0;
}

static void __exit call_exit(void)
{
  printk("call_exit......\n");
  orig_cr0=clear_cr0();
  sys_call_table_my[NUM]=(unsigned long)anything_saved;//将系统调用恢复
  setback_cr0(orig_cr0);
}

module_init(call_init);
module_exit(call_exit);

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值