一、理论知识

Linux中,可以从c源代码生产一个可执行程序,这其中要经过预处理、编译和链接的过程。可以参考以下图来理解这个过程:

其中,目标文件中至少有编译后的机器指令代码、数据,也还包括了链接时所须要的一些信息,比如符号表、调试信息、字符串等。这Linux中,可执行文件的格式现在主要是ELF格式(对应于Windows中PE格式)。ELF的格式如下:

其详细介绍,参见:http://www.muppetlabs.com/~breadbox/software/ELF.txt,这里还有个中文版:http://www.xfocus.net/articles/200105/174.html

链接,是收集、组织程序所需的不同代码和数据的过程,以便程序能被装入内存并被执行。链接过程分为两步:1.空间与地址分配;2.符号解析与重定位。

在Linux中,一个程序的执行是做为一个新的进程,使用execve系统调用完成的。execve对应的系统调用是sys_execve,在其内部会解析可执行文件格式。对应的内核代码,就是,在search_binary_handler中寻找符合文件格式对应的解析模块,关键代码如下:

对于ELF文件,retval = fmt->load_binary(bprm)实际上执行的就是load_elf_binary,其内部就是按照ELF文件格式来加载ELF文件的。这里,我们也可以看到Linux是可以支持多种可执行文件格式的,所有的格式处里信息用一个结构体存储在一个链表中,其中的load_binary是一个函数指针,对应于该中格式的可执行文件的加载方式;要想支持一种新的可执行文件,只需要向链表中注册一个新的format结构体就可以了,此种设计类似观察者模式,具有很好的扩展性。

二、实验过程

打开实验楼中的虚拟机,在shell中依次运行以下命令,获取本次实验的代码,并编译运行

cd LinuxKernel

rm menu -rf

git clone https://github.com/mengning/menu.git

cd menu

mv test_exec.c test.c

make rootfs

效果如下:

关闭QEMU窗口,在shell窗口中,cd LinuxKernel回退到LinuxKernel目录,使用下面的命令启动内核并在CPU运行代码前停下以便调试:

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

接下来,我们就可以水平分割一个新的shell窗口出来,依次使用下面的命令启动gdb调试

gdb

(gdb) file linux-3.18.6/vmlinux

(gdb) target remote:1234

并在系统调用sys_execve的入口处设置断点

(gdb) b sys_execve

继续运行程序,在QEMU窗口中输入exec,系统就会停在上面设置的断点处,如图:

接下来我们可以单步跟踪sys_execve的内核代码,也可以通过设置以下断点

b load_elf_binary

b start_thread

来完整地跟踪进程的创建和启动代码!

三、总结

Linux系统可以通过execve API启动一个新进程,该API又呼叫sys_execve系统调用,负责将新的程序代码和数据替换到新的进程中,打开可执行 文件,载入依赖的库文件,申请新的内存空间,最后执行 start_thread(regs, elf_entry, bprm->p) ,设置 new_ip, new_sp ,完成新进程的代码和数据替换,然后返回,接下来就是执行新的进程代码了。

最新文章

  1. Maven基础配置—本地Maven配置
  2. 普通用户使用dbms_xplan包需要有的权限
  3. java程序保护如何知识产权,特别提供一个java 开发的java 源代码级的混淆器
  4. python—面向对象编程
  5. 【PHP开源产品】Ecshop的商品筛选功能实现分析之一
  6. Linux apt-get
  7. Flex之自定义事件
  8. 获取Exe文件版本信息的函数(使用GetFileVersionInfo得到TFileVersionInfo结构体,包含12项内容)
  9. 更加 "深入" 理解多态
  10. Memcached的基础梳理
  11. geotrellis使用(三十)使用geotrellis读取PostGIS空间数据
  12. Django简介--Django从入门到精通系列教程
  13. 承接Unity外包 U3D外包 Unity3D外包 小型Unity项目外包用Unity还是UE4
  14. python操作三大主流数据库(1)python操作mysql①windows环境中安装python操作mysql数据库的MySQLdb模块mysql-client
  15. Linux下安装软件命令详解
  16. July 10th, Week 29th Sunday, 2016
  17. 阿里云logtail采集IDC机房机器需添加AliUids操作
  18. TNS-12537,TNS-12560,TNS-00507 Linux Error: 29: Illegal seek解决
  19. how2j网站前端项目——天猫前端(第一次)学习笔记1
  20. 关于vc工程包含多个lib库老是提示无法打开问题

热门文章

  1. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)
  2. Sublime Text3.0的安装
  3. info信息的获取
  4. [Ubuntu] <uptime>命令
  5. sqoop安装与简单实用
  6. 小数第n位:高精度
  7. 第八次作业psp
  8. windows环境下nginx服务器的安装与配置
  9. lintcode-480-二叉树的所有路径
  10. lintcode-205-区间最小数