execve源码分析

本文详细分析了Linux内核中execve系统调用的实现过程,从C语言层面的调用到内核的处理,包括系统调用号的查找、参数的保存、权限检查以及对可执行文件的处理。通过源码阅读,揭示了execve如何加载并执行新的程序。
摘要由CSDN通过智能技术生成
C语言的execve经过库函数,最终也会通过int 0x80中断陷入内核,并通过eax寄存器来传递调用号。
内核会根据系统初始化时注册的中断处理函数来对其进行处理。它的中断处理函数为system_call。这个函数定义在system_call.s中,它会保存一些寄存器的值(对于系统调用来说,保存的主要是参数),然后根据调用号调用syscall_table中相应的表项。syscall_table定义在include/linux/sys.h文件中,它是一个函数指针数组。对于execve来说它找到的表项就是sys_execve。它仍然是定义在system_call.s中的,在这里面它最终又调用了do_execve。

下面我们来具体看一下
system_call.s:
 80 _system_call:
 81     cmpl $nr_system_calls-1,%eax
 82     ja bad_sys_call
 83     push %ds
 84     push %es
 85     push %fs
 86     pushl %edx
 87     pushl %ecx      # push %ebx,%ecx,%edx as parameters
 88     pushl %ebx      # to the system call
 89     movl $0x10,%edx     # set up ds,es to kernel space
 90     mov %dx,%ds
 91     mov %dx,%es

可以看到每次系统调用都会设置fs指向用户段,这使得内核可以和用户空间拷贝数据
 92     movl $0x17,%edx     # fs points to local data space
 93     mov %dx,%fs

 94     call _sys_call_table(,%eax,4)
这里根据调用号会找到sys_execve

_sys_execve:
199 .align 2
200 _sys_execve:
201     lea EIP(%esp),%eax
202     pushl %eax
203     call _do_execve
204     addl $4,%esp
205     ret
201-202行把eip压栈,作为do_execve参数
我们分段来看do_execve的过程:
179 /*
180  * 'do_execve()' executes a new program.
181  */
182 int do_execve(unsigned long * eip,long tmp,char * filename,
183     char ** argv, char ** envp)
184 {
185     struct m_inode * inode;
186     struct buffer_head * bh;
187     struct exec ex;
188     unsigned long page[MAX_ARG_PAGES];
189     int i,argc,envc;
190     int e_uid, e_gid;
191     int retval;
1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值