一步步编写操作系统 47 elf格式文件分析实验

在上一节中,我们讲述了elf格式的部分理论知识,为什么是部分呢?因为我们本着“够用”的原则,只把我们需要了解的部分说完啦。不过,我相信大部分同学仅仅凭上一节中的理论知识还是领悟不到elf本质,咱们在本节开始分析前面咱们写过的“内核”,让大家看清elf文件的每一个字节。

为了让大家看清楚elf文件内部,咱们要用之前的xxd命令,为了方便使用,如很久很久以前所述,已经将其封装成了xxd.sh脚本,参数1是待查看的文件名,参数2是文件内的起始字节,参数3是查看的连续字节数。脚本是逐字节输出文件的内容。脚本内容很简单,就是xxd命令而已:xxd -u -a -g 1 -s $2 -l $3 $1,您也看到了,参数比较多,弄成脚本完全是为了避免每次复杂的参数键入。为了让大家方便使用,我已经将其放到了tool目录下,脚本中有参数说明,这里不再列出。下面是用此脚本处理kernel.bin的输出,见图

之前我们就用过多次xxd命令啦,对于输出想必大家一定很熟悉啦。脚本的输出大概分了三部分,最左边的一列是16进制的地址,或者称为偏移量最为恰当。中间这一大块矩阵似的16进制数字是文件中的内容,每两位16进制数字为一字节,每行共16个字节。最右边那一列,含有点点的、偶尔伴有可读字符的部分是字符显示区,这部分将内容按照字符编码显示,当然,前提肯定得是可打印字符,控制字符肯定不行,所以只要不是可显示的字符便显示为‘.’。

为了方便大家查看elf文件中各部分属性,我在各属性下面用下划线予以区分。其中,细下划线属于elf header的范围,粗下划线属于program header table程序头表的范围。在各范围之中的各属性,又以明显的下划线分隔,相信大家一定能一目了然。

咱们按照从上到下的顺序,先从细下划线的elf header部分说起。

第一行是e_ident数组,前4字节是固定的elf魔数,正如您看到的,它们是0x7f、和字符ELF的ascii:0x45、0x4c、0x46。所以您在显示区看到了ELF的三个字符。紧跟其后的三个1分别是e_ident[4]、e_ident[5]、e_ident[6]三个成员,代表的意义是32位elf文件、小端字节序、当前版本。后面的9个00是e_ident[7]~ e_ident[15],这些确实都已经初始化为0。

现在看第二行。

第1个下划线处的内容是02 00,由于是小端字节序,所以其值为0x0002。以下为方便陈述,只说该字节序所表示的数值。这个是e_type属性,它占2字节,值为2表示类型为ET_EXEC,即可执行文件(有兴趣的同学可以自行查看linux下的.o目标文件,其e_type类型是值为1的ET_REL,即待重定位类型)。

本行的第2个下划线处的内容是0x0003,占2字节。该位置是e_machine属性,即EM_386,表示该elf文件是运行在Intel 80386平台。

第3个下划线处的内容是0x00000001,占4字节。该位置是e_version属性,即版本信息。

第4个下划线处的内容是0xc0001500,占4字节,该位置是e_entry属性,即程序的虚拟入口地址。

第5个下划线处的内容是0x00000034,占4字节,该位置是e_phoff属性,表示program header table程序头表在文件中的偏移量,这里的偏移量是0x34。

现在看第三行。

第1个下划线处的内容是0x0000055c,占4字节,该位置是e_shoff,表示section header table节头表在文件内的偏移量,这里的值为0x55c,表示在本文件偏移0x55c字节处为节头表。之前说过啦,若没有节头表,此处便为0。

第2个下划线处的内容是0x00000000,占4字节,该位置是e_flags属性。

第3个下划线处的内容是0x0034,占2字节,该位置是e_ehsize属性,表示elf header大小是0x34字节。这和前面e_phoff属性值大小一致,可见,程序头表紧跟着elf header之后。

第4个下划线处的内容是0x0020,占2字节,该位置是e_phentsize属性,即program header的结构:struct Elf32_Phdr的字节大小,值为0x20字节。

第5个下划线处的内容是0x0002,占2字节,该位置是e_phnum属性,即程序头表中段的个数,这里为2个段。

第6个下划线处的内容是0x0028,占2字节,该位置是e_shentsize属性,即节头表中各个节的大小。

现在看第四行。

第1个下划线处的内容是0x0006,占2字节,该位置是e_shnum属性,即节头表中节的个数,这里表示有6个节。

第2个下划线处的内容是0x0003,占2字节,该位置是e_shstrndx属性,即string name table在节头表中的索引为3。

现在开始分析粗下划线范围的程序头表部分。

从第4行到第8行是程序头表的范围,前面说过啦,程序头表中共有2个段,每个段大小是0x20字节。这有两个粗下划线,每个占0x20字节。大家注意图中,在两个粗下划线间有个小竖线,这是用来区分两个段的。竖线左右两边各是一个段。

下面咱们按照struct Elf32_Phdr结构来分析,该结构中每个属性都占4字节,不再赘述。现在还是继续说图的第4行。

第1个粗下划线值为0x00000001,该位置是p_type属性,值为1,即表示PT_LOAD类型,可加载程序段,由于kernel.bin已经是链接后的可执行程序啦,所以,这PT_LOAD类型符合我们的认知。

第2个粗下划线值为0x00000000,该位置是p_offset属性,表示本段在文件内的偏移量。这个偏移量为0,似乎很奇怪,这表示该段的起始是从文件头开始也算起啦,文件开头的部分不是elf header吗?不是代码啊,这是要闹哪样?好吧,到底是什么情况,一会咱们细说。

第3个粗下划线值为0xc0001000,该位置是p_vaddr属性,表示本段被加载到内存后的起始虚拟地址。看到这里,似乎觉得上面的p_offset为0有那么一点合理啦,结合elf header中的e_entry的值为0xc0101500,不知您想到了点什么。咱们先把剩下的说完。

第4个粗下划线值为0xc0001000,该位置是p_paddr属性,它通常和p_vaddr值一致,但该属性是保留项,咱们不用关注。

第5个粗下划线值为0x00000505,该位置是p_filesz属性,表示本段在文件中的字节大小。

第6个粗下划线值也应该是0x00000505,该位置是p_memsz属性,表示本段在内存中的大小,因为段无论在哪里,逻辑大小是不变的,故该值等于p_filesz。

第7个粗下划线值为0x00000005,该位置是p_flags属性,表示与本段相关的标志。5=4+1=PF_R+PF_X,在此表示可读,可执行,根据此属性,我们推测此段为代码段。

第8个粗下划线值为0x00001000,该位置是p_align属性,表示本段对齐的方式。

第一个段咱们说完了,第二个段这里就不解释啦,留着大家自己练手吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度飞桨顶会论文复现(5):视频分类论文之《Representation Flow for Action Recognition》篇

这次老师在课上总共领读了4篇分类论文,我这里分享其中的一篇论文,是关于使用神经网络对光流进行学习。 课程地址是:https://aistudio.baidu.com/aistudio/education/group/info/1340。 论文地址是:https://arxiv.org/abs/1810.014…

智能算法(GA、DBO等)求解零等待流水车间调度问题(NWFSP)

先做一个声明:文章是由我的个人公众号中的推送直接复制粘贴而来,因此对智能优化算法感兴趣的朋友,可关注我的个人公众号:启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法,经典的,或者是近几年…

【蓝桥官网试题 - 算法提高】change(思维)

题干: 问题描述 数组A中共有n个元素,初始全为0。你可以对数组进行两种操作:1、将数组中的一个元素加1;2、将数组中所有元素乘2。求将数组A从初始状态变为目标状态B所需要的最少操作数。 输入格式 第一行一个正整数n表示数组中元…

一步步编写操作系统 50 加载内核3

接上节,在这里,我们把参数放到了栈中保存,大家注意到了,参数入栈的顺序是先从最右边的开始,最后压入的参数最左边的,其实这是某种约定,要不,为什么不先把中间的参数src入栈呢。既然主…

【POJ - 2965】The Pilots Brothers' refrigerator(暴力枚举,思维)

题干: The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator. There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrige…

动手学无人驾驶(5):多传感器数据融合

本系列的前4篇文章主要介绍了深度学习技术在无人驾驶环境感知中的应用,包括交通标志识别,图像与点云3D目标检测。关于环境感知部分的介绍本系列暂且告一段落,后续如有需要再进行补充。 现在我们开启新的篇章,在本文中将会介绍无人…

一步步编写操作系统 52 深入浅出cpu的特权级

所谓保护模式下的“保护”,主要体现在特权级上,以后随着后面工作的展开,会越来越多的和它们打交道,现在是时候说道说道了。 在人类社会中出现恶势力时,人们总是希望出现一位具有神力的英雄来拯救世人、主持公道。阶级…

详解两阶段3D目标检测网络PVRCNN:Point-Voxel Feature Set Abstraction for 3D Object Detection

在《动手学无人驾驶(4):基于激光雷达点云数据3D目标检测》一文中介绍了3D目标检测网络PointRCNN。今天介绍该作者新提出的3D检测模型:PVRCNN,论文已收录于CVPR2020。 作者个人主页为:https://sshaoshuai.gi…

【Codeforces - 755C】PolandBall and Forest(并查集)

题干: PolandBall lives in a forest with his family. There are some trees in the forest. Trees are undirected acyclic graphs with k vertices and k - 1 edges, where k is some integer. Note that one vertex is a valid tree. There is exactly one …

一步步编写操作系统 53 任务状态段TSS介绍

操作系统是利用PCB来维护所有任务的,包括进程和线程,但cpu提供的是TSS,linux系统可没用它,因为效率太低。但是还是要了解下TSS才清楚操作系统中某些操作的原因。 本节中所讲的特权级与它有着密不可分的联系,TSS作用不…

动手学无人驾驶(6):基于IMU和GPS数据融合的自车定位

在上一篇博文《动手学无人驾驶(5):多传感器数据融合》介绍了如何使用Radar和LiDAR数据对自行车进行追踪,这是对汽车外界运动物体进行定位。 对于自动驾驶的汽车来说,有时也需要对自身进行更精确的定位,今天…

【Codeforces - 798C】 Mike and gcd problem(思维,贪心)

题干: Mike has a sequence A  [a1, a2, ..., an] of length n. He considers the sequence B  [b1, b2, ..., bn] beautiful if the gcd of all its elements is bigger than 1, i.e. . Mike wants to change his sequence in order to make it beauti…

一步步编写操作系统 48 加载内核1

其实,我们等了这一刻好久好久,即使我不说,大家也有这样的认识,linux内核是用c 语言写的,咱们肯定也要用c语言。其实...说点伤感情的话,今后的工作只是大部分(99%)都要用c语言来写&am…

Coursera自动驾驶课程第1讲:Welcome to the self-driving cars specialization

本专栏为Coursera自动驾驶课程笔记,B站上也有配套课程视频,对自动驾驶技术感兴趣的朋友可以看看。 本讲对应视频: https://www.bilibili.com/video/BV1WE411D74g?p1https://www.bilibili.com/video/BV1WE411D74g?p2https://www.bilibili.…

【CodeForces - 999D】Equalize the Remainders(思维,贪心)

题干: You are given an array consisting of nn integers a1,a2,…,ana1,a2,…,an, and a positive integer mm. It is guaranteed that mm is a divisor of nn. In a single move, you can choose any position ii between 11 and nn and increase aiai by 11. …

Coursera自动驾驶课程第2讲:The Requirements for Autonomy

上一讲《Coursera自动驾驶课程第1讲:Welcome to the self-driving cars specialization》对本课程进行了整体概述,同时回顾了自动驾驶汽车的发展历史。 从本讲我们开始进入正式的学习,我们将首先了解到如何划分自动驾驶汽车等级、以及自动驾…

一步步编写操作系统 51 加载内核4

咱们的内容都是连栽的,如果您没看过我之前的文章,本节您是看不懂的。 接上节。 介绍完内核初始化的函数kernel_init后,本节代码部分还差一点点没说啦,下面看代码: …略 179 ;在开启分页后,用gdt新的地址…

【CodeForces - 777C】Alyona and Spreadsheet(思维,前缀和)

题干: During the lesson small girl Alyona works with one famous spreadsheet computer program and learns how to edit tables. Now she has a table filled with integers. The table consists of n rows and mcolumns. By ai, j we will denote the integ…

Coursera自动驾驶课程第3讲:Self-Driving Hardware and Software Architectures

在上一讲《Coursera自动驾驶课程第2讲:The Requirements for Autonomy》中我们了解到了如何划分自动驾驶汽车等级、以及自动驾驶三大模块:感知、决策和执行。 本讲我们将学习新的模块:自动驾驶汽车的硬件和软件架构。 B站视频链接&#xff…

一步步编写操作系统 54 CPL和DPL入门1

我们在工作中,公司都给员工配有员工卡,此员工卡就是员工身份的“标签”,用它来出入公司、食堂就餐等。给公司创造价值的是员工的生产力,不是员工卡,员工卡只是公司人事部门管理员工的一种手段而已。 现在说计算机&…