当前位置: 首页 > 编程日记 > 正文

Linux内核分析——可执行程序的装载

链接的过程

  • 首先运行C预处理器cpp,将C的源程序(a.c)翻译成ASCII码的中间文件(a.i)
  • 接着C编译器ccl,将a.i翻译成ASCII汇编语言文件a.s
  • 接着运行汇编器as,将a.s翻译成可重定位的目标文件a.o
  • 最终完全链接成可执行文件a.out

目标文件

  • 目标文件有三种形式:
    • 可重定位的目标文件
    • 可执行目标文件
    • 共享目标文件
  • ELF格式的可重定位目标文件的结构如下:
    745369-20160406230209718-1098564426.png

  • .text:已编译程序的机器代码
  • .rodata:只读数据
  • .data:已初始化的全局C变量
  • .bss:未初始化的全局C变量.在目标文件中这个节不占实际空间,仅是一个占位符.
  • .sysmtab:一个符号表,存放在程序中被定义和引用的函数和全局变量的信息.
  • .rel.text:当链接器把这个目标文件和其他文件结合时,.text节中的许多位置都需要修改.一般而言,任何调用外部函数或者引用全局变量的指令都要修改.另一个方面,调用本地函数的指令则不需要修改.
  • .rel//.data:被模块定义或引用的任何全局变量的信息.
  • .debug:一个调试符号表
  • .line:原始C源程序中的行号和.text节中机器指令之间的映射.
  • .strtab:一个字符串表,其中内容包括.symtab和.debug节中的符号表,以及节头部中的节名字.
  • 可以通过readelf -h process查看的ELF文件的头部信息

如何将新程序的数据保存下来

  • 通过shell程序调用execve将命令行参数和环境参数传递给可执行程序的main函数中。而后execve在创建新的用户态堆栈时,则将main函数中参数压入堆栈中。最终执行sys_execve来真正实现在系统下参数的传递。

  • 当新的可执行文件被调用的时候,则旧的可执行文件所占有的空间会被新的可执行文件所占用,从而execve返回时,返回的并非为旧的可执行文件所产生的数据,而是新加载进来的可执行文件的返回数据,从而使新的可执行文件可以被执行。

可执行文件的相关点

  • start_thread通过修改内核堆栈中EIP的值作为新程序的起点

  • 根据静态链接的可执行文件elf_entry就是可执行文件头中的起点entry,多为main函数对应的位置

  • 若需要依赖动态链接库的话,则elf_entry则指向动态链接器的起点,即将CPU控制权交给ld来加载依赖库并完成动态链接

  • 新的可执行程序被调用前,需要通过修改int 0x80压入内核堆栈的EIP

  • elf可执行文件会被默认映射到0x8048000这个地址上

execve在内核中的执行过程

  • execve运行可执行程序的主要步骤:
    • 删除已存在的用户区域:删除当前可执行文件所占有的用户部分中的堆栈空间

    • 隐藏私有区域:为新程序的文本、数据和堆栈创建新的他空间,而这些空间是新的可执行文件所私有的,并且是写时拷贝的。

    • 映射共享区域:如果ELF文件与共享目标连接,就需要动态链接,并映射至用户虚拟地址空间中的共享区域。

    • 设置程序计数器:设置EIP,使其指向新的可执行文件的入口地址
    • 如下图:
      745369-20160406230317109-1267165922.png

execve函数在内核中执行流程

  • 在用户态中调用execve(),引发系统中断,在内核态中执行对应的函数sys_execve

  • sys_execve函数调用do_execve函数,该函数会读入可执行文件。

  • 接下来系统会调用search_binary_handler,根据可执行文件的类型查找到相应的处理函数。根据每种文件创建一个struct linux_binfmt的结构体,并将其连接到一个链表智商,执行时候系统就会遍历这个链表,从而找到相应的结构。
    从而调用对应的load_binary函数开始加载可执行文件。

  • 系统是通过load_elf_binary来加载elf类型的可执行文件。该函数会先读入ELF文件的头部,根据ELF文件的头部信息读入各种数据。

  • 如果存在动态链接库,则需要将动态链接映射到共享区域之中。此时就需要使用load_elf_interp来加载映像,并把返回的入口地址设置为load_elf_interp的动态链接器的入口

  • 如下图所示:

745369-20160406230350343-546577203.png

实验部分

实验目的

使用gdb跟踪sys_execve内核函数的处理过程,分析exec*函数对应的系统调用处理过程,理解Linux内核如何装载和启动一个可执行程序。

实验过程

  • 执行MenuOS,其中装载了execve
    745369-20160410190340687-695592489.png

  • 设置断点
    745369-20160410190423547-1800364681.png

  • 装载和运行一个可执行文件的顺序为:

sys_execve() -> do_execve() -> do_execve_common() -> exec_binprm() -> search_binary_handler() -> load_elf_binary() -> start_thread()

总结

  • 当linux内核或程序(例如shell)用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序。

  • 当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始

池彬宁 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

转载于:https://www.cnblogs.com/Spr1ngxx/p/5361615.html

相关文章:

c语言中external,static关键字用法

static用法: 在C中,static主要定义全局静态变量、定义局部静态变量、定义静态函数。 1、定义全局静态变量:在全局变量前面加上关键字static,该全局变量变成了全局静态变量。全局静态变量有以下特点。 a.在全局区分配内存。 b.如…

男神女神配——alpha阶段总结

一、需求分析 虽然公共社交网络系统能够满足大多数高校校园用户在校园网络社交的需求,但是针对校园学习、工作和文化生活等方面的支持以及学校个性化需求方面却存在不足。利用电子校务平台的数据,设计了与真实校园环境和活动紧密结合,包含具有…

正向代理和反向代理??

(5 条消息)正向代理 反向代理 本质区别? - 知乎 https://www.zhihu.com/question/36412304/answer/76804314 正向代理,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代…

虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通

UE5 Niagara学习教程 课程获取:虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通-云桥网 你会学到什么 我将通过创建各种各样的实时效果来教你虚幻引擎中强大的粒子系统。 我们将从简单的基础知识开始,然后逐渐地,我们将…

share extension 不显示_你所不知道的网红小酒馆Helens

当夜幕降临后,Helens小酒馆显示出她真正的魅力约上你的好友,来Helens体验一次穿越异国的饮酒之旅吧由美、中、泰设计师倾力打造,有着浓郁的东南亚异域style。木质的桌椅、精美的木雕装饰,每个细节都可以感受到不同文化的碰撞。别样…

怎么将jenkins打包后的war自动部署到jetty上?

1,使用maven的cargo插件,实现远程部署 (官网描述地址:https://codehaus-cargo.github.io/cargo/JettyRemoteDeployer.html) Maven中添加配置文件: Type: 可选参数有remote(远程部署的模式&#…

自制青蛙跳台阶小游戏~

青蛙跳台阶小游戏 1、概念(concept)文档 楔子(Setting):千百年来,人们在贬低别人时,常用井底之蛙来描述那个人,但这却让青蛙不开心了,于是青蛙决定跳出井底,为自己讨一个公道。 玩法…

提高性能的Varnish缓存方案

转载http://www.s135.com/post/313/arnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (http://www.vg.no) 使用3台Varnish代替了原来的12台squid,性能居然比以前更好。Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一&am…

Python学习小甲鱼视频003

变量 变量名就类似于我们现实社会的名字,发一个值赋值给一个名字的时候,它会存储在内存中,称之为变量(Variable) 但是Python并没有将值存储在变量中,而更像是把名字贴在值上。或者说Python只有名字而没有…

虚幻引擎的数学知识学习教程 Math for Unreal Engine (Early Preview)

通过做真实世界的 Unreal Engine项目来学习数学 你会学到什么 理解游戏开发对数学的基本需求 将数学直接应用到用例中,而不是钻研理论(用我们的示例项目进行实践) 正确编辑短视频,节省您的时间 本课程涵盖向量数学、基础三角、叉/点积和四元数旋转 要求…

2016.4.2 动态规划练习--讲课整理

1.codevs1742 爬楼梯 时间限制: 1 s空间限制: 128000 KB题目等级 : 黄金 Gold题目描述 Description小明家外面有一个长长的楼梯,共N阶。小明的腿很长,一次能跨过一或两阶。有一天,他突发奇想,想求出从最低阶到最高阶共有几种爬楼梯…

matlab 通过矩阵变换使图像旋转平移_图像的几何变换

学习图像中的仿射变换(affine transform), 这是一种线性变换(涵盖旋转,平移,错切(shear), 缩放等线性变换),既然是线性变换则可以通过线性变换(矩阵)来获得。仿射变换矩阵M为2*3的矩阵。仿射变换…

用伪代码模拟洗衣机的运转流程

今天的软导课又学到了不少“骚操作”,其中就包括Pseudocode和Top-down design。 不如现在就借着介绍洗衣机的运转流程向大家介绍一下这两个简单的东西。 题目如下 仔细观察您洗衣机的运作过程,运用Top-down设计方法和Pseudocode 描述洗衣机控制程序。 假…

使用 PHP 在站点上构建类似 Twitter 的系统

2019独角兽企业重金招聘Python工程师标准>>> 如果您曾经留意过,就会知道 Twitter 是 Web 2.0 世界最大的轰动事件之一。简单来说,Twitter(Twitter.com 上提供的一个服务)是一个简单的微博客服务,用户可以发…

Python中的变量以及赋值语句

列表的拷贝区别。 就是在Python中的任何的变量只是一个单纯的名字。名字只是数据的一个贴纸,名字可以来回的变动 赋值语句: 变量就像临时的“存储器”(就像厨房中的锅碗瓢盆),它的强大之处就在于,我们在操…

UE4制作程序背景游戏 Make a game with Procedural Backgrounds in UE4

使用虚幻引擎4蓝图创建一个程序背景的游戏 你会学到什么 学习虚幻引擎4要领 使用程序切片创建标高 保存并加载某些游戏元素 创造一个无止境的跑步者角色 创建和完成游戏的良好习惯和实践 MP4 |视频:h264,1280720 |音频:AAC,44.1 KHz 语言:英…

android pop3与imap方式接收邮件(javamail)

需要下载3个jar包&#xff1a;mail.jar/ activation.jar/ additionnal.jar 1.pop3/** * 以pop3方式读取邮件&#xff0c;此方法不能读取邮件是否为已读&#xff0c;已经通过测试 * */ private void getEmail() { List<Map<String, Object>> list new A…

什么是条件组合覆盖_物史政组合分析,新高考最终受益者丨选科17期

导读&#xff0c;规划物理历史政治是新高考33模式下存在的选科组合&#xff0c;为了给马上面临选科问题的高一、高二考生提供有效帮助&#xff0c;自主选拔在线选科模型解读第17期就来分析一下该组合的学科特性、适合人群、优势劣势、专业覆盖及往年选考情况。说明&#xff1a;…

进击时代!王雪红的谦卑与坚守

节前&#xff0c;HTC董事长王雪红发表了一封内部信&#xff0c;王雪红在心中表示&#xff0c;2015年&#xff0c;HTC不仅要在质量、创新能力与工作效率方面更进步&#xff0c;并表示&#xff0c;“我们未来企业成长的动能不仅包含智能手机&#xff0c;还会加入新的领域如RE、虚…

Python中的过滤器

寄语&#xff1a;新的有一天&#xff0c;开始了&#xff0c;让我们把内心的一些想法都放一放&#xff0c;努力去学习吧。 《Python基础教程&#xff08;第2版&#xff0c;修订版&#xff09;&#xff09;》 Assignment 赋值 Variable 变量 Nan是一种特殊的简写 not a numb…

UE4材质着色器全面学习教程

你会学到什么 通过所有着色器类型和设计的实际演示&#xff0c;学习创建材质 要求 对虚幻的基本理解会有所帮助 了解纹理的一般知识(不仅限于UE4)也很有用 描述 在这个系列中&#xff0c;我将带你设置大量不同的材料&#xff0c;教你如何以实用的方式使用虚幻4材料系统。我们…

codeforces #310 div1 C

操作无论是U还是L&#xff0c;都会使原图形分裂成两个图形&#xff0c;且两个图形的操作互不影响 我们又发现由于操作点只可能在下斜线上&#xff0c;如果将操作按x排序 那么无论是U还是L&#xff0c;都会将操作序列完整分割成两半&#xff0c;且两个操作序列互不影响 这样我们…

硬盘温度70度正常吗_70多岁老年人原来血压160,现在130正常吗?医生为你分析实情...

70多岁的老年人&#xff0c;原来有高血压&#xff0c;高压160左右&#xff0c;现在是130左右&#xff0c;正常吗&#xff1f;这个问题问的太过笼统&#xff0c;我们只好通过这个问题&#xff0c;来分享一些老年高血压患者血压控制的一些知识点&#xff0c;希望能够对老年人的高…

使用python愉快地做高数线代题目~

今天接触到了python&#xff0c;发现真是极易上手啊&#xff01;对比c语言是什么鬼东西 诶&#xff0c;等下&#xff0c;看完教学文章发现TA在下面写了这句话 如果做了前面的内容你可能已被吸引了&#xff0c;觉得c语言真的是废材! 不。。。不是的。。。python 基础库几乎都…

Docker总结

2019独角兽企业重金招聘Python工程师标准>>> 查看docker的子命令&#xff0c;直接敲docker或完整的docker help就可以了: bash-3.2$ docker Usage: docker [OPTIONS] COMMAND [arg...] A self-sufficient runtime for linux containers. Options:-D, --debugfalse …

Python中的对象,类,super()函数

对象&#xff1a;&#xff08;1&#xff09;外观的特征 &#xff08;2&#xff09;正在做的事情 比如&#xff1a;那个穿蓝色衣服的正在打球的帅哥 类&#xff1a;属性&#xff08;静态的变量&#xff09;方法&#xff08;函数&#xff09;是对对象的近似 类名约定是以大写字…

Blender赛车动画制作学习教程 Learn Race Car Animation with Blender

使用Blender 2.93创建您自己的惊人汽车动画 你会学到什么 Blender的界面和导航 建模 UV制图 材料 动画 照明设备 渲染 合成 要求 下载并安装Blender。免费下载和免费用于任何目的。 MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&…

数据结构-线性表的顺序结构

1 #include "stdio.h"2 #include "stdlib.h"3 4 typedef int ElemType; //线性表存储基本类型5 typedef int Status; //基本操作函数类型6 #define LIST_INT_SIZE 50 //线性表初始化存储空间分配量7 #define LISTINCREMENT 10 //线…

项目背景怎么描述_课程游戏背景下幼儿户外活动的组织和实施 ——记岱山县课程项目实施组活动...

课程游戏背景下幼儿户外活动的组织与实施——记岱山县课程项目实施组活动为了深入推进园本化课程实施的实践与研究&#xff0c;加强项目组幼儿园课程的建设与实施&#xff0c;提升项目组幼儿园课程质量。11月23日&#xff0c;县课程项目实施组活动在东沙镇中心幼儿园开展。本次…