博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用模块添加系统调用(不重新编译内核)
阅读量:6722 次
发布时间:2019-06-25

本文共 1443 字,大约阅读时间需要 4 分钟。

其实用这个标题随便baidu、Google出来都是一大堆,大部分都是转来转去,代码无非那么几种。可是真正编译通过还是费了不少功夫,我在双系统的Ubuntu10.04和虚拟机里的Red Hat9里来来回回不知折腾了多少次。所以本文更多的是记录下自己调试的细节,而不是简单的粘代码和转载。

  目的是在不重新编译内核的前提下添加系统调用,思路倒是很简单,修改映射在内存中的系统调用表,把一个空闲的系统调用表项指向自己写的模块中的函数,如果是已使用的表项,甚至可以实现系统调用劫持。

  分配的空闲的系统调用号依然要在源码的asm/unistd.h中去找,只是不用修改。如果没有unused的,怕是还是得重新编译内核了,毕竟系统调用表在编译后大小就固定了,映射到内存中也是固定的,在内存中这个表的最后新增加表项难免会溢出。

  找到系统调用号后,还要找系统调用表在内存中的位置。当前系统可以查看/proc/kallsyms的。对于不同的内核,它放在编译后的System.map中,同样可以在/boot/System.map.X.X.XX.XX中查看。我的是c057e110,由于它是十六进制数,这在源代码中前面还要加0x。而且通过R标志可以看出它是只读的。

  为了修改内存中的表项,还要修改寄存器写保护位,否则是不能修改的。它位于cr0的16位,其修改和保存由模块初始化函数实现。

  模块代码基本是参考,几乎没有改动,只是系统调用提供的功能不同,这不是重点。

syscall.c

  测试代码

test1.c

 

  最初用带参数的gcc编译时总是出错,看了一些帖子,照猫画虎的写了一个Makefile,现在觉得它是很有必要的:

obj-m := syscall.oKERNELDIR := /lib/modules/2.6.32.22/build PWD := $(shell pwd) modules:     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install:     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

  模块倒是正确生成了syscall.ko,但是insmod时终端直接显示“段错误”,lsmod里看却是加载了,但是系统调用的功能无法实现,而且这个模块还卸载不掉,总是显示in use。编译的时候也没有把rmmod的-f功能打开,不能强制卸载,只能重启,相当郁闷。

  没办法,只能找问题所在了。Linux下的调试不是很熟悉,打算用printk手动找bug。以前没用过printk,查询了一下,使用dmesg就可以看到它的输出了。于是在模块里加了一些。首先定位出内联汇编那里执行不下去了,但是与内联汇编的代码比照,反复看都没有问题。不经意间删除了一些空格,替换成了Tab(其他位置也有这样做),再次重启、make、insmod,居然没有提示并加载成功了。运行测试函数,输出了正确结果,这么看来代码本身是没有问题的,问题应该出在复制代码时的空格上。

  这里可以看出,这个模块如果放到别的环境中是不能运行的,移植时,系统调用号和系统调用表地址必须做出相应的修改。

本文转自五岳博客园博客,原文链接:http://www.cnblogs.com/wuyuegb2312/archive/2012/05/20/2510668.html,如需转载请自行联系原作者

你可能感兴趣的文章
未来技术与安全
查看>>
2012中国虚拟化及云计算技术年度市场研究报告
查看>>
进程管理
查看>>
Kali 开机自动启动服务
查看>>
我的友情链接
查看>>
SQL(三)、SQL语句练习
查看>>
XenServer 6.5实战系列之三:Prepare for XenServer 6.5
查看>>
红帽5.8 yum小记
查看>>
日历源代码
查看>>
我的友情链接
查看>>
Ascll、GB2312、Ansi
查看>>
ubuntu ftp 服务器搭建
查看>>
2.1、Android Studio通过Lint提升你的代码
查看>>
魔域深渊
查看>>
ffmpeg 去除图片中的水印
查看>>
将博客搬至CSDN
查看>>
Java线程创建形式 Thread构造详解 多线程中篇(五)
查看>>
Hexo博客系列(二)-在多台机器上利用Hexo发布博客
查看>>
C语言参考程序—无符号一位整数的四则运算
查看>>
逻辑电路 - 与门And Gate
查看>>