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