欢迎来到天天文库
浏览记录
ID:9495990
大小:77.50 KB
页数:13页
时间:2018-05-01
《linux管理员记录(12)》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、Linux管理员记录(12) Linux内核是作为Monolithicarchitecture(单内核体系结构)而实现的,为了获得Microkernelarchitecture(微内核体系结构)带来的可扩展性和可维护性,Linux引入了模块(module)机制,(比较准确的说法是LoadableKernelModule,可装载内核模块),藉此来保证内核的紧凑性和Linux本身固有的单一体系结构的优点上下文切换速度快。 在Linux中,用户(通常需要root权限)通过modutils软件包中提供的工具,动态地将模块(如网络驱动等)插入、移出内核。这样,内核的功能可以动态地添
2、加和删除,却不需要每次都经过冗长的关机/重启过程。因为模块运行的环境是内核,因而它具有内核特权,模块编程也就是内核编程,它是LinuxKernelHacking的主要工具。下面,讲述在Linux下如何通过module来拦截系统调用,以及KernelHacking的一些防范手段。 Linux通过int0x80软中断实现系统调用。系统调用列表在Linux自举时通过init_IRQ()调用宏set_intr_gate初始化。当系统调用发生时,内核检查系统调用的有效性,然后将控制权转给实际的系统调用代码。系统调用表sys_call_table[]可以在文件entry.S中找到。它看
3、起来应该如下所示: ENTRY (sys_call_table).long SYMBOL_NAME (sys_ni_syscall) /* */.long SYMBOL_NAME (sys_exit).long SYMBOL_NAME (sys_fork).long SYMBOL_NAME (sys_read) 文件unistd.h为每个系统调用规定了唯一的编号,它看起来应该如下所示: #define __NR_exit 1#define __NR_fork 2#define __NR_read 3 编缉推荐阅读以下文章Linux管理员记录(18)——对Linux系统下
4、的开发环境梳理Linux管理员记录(17)——阅读Linux的内核源码Linux管理员记录(16)——关于Linux内核的编译Linux管理员记录(15)——与Linux相关的接口测试Linux管理员记录(14)——细数家珍:我比较喜欢的Linux命令Linux管理员记录(13)——紧急处理:别让Linux故障晕了你Linux管理员记录(12)——庖丁解牛:Linux就包括这么四大部分Linux管理员记录(11)——入对行与嫁对郎:Linux的职业前景Linux管理员记录(10)——Linux到底有多吸引人?Linux管理员记录(9)——Linux的前世今生 不难看出,每个
5、系统调用所对应的编号正是该系统调用在指向函数的指针数组sys_call_table[]中的下标。内核检查%eax的有效性,sys_call_table[%eax]便是用户要求的系统调用的入口指针。那么,怎样才能拦截系统调用呢?很简单,只要将sys_call_table[]中对应的入口指针替换成我们自己的函数指针即可。 好了,有了上述知识,现在可以进行编程了。作为最简单的例子,我们可以试着拦截mkdir()系统调用。/**hack_mkdir.c*It sho call.*/#include /*编译模块必需的头文件*/#include #include extern voi
6、d *sys_call_table [];int (*origin_mkdir) (const char *); /*用于保存旧的系统调用*/int hacked_mkdir(const char *pathname) /*新的系统调用*/{return 0;}int init_module() /*模块入口点,初始化时调用*/{origin_mkdir=sys_call_table [__NR_mkdir]; /*保存旧系统调用*/sys_call_table [__NR_mkdir] = hacked_mkdir;/*替换成新系统调用*/return 0;}void cl
7、eanup_module() /*模块入口点,卸载前调用*/{sys_call_table [__NR_mkdir] = origin_mkdir; /*复位旧系统调用*/} 应用程序从main()开始执行单个任务,而模块却只是预先注册自己以服务于将来的某个请求。插入模块时,内核调用init_module()初始化模块;移除模块时,内核调用cleanup_module()做一些善后工作。 如上代码所示,我们将mkdir()系统调用换成了新的调用hacked_mkdir(),事实上它只是一个空函数。为
此文档下载收益归作者所有