Linux添加系统调用的两种方法

本文详细介绍了在Linux系统中添加自定义系统调用的两种方法:一是通过修改内核源码并重新编译;二是利用内核模块实现系统调用拦截。在编译内核法中,需要更新系统调用号和调用函数的对应关系,并在kernel/sys.c中添加服务函数。而在内核模块法中,通过修改sys_call_table的地址达到拦截系统调用的目的。最后,文章还提供了编写用户态测试程序的指导。
摘要由CSDN通过智能技术生成

前言

系统调用的基本原理

系统调用其实就是函数调用,只不过调用的是内核态的函数,但是我们知道,用户态是不能随意调用内核态的函数的,所以采用软中断的方式从用户态陷入到内核态。在内核中通过软中断0X80,系统会跳转到一个预设好的内核空间地址,它指向了系统调用处理程序(不要和系统调用服务例程混淆),这里指的是在entry.S文件中的system_call函数。就是说,所有的系统调用都会统一跳转到这个地址执行system_call函数,那么system_call函数如何派发它们到各自的服务例程呢?
我们知道每个系统调用都有一个系统调用号。同时,内核中一个有一个system_call_table数组,它是个函数指针数组,每个函数指针都指向了系统调用的服务例程。这个系统调用号是system_call_table的下标,用来指明到底要执行哪个系统调用。当int ox80的软中断执行时,系统调用号会被放进eax寄存器中,system_call函数可以读取eax寄存器获得系统调用号,将其乘以4得到偏移地址,以sys_call_table为基地址,基地址加上偏移地址就是应该执行的系统调用服务例程的地址。

系统调用的传参问题

当一个系统调用的参数个数大于5时(因为5个寄存器(eax, ebx, ecx, edx,esi)已经用完了),执行int 0x80指令时仍需将系统调用功能号保存在寄存器eax中,所不同的只是全部参数应该依次放在一块连续的内存区域里,同时在寄存器ebx中保存指向该内存区域的指针。系统调用完成之后,返回值扔将保存在寄存器eax中。由于只是需要一块连续的内存区域来保存系统调用的参数,因此完全可以像普通函数调用一样使用栈(stack)来传递系统调用所需要的参数。但是要注意一点,Linux采用的是c语言的调用模式,这就意味着所有参数必须以相反的顺序进栈,即最后一个参数先入栈,而第一个参数则最后入栈。如果采用栈来传递系统调用所需要的参数,在执行int 0x80指令时还应该将栈指针的当前值复制到寄存器ebx中。

1.添加系统调用的两种方法

方法一:编译内核法
拿到源码之后

  • 修改内核的系统调
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值