Linux内核监控模块-2-系统调用表地址的获取(Linux内核版本3.13)
那么在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)的更多相关文章
- linux内核编程入门--系统调用监控文件访问
参考的资料: hello world https://www.cnblogs.com/bitor/p/9608725.html linux内核监控模块--系统调用的截获 https://www. ...
- linux内核基础(系统调用,简明)
内核基础(系统调用) 在说系统调用之前.先来说说内核是怎么和我们交互的.或者说是怎么和我们产生交集的. 首先,内核是用来控制硬件的仅仅有内核才干直接控制硬件,所以说内核非常重要,假设内核被控制那么电脑 ...
- linux内核学习之四 系统调用
一 概念区分 提到linux系统调用,不得不区分几个比较容易混淆的概念: 系统调用:系统调用就是一种特殊的接口.通过这个接口,用户可以访问内核空间.系统调用规定了用户进程进入内核的具体位置. 应用程 ...
- 【原创】xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正. 1. 引出问题 上一篇文章xenomai内核解析--双核系统调用(一)以X86处理器为例,分析了xenomai内核调用的流程, ...
- linux内核分析——扒开系统调用的三层皮(下)
20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 实验 ...
- Linux内核监控模块-3-系统调用的截获
上一章,我们获取了系统调用表的地址,这里我们来搞点所谓“截获”的事情.所谓“截获”即是将系统调用表里的地址指向我们自己写的一个函数,系统调用先执行我们自己写的函数,处理完后,再返回原来系统调用的执行函 ...
- Linux内核分析— —扒开系统调用的三层皮(下)
课程主要内容有三点: 在MenuOS中通过添加代码增加自定义的系统调用命令 使用gdb跟踪调试内核 简单分析system_call代码了解系统调用在内核代码中的处理过程 实验——分析system_ca ...
- linux内核分析——扒开系统调用的三层皮
万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验部分 选择2 ...
- Linux内核监控模块-1-驱动模块(LKM)开发(以一个简单的hello world程序为例)
在上面一篇中介绍到,监控模块要做成一个驱动模块(或者说是可加载模块,LKM),动态的加载到Linux内核中.那么这篇就简单的介绍一下怎样做一个这样的驱动模块. 以简单的hello world程序为 ...
随机推荐
- Lamda和Linq语法对比详细
本人转载:http://www.cnblogs.com/knowledgesea/p/3897665.html 闲言碎语 近期比较忙,但还是想写点什么,就分享一些基础的知识给大家看吧,希望能帮助一些l ...
- [rxjs] Demystifying Cold and Hot Observables in RxJS
Cold: console.clear(); var Observable = Rx.Observable; var clock = Observable.interval(1000).take(10 ...
- NodeJs读取源代码使用的字符集
今天用NodeJs写了个简单的客户端/服务器程序,并让客户端向服务器发送汉字.当在Windows上执行客户端时,发现服务器端打印的接收到的数据是乱码.后来发现Windows上的客户端文件的储存编码方案 ...
- AndroidUniversalImageLoader网络图片加载
1.功能概要 Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示. (1).使用多线程加载图片(2) ...
- Oracle笔记-表的管理
3.1创建和管理表在Oracle表中使用的emp,dept,sal都是系统内建好的表,那么在SQL语法中同样支持了表的创建语句,要想创建表,则应先了解下Oracle中最常用的几种数据类型3.1.1常用 ...
- Validation Rule和Binding Group
WPF学习之绑定-Validation Rule和Binding Group 在上一篇文章中我们讨论了有关WPF绑定的知识点,现在我们可以很容易的将业务数据作为源绑定到WPF控件并可以通过创建不同的D ...
- PHP中的session会话创建打印释放销毁;
PHP Session PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置.Session 变量存储单一用户的信息,并且对于应用程序中的 ...
- System Operations on AWS - Lab 3W - Managing Storage (Windows)
创建一个名叫Processor的EC2实例,登陆到CommandHost实例,通过AWS CLI对Processor实例的EBS卷做snapshot,设置周期性snapshot的计划任务, 登陆到Pr ...
- 15个Linux Yum命令实例--安装/卸载/更新
在linux环境中, 安装, 卸载更新包是一个极为常见的操作.大部分的linux环境都提供了包的管理工具, 例如:apt-get, dpkg, rpm, yum等等. 一些Linux环境中,yum是默 ...
- 让图片在DIV中垂直居中
window.onload=function(){ var img = document.getElementById("imgdiv"); var div = document. ...