那么在Linux内核2.6之后,不能直接导出sys_call_table的地址后,我们要如何获得系统调用表的地址,从而实现系统调用的截获呢。

先贴上我实现好的代码,然后再来讲解吧。

modu.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/moduleparam.h>
#include<linux/unistd.h>
#include<linux/sched.h>
#include<linux/syscalls.h>
#include<linux/string.h>
#include<linux/fs.h>
#include<linux/fdtable.h>
#include<linux/uaccess.h> #include<linux/rtc.h> MODULE_LICENSE("Dual BSD/GPL"); #define _DEBUG
#ifdef _DEBUG
#define kprintk(fmt,args...) printk(KERN_ALERT fmt,##args)
#define kprintf(fmt,args...) printf(fmt,##args)
#define kperror(str) perror(str)
#else
#define kprintk
#define kprintf
#define kperror
#endif /*Function declaration*/
long * get_sys_call_table(void); long * g_sys_call_table=NULL;//save address of sys_call_table struct _idtr{
unsigned short limit;
unsigned int base;
}__attribute__((packed)); struct _idt_descriptor{
unsigned short offset_low;
unsigned short sel;
unsigned char none,flags;
unsigned short offset_high;
}__attribute__((packed)); /*Get the address of sys_call_table*/
long * get_sys_call_table(void){ struct _idt_descriptor * idt;
struct _idtr idtr;
unsigned int sys_call_off;
int sys_call_table=;
unsigned char* p;
int i;
asm("sidt %0":"=m"(idtr));
kprintk(" address of idtr: 0x%x\n",(unsigned int)&idtr);
idt=(struct _idt_descriptor *)(idtr.base+*0x80);
sys_call_off=((unsigned int)(idt->offset_high<<)|(unsigned int)idt->offset_low);
kprintk(" address of idt 0x80: 0x%x\n",sys_call_off);
p=(unsigned char *)sys_call_off;
for(i=;i<;i++){
if(p[i]==0xff&&p[i+]==0x14&&p[i+]==0x85){
sys_call_table=*(int*)((int)p+i+);
kprintk(" address of sys_call_table: 0x%x\n",sys_call_table); return (long*)sys_call_table;
}
} return ;
} int monitor_init(void){
kprintk("Monitor init\n");
g_sys_call_table = get_sys_call_table();
return ;
} void monitor_exit(void){
kprintk("Monitor exit\n");
} module_init(monitor_init);
module_exit(monitor_exit);

Makefile

obj-m := modu.o
KERNELDIR := /lib/modules/3.13.--generic/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

将modu.c和Makefile放在同一个目录下,执行“make”,编译程序,会生成modu.ko文件。

执行“sudo insmod modu.ko”,将modu.ko加载到内核中。

执行“dmesg”,查看系统日志,如图。

接下来就要解释解释原理了。

我们知道Linux系统中的系统调用是通过用户软件调用中断int0x80激发的,int0x80被执行后,内核获得CPU的控制权,并交由system_call程序处理。即sys_call_table是由system_call进行调用的。

而system_call是int0x80软中断,即int0x80中断对应的地址就是system_call函数的地址。而Linux系统中所有中断信息都保存在一张中断描述表IDT中,而这张表的地址又是保存在IDTR寄存器里面,所以整个截获过程可以用如下图表示。

即先在IDTR寄存器中获得IDT_TABLE的地址,再在IDT_TABLE中获得int0x80的地址,int0x80对应的是system_call函数的地址。最后通过system_call函数的地址获得sys_call_table的地址。

Linux内核监控模块-2-系统调用表地址的获取(Linux内核版本3.13)的更多相关文章

  1. linux内核编程入门--系统调用监控文件访问

    参考的资料: hello world   https://www.cnblogs.com/bitor/p/9608725.html linux内核监控模块--系统调用的截获  https://www. ...

  2. linux内核基础(系统调用,简明)

    内核基础(系统调用) 在说系统调用之前.先来说说内核是怎么和我们交互的.或者说是怎么和我们产生交集的. 首先,内核是用来控制硬件的仅仅有内核才干直接控制硬件,所以说内核非常重要,假设内核被控制那么电脑 ...

  3. linux内核学习之四 系统调用

    一  概念区分 提到linux系统调用,不得不区分几个比较容易混淆的概念: 系统调用:系统调用就是一种特殊的接口.通过这个接口,用户可以访问内核空间.系统调用规定了用户进程进入内核的具体位置. 应用程 ...

  4. 【原创】xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正. 1. 引出问题 上一篇文章xenomai内核解析--双核系统调用(一)以X86处理器为例,分析了xenomai内核调用的流程, ...

  5. linux内核分析——扒开系统调用的三层皮(下)

    20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 实验 ...

  6. Linux内核监控模块-3-系统调用的截获

    上一章,我们获取了系统调用表的地址,这里我们来搞点所谓“截获”的事情.所谓“截获”即是将系统调用表里的地址指向我们自己写的一个函数,系统调用先执行我们自己写的函数,处理完后,再返回原来系统调用的执行函 ...

  7. Linux内核分析— —扒开系统调用的三层皮(下)

    课程主要内容有三点: 在MenuOS中通过添加代码增加自定义的系统调用命令 使用gdb跟踪调试内核 简单分析system_call代码了解系统调用在内核代码中的处理过程 实验——分析system_ca ...

  8. linux内核分析——扒开系统调用的三层皮

    万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验部分 选择2 ...

  9. Linux内核监控模块-1-驱动模块(LKM)开发(以一个简单的hello world程序为例)

    在上面一篇中介绍到,监控模块要做成一个驱动模块(或者说是可加载模块,LKM),动态的加载到Linux内核中.那么这篇就简单的介绍一下怎样做一个这样的驱动模块.   以简单的hello world程序为 ...

随机推荐

  1. UVA Mapping the Swaps

    题目例如以下: Mapping the Swaps  Sorting an array can be done by swapping certain pairs of adjacent entrie ...

  2. Java-SSI框架学习

    框架简介: 相信大家对于mvc的三层架构已经灰常熟悉了,在这就不细讲了,个人感觉ssi的框架结构还是比较典型的mvc三层架构,还是比较容易上手的.关于这块的入门我想特别感谢下FrankHui童鞋,在他 ...

  3. Nginx模块fastcgi_cache的几个注意点 转

    Nginx模块fastcgi_cache的几个注意点   去年年底,我对nginx的fastcgi_cache进行摸索使用.在我的测试过程中,发现一些wiki以及网络上没被提到的注意点,这里分享一下. ...

  4. 关于Clone 的方法使用

    package cn.hncu.day7.clone.v1;//克隆的套路:// 第1步:重写User类的clone()方法,以供外面调用.因为外面的类无法直接调用User类父类中的clone()方法 ...

  5. oracle学习----统计信息

    1.收集统计信息的方式 for all columns size skewonly BEGIN  DBMS_STATS.GATHER_TABLE_STATS(ownname          => ...

  6. Linux下搭建Oracle11g RAC(4)----配置oracle,grid用户SSH对等性

    虽然在安装软件的过程中,oracle会自动配置SSH对等性,建议在安装软件之前手工配置. 配置oracle用户对等性: node1: [root@node1 ~]# su - oracle node1 ...

  7. JSON 学习总结 <一>:什么是JSON

    JSON的相关资料和博客很多,JSON无处不用,最近项目中一直要用到JSON,今天没有加班,就写下,算是对自己的总结,对JSON又一次深入的认识. 废话不多了,直接进入今天的主题: 如题:今天就介绍下 ...

  8. quartz.net 基于数据库的简单实现

    前面简单学习了通过XML配置或者内存指定的方式实现调度任务.但此用法实战用途较小,企业上多需要分布式集群的方式.quart团队也考虑到了这点,于是有了我们今天要学习的.基于数据库实现分布式. Name ...

  9. js 的执行过程

    step 1.  读入第一个代码块. step 2.  做语法分析,有错则报语法错误(比如括号不匹配等),并跳转到step5. step 3.  对var变量和function定义做"预编译 ...

  10. (转)PHP获取今天、昨天、明天的日期

    <?php echo "今天:".date("Y-m-d")."<br>"; echo "昨天:".d ...