实验部分

首先clone最新的menu

我们可以看到,test.c里多了一个exec的功能,它的代码和fork基本一致,多了一项加载hello

rootfs也有一些变化

执行一下exec

让我们启动一个冻结的menuOS

设置三个断点sys_execve;load_elf_binary;start_thread.启动起来之后,执行exec命令,跟踪

思考部分

新的可执行程序是从哪里开始执行的?

新的可执行程序是从程序的头部,也就是main函数开始执行的,被装载到内核的地址空间是0x8048x00(x是整数)。

为什么execve系统调用返回后新的可执行程序能顺利执行?

要得到返回之后能顺利执行的原因,让我们来先简单地分析一下整个过程。父进程在用户态中创建一个新的子进程,在内核中给子进程分配空间,子进程从ret_from_fork开始,先修改eax=0,再将五个值压栈,在执行execve时,需要将内核堆栈中以前压栈的五个之中的两个sp,ip做修改,修改的地址映射新可执行程序的入口,这样一来,新的可执行程序就可以顺利执行了。

对于静态链接的可执行程序和动态链接的可执行程序execve系统调用返回时会有什么不同?

对于静态链接和动态链接在execve系统调用返回时有很大的不同,静态链接相对于动态链接来说要简单许多,它们的不同之处主要在修改的sp,ip的值上。静态链接直接修改为新的可执行程序的入口即可(即0x8048x000,也就是main函数处);对于动态链接,让我们先来分析一下动态链接的过程。动态链接需要先加载动态链接器ld,然后由动态连接器加载程序中需要加载的动态库,以及其他的一些资源(这是一个遍历动态库依赖关系图的过程),然后才能开始执行新的可执行程序。所以对于动态链接,execve系统调用返回到动态链接加载器ld.

总结部分

预处理、编译、链接和目标文件的格式

可执行程序是怎么得来的

以C语言为例,c代码经过编译器的预处理,编译成汇编代码,由汇编器编译成目标代码,再链接成可执行文件,由操作系统加载到cpu里来执行。

.c-预处理(-E)---.i--编译(-S)--.asm(.s)--汇编(-c)---.o(二进制文件,ELF格式,readelf -h显示头部信息)--链接---A.out(可执行文件)

预处理负责把include的文件包含进来及宏替换等工作

可执行文件是使用共享库的。

静态编译
-static

把库里的东西都放在里面了所以比较大

可执行文件的内部是怎样的?

目标文件的格式ELF

文件格式:

  • PE是windows下
  • ELF是linux下(executable linkable format)

目标文件格式和ABI应用程序二进制接口适应到某一种cpu格式

ELF标准下三种可执行文件:

  • 一个可重定位文件(代码和数据)
  • 一个可执行文件(用来执行的程序)
  • 一个共享文件(代码和数据,连接编译器和动态连接器)

Obeject文件参与程序联接(创建一个程序)和程序执行(运行一个程序)

重定位:在程序中调用外部函数时。在程序链接以后,将外部函数和程序中的内存地址联系起来。物理地址和虚拟地址映射。

符号(引用)解析:链接以前,可重定位的目标联系虚拟地址。

查看ELF文件的头部
gccs readelf -h main

可执行程序加载的主要工作:

映射代码中各种数据对应到进程空间的地址。例如:在文件中的代码段,拷贝到进程的空间时;数据段拷贝到进程空间。

静态链接的ELF可执行文件和进程的地址空间

文件映射进程地址空间

0xc000000开始是用户态可以使用的

0x8048000默认的加载地址

0x8048X00程序的真实入口,可执行文件加载到内存中开始执行的第一行代码

  • 一般静态链接会将所有代码放在一个代码段

  • 动态链接的进程会有多个代码段

可执行程序、共享库和动态链接

装载可执行程序之前的工作

可执行程序的的执行环境

  • 命令行参数和shell环境

    • ls -l/usr/bin列出/usr/bin下的目录信息//ls是一个可执行程序
    • shell本身不限制命令行参数的个数,命令行参数的个数受限于命令自身//也就是main函数
    • 例如,int main(int argc,char argv[]);//愿意接受命令行参数,用户输入的

      -又例如,int main(int argc,char argv[],charenvp[])//
      envp:shell的环境变量
    • shell会调用execve将命令行参数传递给可执行程序的main()函数
    • int execve(int char *filename,char *argv[],char *const envp[]);//函数原型,先函数调用参数传递,再系统调用参数传递

命令行参数和环境变量时如何保存和传递的?

命令行参数和环境变量,fork一个子进程时完全复制父进程的,然后调用execv时,把当前的可执行程序把原来的环境(子进程)给覆盖掉,子进程的用户态堆栈也被清空了,因为新的进程要执行。

那么命令行参数和环境变量时如何进入新程序的堆栈的?
  • 命令行参数(char *argv[])、环境变量(char *const envp[])压栈
  • 创建一个新的用户态堆栈,通过指针将命令行参数,环境变量传递给系统调用execve的内核处理函数
  • 内核处理函数创建一个新的可执行程序用户态堆栈的同时,将命令行参数和环境变量拷贝进去

    shell程序--execve--对应的系统调用sys_execv--然后在初始化时拷贝

装载时动态链接和运行时动态链接的应用举例

  • 可执行程序装载时动态链接
  • 可执行程序运行时动态链接

可执行装载时、运行动态链接

1. 准备.so文件
共享库文件shlibexample.h和shlibexample.c编译成.so文件
![](http://images2015.cnblogs.com/blog/744818/201604/744818-20160408154304515-1049697563.png) gcc -shared shlibexample.c -o libshlibexample.so -m32
2. 分别以共享库和动态加载共享库的方式使用libshlibexample.so文件和libdllibexample.so文件
![](http://images2015.cnblogs.com/blog/744818/201604/744818-20160408154246343-1770179350.png) 编译main注意这里只提供shlibexample的-L(库对应接口文件所在目录)和-l(库名)并没有提供dllibexample的信息
  • gcc mian.c -o main -l/path/to/your/dir -lshlibexample -ldl -m32

    //分别指定头文件的路径和库文件的路径,动态加载

  • export LD_LIBRARY_PATH=$PWD

    //将当前目录加入默认路径

  • ./main

可执行程序的装载相关关键问题分析

execve()和fork()都是特殊的系统调用

普通系统调用

陷入内核返回用户态继续

execve

陷入内核态,使用其加载的可执行文件把当前的程序给覆盖掉,当系统调用返回的时候,返回的不是原来的程序,而是新的可执行程序了。

fork

进入内核态两次返回,第一次返回到用户态(父进程)继续执行(和普通模式一样),第二次返回内核态(子进程),是返回到ret_from_fork然后构造了一个用户态堆栈,然后进入构造的用户态堆栈继续执行。 #### 可执行程序的装载

sys_execve内部会解析可执行文件格式

  • do_execve---do_execve_common----execvebinprm
  • search_binary_handler符合寻找文件格式的解析模块

对于ELF格式的可执行文件fmt--load_binary(bprm)执行的是load_elf_binary

linux如何支持多种不同的可执行文件

load_elf_binary->start_thread

静态链接,修改内核堆栈压入的指针。ip和sp.

execve的内部处理过程

重点:start_thread把原来进程的地址改成了链接以后的位置。

可执行程序的装载与庄生梦蝶的故事

进程在int0x80中断的时候还是庄子(原来的程序),在shell加载了一个新的可执行程序,醒来的时候(返回),就变成了蝴蝶(新进程)。但是其实这是一个相互的过程,你可以装载我,返回后你变成我;我可以装载你,返回后我变成你。

浅析动态链接的可执行程序的装载

静态链接的可执行程序都是比较简单的,但是大多数都需要负载的动态链接,动态链接的时候,内核做了什么?首先elf可执行格式,需要依赖其他动态链接库,动态链接的依赖关系会形成一个图,先解析依赖哪些动态链接库,加载动态连接器ld,elf_entry返回动态链接器的入口,然后加载动态链接库,这是一个依赖关系图遍历的过程。装载和链接之后,ld将cpu的控制权交给可执行程序。

静态链接的话,elf_entry直接返回可执行程序的入口。

linux及安全第七周总结——20135227黄晓妍的更多相关文章

  1. linux及安全第八周总结——20135227黄晓妍

    实验部分 实验环境搭建 -rm menu -rf git clone https://github.com/megnning/menu.git cd menu make rootfs qemu -ke ...

  2. linux及安全第六周总结——20135227黄晓妍

    总结部分: 操作系统内核三大功能: 进程管理,内存管理,文件系统 最核心的是进程管理 为了管理,首先要对每一个进程进行描述.进程描述符提供了所有内核需要了解的信息. 进程控制模块:task_struc ...

  3. linux及安全第五周总结——20135227黄晓妍

    (注意:本文总结备份中有较多我手写笔记的图片,其中重要的部分打出来了.本文对分析system_call对应的汇编代码的工作过程,系统调用处理过程”的理解,以及流程图都写在实验部分.) 实验部分 使用g ...

  4. linux及安全第三周总结——20135227黄晓妍

    总结部分: Linux内核源代码: Arch 支持不同cpu的源代码:主要关注x86 Init   内核启动的相关代码:主要关注main.c,整个Linux内核启动代码start_kernel函数 K ...

  5. linux安全第一周总结——20135227黄晓妍

    实验部分: 我将源代码做了修改,将其中一个数字修改为我学号27 2.在实验楼环境下将其保存为text.c并将其编译,得到text.s 3.将.开头的多余的语句删去了之后,我得到了32位环境的汇编代码 ...

  6. linux及安全第二周总结——20135227黄晓妍

    实验部分: 首先运行结果截图 代码分析: Mypcb.h /* *  linux/mykernel/mypcb.h * *  Kernel internal PCB types * *  Copyri ...

  7. linux及安全期中总结——20135227黄晓妍

    Linux及安全期中总结 黄晓妍 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ...

  8. Linux基础入门学习笔记20135227黄晓妍

    学习计时:共24小时 读书:1小时 代码:8小时 作业:3小时 博客:12小时 一.学习目标 1. 能够独立安装Linux操作系统   2. 能够熟练使用Linux系统的基本命令   3. 熟练使用L ...

  9. linux及安全《Linux内核设计与实现》第四章——20135227黄晓妍

    第四章 进程调度 进程调度程序是一个内核子系统 分配有限的处理器时间和资源 最大限度利用时间的原则(只要有可执行的进程,那么总会有进程执行) 基本工作:从一组处于等待(阻塞)状态的可执行进程中选择一个 ...

随机推荐

  1. Bootstrap篇:弹出框和提示框效果以及代码展示

     前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编辑功能,一般常见的主要有两种处理方式:行内编辑和弹出框编辑.在增加用户体验方面,弹出框和提示框起着重要的作用,如果你 ...

  2. LeetCode - Customers Who Never Order

    Description: Suppose that a website contains two tables, the Customers table and the Orders table. W ...

  3. 学习坤哥的replaceTpl方法

    学习坤哥的方法之后自己写的replaceTpl function replaceTpl(tpl, data){///////////////没有传入可让用户自己定义的方式进行替换,不够灵活       ...

  4. c# 给button添加不规则的图片以及用pictureBox替代button响应点击事件

    1.Flat button 用这个方法,前提是要把button的type设置为Flat button1.TabStop = false;button1.FlatAppearance.BorderSiz ...

  5. c# 数据库数据与DataGridView表控件的绑定

    public Form1() { InitializeComponent(); //连接数据库 string str = "Data Source=IP;Initial Catalog=数据 ...

  6. 01.MyBatis入门

        MyBatis入参考文档:http://mybatis.org/mybatis-3/zh/  1.使用MyBatis前的准备 1.增加Maven依赖 <dependency> &l ...

  7. Apache POI 读写 Excel 文件

    目录 写入 Excel 文件 读取 Excel 文件 遍历 Excel 文件 需要的 maven 依赖 完整代码 写入 Excel 文件 // 写入 Excel 文件 // ============= ...

  8. Oracle管理监控之使用utl_mail自动邮件报警配置

    --代发邮件存储过程源码如下: CREATE OR REPLACE PROCEDURE send_mail(p_recipient VARCHAR2, -- 邮件接收人                 ...

  9. Jury Compromise---poj1015(动态规划,dp,)

    题目链接:http://poj.org/problem?id=1015 大致题意: 在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n 个人作为陪审团的候 ...

  10. CF734F Anton and School 构造+数论

    正解:构造 解题报告: 先放下传送门QwQ 这题首先要知道一个结论:(x&y)+(x|y)=x+y 还是能理解的趴? 所以我们把bi+ci就能得到∑a+n*a[i] 然后我们就能成功求出∑a ...