进程装载过程分析(EXECVE系统调用分析)

文章详细阐述了Linux环境下进程启动的过程,从通过shell或exec系列函数启动程序,到内核中的execve系统调用,再到elf格式的加载和动态链接的处理。通过代码分析和调试跟踪,解释了如何通过堆栈替换实现进程的“偷梁换柱”。
摘要由CSDN通过智能技术生成

最近一段时间在学习linux内核,这里将进程启动的过程的一些心得体会记录一下。

1、进程启动

  linux环境下我们启动一个程序一般都是通过shell拉起来的。或者通过一个程序调用exec系列函数进行进程替换的。

  其实这两种方式实质是一样的,shell拉起也是调用的exec系列函数;所以我们就以第二种方式用代码来分析整个装载过程。

2、程序代码

  首先我们来看下我们的实例程序代码。

   为了好跟踪内核代码,所以这里通过qemu模拟了linux和文件系统。上左图为主进程,主进程fork了一个子进程,子进程最后调用exec*将自己替换为hello进程(),

  hello进程代码为右图。

3、 内核代码走读

  其实这里主要就是跟踪exec* 系统调用在内核中的执行,exec*系列函数都是execve的封装例程,execve系统调用最终对应的系统调用处理函数为sys_execve。

  

  sys_execve——> do_execve——>do_execve_common调用过程,do_execve_common 里面的实际上就是在组装 struct linux_binprm结构体。

  其主要调用exec_binprm

 

最终找到elf的加载函数,开始正式按照elf格式进行加载。

,通过上图,可以看到“current_pt_regs”这个就是将当期进程的寄存器堆取出来(eax、ebx……)。

然后“elf_entry”这个就是新的进程的入口,也就是这里是在准备新进程的堆栈信息、执行环境,实际上start_thread就是将原来的进程的堆栈信息全给替换为了新的进程的堆栈.

4、调试跟踪

 

如上图可以看到在start_thread函数中将新的进程的入口函数加载到堆栈中了,而进程入口就是进行elf文件中的entry point address.于是当进程返回用户空间时,就从新的进程入口开始执行了,于是进程就被替换成新的进程了——偷梁换柱

5、总结

  其实我们上面只分析了进程为静态链接的情况。如果是动态链接,老进程的堆栈入口将不是elf文件的开始。二手ld动态加载器,如下图代码所示:

我们进程的加载都是通过exec系统调用在内核中通过堆栈的替换 来偷梁换柱完成的。可以比喻为当一个人走进一个房间后(内核),等他出来时他的灵魂已经被换成另一个人了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值