ELF文件结构描述
elf文件格式
第1章文件格式1.1 Executable and Linking Format (ELF)1.1.1整体结构ELF对象格式用于目标文件(.o扩展名)和执行文件. 有些信息只出现在目标文件或执行文件中.ELF文件由下列部件构成. ELF header必须放在文件的开始;其他部件可以随便排放(ELF header给出了其他部件的偏移量).1.1.2ELF头[ELF Header]ELF头包含目标文件的一般信息;具有如下结构(from elf.h):#define EI_NIDENT 16typedef struct {unsigned char e_ident[EI_NIDENT];Elf32_Half e_e_type;Elf32_Half e_machine;Elf32_Word e_version;Elf32_Addr e_entry;Elf32_Off e_phoff;Elf32_Off e_shoff;Elf32_Word e_flags;Elf32_Half e_ehsize;Elf32_Half e_phentsize;Elf32_Half e_phnum;Elf32_Half e_shentsize;Elf32_Half e_shnum;Elf32_Half e_shstrndx;};ELF头域描述:1.1.3程序头[Program Header]程序头为一结构数组,每个元素描述执行文件的一个可载入段.元素结构如下(from elf.h):typedef struct {Elf32_Word p_type;Elf32_Off p_offset;Elf32_Addr p_vaddr;Elf32_Addr p_paddr;Elf32_Word p_filesz;Elf32_Word p_memsz;Elf32_Word p_flags;Elf32_Word p_align;} Elf32_Phdr;1.1.4Section HeadersELF文件中的每个section的都有激励[incitation]头; Section个数由ELF Header中的e_shnum域指明. Section headers结构如下(from elf.h):typedef struct {Elf32_Word sh_name;Elf32_Word sh_type;Elf32_Word sh_flags;Elf32_Addr sh_addr;Elf32_Off sh_offset;Elf32_Word sh_size;Elf32_Word sh_link;Elf32_Word sh_info;Elf32_Word sh_addralign;Elf32_Word sh_entsize;} Elf32_Shdr;1.1.5Special Sections1.1.6重定位信息[Relocation Information]重定位信息section包含关于非确定引用[unresolved references]的信息.因为编译器[compilers]和汇编器[assemblers]不知道符号将分配的绝对内存地址,和别的文件的符号定义;所以对符号的每个引用都将创建一个重定位条目. 该条目指向地址(where the reference is being made), 和指向包含被引用符号的符号表. 连接器[linker]给所有符号分配地址之后, 将使用重定位信息添入正确的地址. 执行文件没有重定位section.例如: 汇编表示符号加上偏移:move.l var+16,d0偏移量存储在r_addend域,这样,符号真实地址加上该地址域将产生一个正确的引用.重定位条目有如下结构(from elf.h):typedef struct {Elf32_Addr r_offset;Elf32_Word r_info;Elf32_Sword r_addend;} Elf32_Rel;1.1.7符号表符号表section .symtab为一数组,数组元素包含关于被ELF文件引用的符号的信息.符号表条目有如下结构(from elf.h):typedef struct {ELF32_Word st_name;ELF32_Addr st_value;ELF32_Word st_size;unsigned char st_info;unsigned char st_other;Elf32_Half sth_shndx;} Elf32_Sym;1.1.8串表串表sections( .strtab和.shstrtab)包含符号表中符号名和section名.名都以null结束. 这些符号通过偏移指向[point into]串表. 串表的第一字节总是零, 其后所有串顺序存放.。
linux elf执行流程
linux elf执行流程Linux ELF 执行流程ELF(Executable and Linkable Format)是Linux系统中可执行文件的一种格式。
在Linux下,当我们执行一个可执行文件时,操作系统会按照一定的流程解析和执行该文件。
本文将介绍Linux ELF 的执行流程。
1. ELF文件格式ELF文件由多个段(section)组成,每个段都有特定的作用。
常见的段包括.text段(包含程序的指令)、.data段(包含程序的全局变量和静态变量)、.bss段(包含未初始化的全局变量和静态变量)等。
2. 加载可执行文件当用户在终端输入可执行文件名并按下回车键时,操作系统会通过解析文件头判断该文件是否为有效的ELF文件。
如果是有效的ELF 文件,操作系统会为该进程分配一块内存空间,并将ELF文件中的各个段加载到相应的内存地址上。
3. 解析程序入口操作系统会根据ELF文件中的程序入口地址(Entry Point)来确定程序的入口点。
程序入口地址通常位于.text段的起始位置。
操作系统将程序计数器(PC)设置为程序入口地址,从而开始执行程序。
4. 执行程序指令程序从程序入口地址开始执行,按照顺序执行.text段中的指令。
每条指令都会被解码和执行,直到程序结束或者遇到跳转指令。
5. 解析跳转指令在程序执行过程中,可能会遇到跳转指令(如条件跳转、无条件跳转、函数调用等)。
当遇到跳转指令时,操作系统会根据指令中的目标地址重新设置程序计数器,从而改变程序的执行流程。
6. 处理函数调用当程序执行到函数调用指令时,操作系统会将函数的返回地址和参数等信息保存到栈中,并跳转到函数的入口地址执行。
函数执行完毕后,操作系统会从栈中恢复返回地址,继续执行函数调用指令后面的指令。
7. 处理系统调用程序中可能会包含系统调用指令,用于请求操作系统提供各种服务。
当遇到系统调用指令时,操作系统会切换到内核态,执行相应的系统调用处理程序,并返回结果给用户程序。
elf 结构解析
elf 结构解析一、ELF文件的基本结构1. ELF文件头(ELF Header):ELF文件的入口点,包含了文件的基本信息和描述,如魔数、文件类型、入口地址等。
2. 程序头表(Program Header Table):描述了ELF文件的各个段(Segment)的加载和运行时的属性,如可执行代码段、数据段、只读段等。
3. 节头表(Section Header Table):描述了ELF文件的各个节(Section)的属性和位置信息,如代码节、数据节、字符串节等。
4. 节区(Section):包含了ELF文件的各种数据和代码,如程序的实际指令、全局变量、局部变量等。
5. 字符串表(String Table):存储了ELF文件中使用的所有字符串,如符号表中的符号名、节名等。
6. 符号表(Symbol Table):记录了ELF文件中定义和引用的各个符号的信息,如函数、变量等。
7. 重定位表(Relocation Table):用于修正程序中的跳转地址,使得程序可以正确地链接和执行。
二、ELF文件加载和链接过程1. 加载:当操作系统执行一个ELF可执行文件时,将会执行加载过程。
操作系统会按照程序头表中的描述,将各个段加载到内存中的相应位置,建立虚拟地址和物理地址之间的映射关系。
2. 符号解析:在加载过程中,操作系统会解析符号表,建立符号名与符号地址之间的映射关系。
这样,在程序执行过程中,可以通过符号名来访问对应的函数或变量。
3. 重定位:由于不同的目标文件可能会引用其他目标文件中的符号,所以在加载过程中,操作系统会根据重定位表的信息,修正程序中的跳转地址,确保程序可以正确地链接和执行。
三、ELF文件的应用1. 可执行文件:ELF格式的可执行文件可以直接在操作系统中运行,例如Linux系统中的可执行文件就是以ELF格式存储的。
2. 共享库:ELF格式的共享库包含了一组可被多个可执行文件共享的代码和数据,可以在程序运行时动态加载和链接。
ELF文件格式
ELF文件格式•目标文件有三种类型:–可重定位文件(Relocatable File)包含适合于与其他目标文件链接来创建可执行文件或者共享目标文件的代码和数据。
–可执行文件(Executable File)包含适合于执行的一个程序,此文件规定了exec()如何创建一个程序的进程映像。
–共享目标文件(Shared Object File)包含可在两种上下文中链接的代码和数据。
首先链接编辑器可以将它和其它可重定位文件和共享目标文件一起处理,生成另外一个目标文件。
其次,动态链接器(Dynamic Linker)可能将它与某个可执行文件以及其它共享目标一起组合,创建进程映像。
•目标文件全部是程序的二进制表示,目的是直接在某种处理器上直接执行。
ELF格式文件目前是UNIX系统非常常见二进制文件格式,ELF文件格式主要3大部分,ELF 文件头,节区表,和节区。
对于可执行文件对应的是段表,段。
下面这3部分简单分布情况,上面这条横条可以看成ELF文件从头到尾。
对于ELF头,节区表,节区都对应分布在文件里面,通过偏移来表示其对应在文件的位置。
2、ELF头对应字段的意义简单用下图来说明,其他字段可以对应解析3、节区相关信息4、对于节区经常使用的两个信息字段sh_info,sh_link对应字段意义5、对于一个ELF目标文件,通常都会有以下几个节区,可以通readelf–S test.oSection Headers:[Nr]Name Type Addr Off Size ES Flg Lk Inf Al [0]NULL0000000000000000000000000[1].text PROGBITS0000000000003400001100AX004[2].data PROGBITS0000000000004800000000WA004[3].bss NOBITS0000000000004800000000WA004[4].comment PROGBITS0000000000004800002a00001[5].note.GNU-stack PROGBITS0000000000007200000000001[6].shstrtab STRTAB0000000000007200004500001[7].symtab SYMTAB0000000000022000008010874[8].strtab STRTAB000000000002a000000a00001符号表:对应于.symtab,它保存着目标文件中所有的符号信息字符串表:.strtab,保存字符窜信息。
ELF文件格式分析
ELF⽂件格式分析⼀般的 ELF ⽂件包括三个索引表:ELF header,Program header table,Section header table。
1)ELF header:在⽂件的开始,保存了路线图,描述了该⽂件的组织情况。
2)Program header table:告诉系统如何创建进程映像。
⽤来构造进程映像的⽬标⽂件必须具有程序头部表,可重定位⽂件不需要这个表。
3)Section header table :包含了描述⽂件节区的信息,每个节区在表中都有⼀项,每⼀项给出诸如节区名称、节区⼤⼩这类信息。
⽤于链接的⽬标⽂件必须包含节区头部表,其他⽬标⽂件可以有,也可以没有这个表。
⼀、分析ELF⽂件头vi /usr/include/elf.h查看elf头数据结构⽤readelf –h 1(可执⾏⽂件名)读取⼀个简单可执⾏⽂件的elf头可见elf头⼤⼩为52字节,⽤dump命令16进制读取前52个字节进⾏分析命令:hexdump –x 1 –n 52解析:第⼀⾏,对应e_ident[EI_NIDENT]。
⼩端法实际表⽰内容为7f454c46010101000000000000000000,前四个字节为elf固定开头7f454c46(0x45,0x4c,0x46是'e','l','f'对应的ascii编码),表⽰这是⼀个ELF对象。
接下来的⼀个字节01表⽰是⼀个32位对象,接下来的⼀个字节01表⽰是⼩端法表⽰,再接下来的⼀个字节01表⽰⽂件头版本。
剩下的默认都设置为0.第⼆⾏,e_type值为0x0002,表⽰是⼀个可执⾏⽂件。
e_machine值为0x0003,表⽰是intel80386处理器体系结构。
e_version值为0x00000001,表⽰是当前版本。
e_entry值为0x08048320,表⽰⼊⼝点。
e_phoff值为0x00000034,表⽰程序头表的偏移量为0x34即52个字节刚好是elf头⼤⼩。
ELF文件格式分析
ELF文件格式分析ELF(Executable and Linkable Format)是一种常见的可执行文件格式,用于在UNIX和类UNIX系统上存储和执行程序。
在本文中,我们将详细分析ELF文件格式的结构和各个部分的作用。
首先是标识部分,它占据ELF文件的最开始位置,有以下几个字段:1. Magic Number:ELF文件的前四个字节,用于识别文件类型。
对于32位系统,它的值是0x7F、'E'、'L'和'F';对于64位系统,它的值是0x7F、'E'、'L'和'F'以及0x022.类型:指定了ELF文件的类型,比如可执行文件、目标文件、共享库等等。
3.类型机器:指定了目标机器的体系结构,如x86、ARM等等。
4.版本:指定了ELF文件的版本号。
5.入口点:对于可执行文件,指定程序的入口点。
6.程序头表和节头表的偏移地址和大小。
接下来是文件头部分,它描述了ELF文件的整体结构和布局:1.类型:表示ELF文件的类型,如可重定位文件、可执行文件、共享目标文件等。
2.目标机器:标识目标机器的类型。
3.版本:指定了ELF文件的版本号。
4.入口点:指定程序的入口点。
5.程序头表偏移地址和节头表偏移地址。
6.程序头表项的大小、数量和节头表项的大小、数量。
7.字符串表索引,用于找到文件中的字符串。
最后是节头表部分,它包含了所有节(Section)的相关信息,比如代码段、数据段等等。
每个节头表项包含以下字段:1.节的名称:用于标识节的名称。
2.节的类型:描述节的属性,如代码段、数据段、符号表等。
3.节的标志:描述节的属性,如可写、可执行等。
4.节的虚拟地址:指定节在内存中的虚拟地址。
5.节的文件偏移地址:指定节在文件中的偏移地址。
6.节的大小:指定节的大小。
7.链接和信息:用于指定其他与节相关的信息。
通过分析ELF文件的结构,我们可以获得有关程序入口点、机器类型、节的信息等重要的元数据。
elf中的filesize
elf中的filesizeElf中的文件大小:探索文件大小与存储空间的关系在计算机领域中,文件大小是指文件占用的存储空间大小。
在Elf (可执行和可链接格式)文件中,文件大小是一个重要的指标,它决定了文件在系统中的存储需求和传输速度。
本文将探索Elf文件中的文件大小,并分析文件大小与存储空间的关系。
一、Elf文件的结构和组成Elf文件是一种常见的二进制文件格式,用于存储可执行程序、库文件和目标文件。
它由多个节(section)组成,每个节都有自己的类型和内容。
Elf文件的头部(header)包含了对文件结构的描述信息,如文件大小、节表的位置和偏移量等。
二、Elf文件大小的计算Elf文件的大小由多个因素决定,包括头部的大小、节的大小以及其他元数据的大小。
在计算文件大小时,需要考虑以下几个方面:1. 头部大小:Elf文件的头部包含了对文件的描述信息,如文件的魔数、版本号等。
头部的大小在不同的Elf文件中可能有所不同,但通常都是固定大小。
2. 节的大小:Elf文件中的每个节都有自己的大小。
不同类型的节可能包含不同的数据,如代码、数据、符号表等。
每个节的大小由其中包含的数据量决定。
3. 对齐方式:为了提高访问效率和存储利用率,Elf文件中的节通常按照一定的对齐方式进行存储。
对齐方式可以使节的大小增大,从而增加文件的大小。
4. 其他元数据:除了头部和节的数据外,Elf文件可能还包含其他元数据,如字符串表、重定位表等。
这些元数据也会增加文件的大小。
Elf文件的大小可以通过计算头部大小、节的大小和其他元数据的大小来得出。
三、文件大小与存储空间的关系文件大小与存储空间之间存在着紧密的关系。
文件大小决定了文件在存储介质中占用的空间大小,而存储空间则决定了系统可以存储的文件数量和传输文件的速度。
1. 存储介质的容量:存储介质的容量决定了系统可以存储的文件大小。
如果一个Elf文件的大小超过了存储介质的容量,那么该文件将无法存储在该介质中。
elf结构与编译运行
elf结构与编译运行Elf结构与编译运行一、引言Elf(Executable and Linkable Format)是一种可执行和可链接格式,广泛应用于Linux系统中的可执行文件、共享库和内核模块。
本文将着重介绍Elf结构以及与编译运行相关的内容。
二、Elf结构Elf结构由多个部分组成,包括文件头、程序头表、节区头表和节区数据。
下面将逐一介绍这些部分的作用和内容。
1. 文件头(File Header)文件头包含了一些描述整个Elf文件的基本信息,如文件类型、目标体系结构、入口地址等。
文件头的大小固定为52个字节,可以通过读取文件头来确定Elf文件的版本和目标体系结构。
2. 程序头表(Program Header Table)程序头表描述了如何创建一个进程映像,包括加载和运行程序所需的信息。
每个条目都描述了一个段(segment),段是进程映像的基本单位,用于存储代码、数据等信息。
程序头表的大小和数量可变,每个条目的大小为32个字节。
3. 节区头表(Section Header T able)节区头表包含了所有节区的描述信息,如名称、大小、类型等。
节区是Elf文件中的一个逻辑部分,用于存储不同类型的数据,如代码、数据、符号表等。
节区头表的大小和数量可变,每个条目的大小为40个字节。
4. 节区数据(Section Data)节区数据是Elf文件中实际存储的各个节区的数据内容。
每个节区的数据内容可以是代码、数据、符号表等。
三、编译运行过程编译运行是将源代码编译成可执行文件并执行的过程。
一般包括以下几个步骤:预处理、编译、汇编、链接和运行。
1. 预处理(Preprocessing)预处理是编译过程的第一步,主要进行宏展开、头文件包含等操作。
预处理器将源代码中的宏定义进行替换,并将头文件的内容插入到源代码中,生成预处理后的代码。
2. 编译(Compiling)编译是将预处理后的代码转换为汇编语言的过程。
二进制基础 elf文件结构
二进制基础 elf文件结构ELF文件是一种常见的可执行文件格式,用于在计算机系统中存储和运行可执行程序。
它是以二进制形式存储的,具有特定的结构和组织方式。
ELF文件由多个段(Section)组成,每个段都有特定的功能和用途。
其中,最重要的段是代码段(text section)和数据段(data section)。
代码段包含可执行程序的机器指令,而数据段包含程序运行所需的数据。
除了代码段和数据段,ELF文件还包含其他一些重要的段,如符号表段和重定位表段。
符号表段记录了程序中定义和引用的符号信息,用于链接和调试程序。
重定位表段则记录了需要进行地址重定位的位置和信息。
ELF文件还包含了一些元数据,如文件头(File Header)和程序头(Program Header)。
文件头包含了文件的基本信息,如文件类型、目标体系结构和入口地址等。
程序头则描述了ELF文件中各个段的位置和大小等信息。
在计算机系统中,使用ELF文件格式的可执行程序可以直接加载到内存中运行。
当操作系统加载一个ELF文件时,它会解析文件头和程序头,将各个段加载到内存中的合适位置。
然后,操作系统将控制权转交给程序的入口地址,从而开始执行程序。
ELF文件的结构和组织方式使得它具有很好的可扩展性和可移植性。
不同的编程语言和编译器都可以生成符合ELF文件格式的可执行程序,从而实现跨平台的兼容性。
ELF文件是一种以二进制形式存储的可执行文件格式,具有特定的结构和组织方式。
通过解析ELF文件的各个段和元数据,操作系统可以加载和运行程序。
ELF文件的设计使得它具有很好的可扩展性和可移植性,成为计算机系统中常见的可执行文件格式之一。
ELF文件结构描述
ELF⽂件结构描述ELF⽬标⽂件格式最前部ELF⽂件头(ELF Header),它包含了描述了整个⽂件的基本属性,⽐如ELF⽂件版本、⽬标机器型号、程序⼊⼝地址等。
其中ELF⽂件与段有关的重要结构就是段表(Section Header Table)ELF⽂件格式1. 可重定向⽂件:⽂件保存着代码和适当的数据,⽤来和其他的⽬标⽂件⼀起来创建⼀个可执⾏⽂件或者是⼀个共享⽬标⽂件。
(⽬标⽂件或者静态库⽂件,即linux通常后缀为.a和.o的⽂件)2. 可执⾏⽂件:⽂件保存着⼀个⽤来执⾏的程序。
(例如bash,gcc等)3. 共享⽬标⽂件:共享库。
⽂件保存着代码和合适的数据,⽤来被下连接编辑器和动态链接器链接。
(linux下后缀为.so的⽂件。
)另外的windows下为pe格式的⽂件;ELF视图⾸先,ELF⽂件格式提供了两种视图,分别是链接视图和执⾏视图。
链接视图是以节(section)为单位,执⾏视图是以段(segment)为单位。
链接视图就是在链接时⽤到的视图,⽽执⾏视图则是在执⾏时⽤到的视图。
上图左侧的视⾓是从链接来看的,右侧的视⾓是执⾏来看的。
总个⽂件可以分为四个部分:ELF header:描述整个⽂件的组织。
Program Header Table: 描述⽂件中的各种segments,⽤来告诉系统如何创建进程映像的。
sections 或者 segments:segments是从运⾏的⾓度来描述elf⽂件,sections是从链接的⾓度来描述elf⽂件,也就是说,在链接阶段,我们可以忽略program header table来处理此⽂件,在运⾏阶段可以忽略section header table来处理此程序(所以很多加固⼿段删除了section header table)。
从图中我们也可以看出, segments与sections是包含的关系,⼀个segment包含若⼲个section。
Section Header Table: 包含了⽂件各个segction的属性信息,我们都将结合例⼦来解释。
ELF文件格式分析
ELF文件格式分析ELF(Executable and Linkable Format)是一种标准的文件格式,用于存储可执行代码,共享库和核心转储文件。
它在UNIX系统中广泛使用,包括Linux和BSD。
ELF文件格式的设计旨在提供一种灵活的格式,以满足各种不同类型的程序和软件库的需要。
在本文中,我们将对ELF文件格式进行详细分析,并深入探讨其结构和各个部分的作用。
1.ELF文件格式概述ELF文件格式由头部(Header)、节区表(Section Table)、节区(Section)、程序头部(Program Header)和数据部分组成,其中头部和节区表是ELF文件的核心组成部分,用于描述整个文件的结构和内容。
程序头部用于描述如何将节区加载到内存中以执行程序。
节区是文件内容的实际载体,包含各种类型的数据和代码。
2. ELF文件头部(Header)- e_ident:ELF头部的标识字段,用于标识文件的类型、字节序及其他相关信息。
- e_type:文件的类型,包括可执行文件、共享库、目标文件等。
- e_machine:目标机器的体系结构,如x86、ARM、MIPS等。
- e_version:文件的版本号。
- e_entry:程序的入口地址,即程序开始执行的地址。
- e_phoff:程序头部表的偏移量。
- e_shoff:节区头部表的偏移量。
- e_flags:标识文件特定属性的标志位。
- e_phentsize:每个程序头部表项的大小。
- e_phnum:程序头部表的项数。
- e_shentsize:每个节区头部表项的大小。
- e_shnum:节区头部表的项数。
头部的格式在不同的ELF文件版本中会有所不同,但一般遵循上述结构。
头部的内容是用于解析和执行ELF文件的关键信息,因此它是整个文件结构中最重要的部分之一3. 节区表(Section Table)节区表包含了描述各个节区的信息,包括名称、偏移量、大小、类型等。
elf文件编码方式
elf文件编码方式ELF文件编码方式ELF(Executable and Linkable Format)是一种可执行和可链接的文件格式,它是Linux系统中常用的二进制文件格式。
在Linux系统中,ELF文件包括可执行文件、共享库、目标文件等类型。
本文将详细介绍ELF文件的编码方式。
1. ELF文件结构ELF文件由三个部分组成:头部、节区表和节区数据。
其中,头部包含了整个ELF文件的基本信息,节区表记录了各个节区的位置和大小等信息,节区数据则包含了程序代码、数据和其他相关信息。
2. ELF头部ELF头部是一个固定大小的结构体,它包含了整个ELF文件的基本信息。
在32位系统中,其大小为52字节,在64位系统中其大小为64字节。
下面是一个32位系统下的ELF头部结构体:```typedef struct {unsigned char e_ident[16]; /* ELF标识 */Elf32_Half e_type; /* 文件类型 */Elf32_Half e_machine; /* 机器类型 */Elf32_Word e_version; /* 文件版本号 */Elf32_Addr e_entry; /* 程序入口地址 */Elf32_Off e_phoff; /* 程序头表偏移量 */Elf32_Off e_shoff; /* 节区表偏移量 */Elf32_Word e_flags; /* 处理器特定标志 */Elf32_Half e_ehsize; /* ELF头部大小 */Elf32_Half e_phentsize; /* 程序头表项大小 */Elf32_Half e_phnum; /* 程序头表项数目 */Elf32_Half e_shentsize; /* 节区表项大小 */Elf32_Half e_shnum; /* 节区表项数目 */Elf32_Half e_shstrndx; /* 节区字符串表索引 */} Elf32_Ehdr;```其中,e_ident是一个16字节的数组,用于标识ELF文件的类型、机器类型、文件版本等信息。
elf文件代码段长度 数据段长度 padding之间的关系-概述说明以及解释
elf文件代码段长度数据段长度padding之间的关系-概述说明以及解释1.引言1.1 概述概述:ELF(Executable and Linkable Format)是一种广泛用于Unix类操作系统的可执行文件格式,它包含了程序在内存中执行所需的所有信息。
在一个ELF文件中,代码段和数据段都是存放程序的关键部分,而Padding 则是用来填充文件空间的字节。
本文将探讨ELF 文件中代码段长度、数据段长度以及Padding 之间的关系,分析它们在程序执行过程中的作用和重要性。
通过深入了解这些概念,我们可以更好地理解可执行文件的结构,从而更好地编写和调试程序,提高软件开发的效率和质量。
文章结构如下:1. 引言1.1 概述1.2 文章结构1.3 目的2. 正文2.1 ELF文件格式简介2.2 代码段长度与数据段长度的概念2.3 Padding在ELF文件中的作用3. 结论3.1 ELF文件中代码段、数据段和Padding的关系总结3.2 实际应用中的重要性3.3 展望与未来发展方向在文章中,将对ELF文件的结构和内容进行介绍和分析,重点探讨代码段长度、数据段长度以及Padding之间的关系,以及它们在ELF文件中的作用和重要性。
最后展望未来发展方向,指出该研究领域的潜力和前景。
1.3 目的本文旨在探讨ELF 文件中代码段长度、数据段长度以及Padding 之间的关系。
通过深入分析ELF 文件格式的特点,我们将解释代码段和数据段在文件中的表示方式,以及为什么在编译过程中需要适当的Padding 来保证文件的正确性和可执行性。
通过这篇文章,读者将能够更好地理解ELF 文件的组成结构,加深对程序执行过程中内存分配和加载的理解,为日后的软件开发和调试工作提供帮助。
章1.3 目的部分的内容2.正文2.1 ELF文件格式简介:ELF(Executable and Linkable Format)是一种常见的可执行文件格式,它被广泛应用于Linux等操作系统中。
ELF文件解析(一):Segment和Section
ELF⽂件解析(⼀):Segment和SectionELF 是Executable and Linking Format的缩写,即可执⾏和可链接的格式,是Unix/Linux系统ABI (Application Binary Interface)规范的⼀部分。
Unix/Linux下的可执⾏⼆进制⽂件、⽬标代码⽂件、共享库⽂件和core dump⽂件都属于ELF⽂件。
下⾯的图来⾃于⽂档,描述了ELF⽂件的⼤致布局。
左边是ELF的链接视图,可以理解为是⽬标代码⽂件的内容布局。
右边是ELF的执⾏视图,可以理解为可执⾏⽂件的内容布局。
注意⽬标代码⽂件的内容是由section组成的,⽽可执⾏⽂件的内容是由segment组成的。
要注意区分段(segment)和节(section)的概念,这两个概念在后⾯会经常提到。
我们写汇编程序时,⽤.text,.bss,.data这些指⽰,都指的是section,⽐如.text,告诉汇编器后⾯的代码放⼊.text section中。
⽬标代码⽂件中的section和section header table中的条⽬是⼀⼀对应的。
section的信息⽤于链接器对代码重定位。
⽽⽂件载⼊内存执⾏时,是以segment组织的,每个segment对应ELF⽂件中program header table中的⼀个条⽬,⽤来建⽴可执⾏⽂件的进程映像。
⽐如我们通常说的,代码段、数据段是segment,⽬标代码中的section会被链接器组织到可执⾏⽂件的各个segment中。
.text section的内容会组装到代码段中,.data, .bss等节的内容会包含在数据段中。
在⽬标⽂件中,program header不是必须的,我们⽤gcc⽣成的⽬标⽂件也不包含program header。
⼀个好⽤的解析ELF⽂件的⼯具是readelf。
对我本机上的⼀个⽬标代码⽂件sleep.o执⾏readelf -S sleep.o,输出如下:There are 12 section headers, starting at offset 0x270:Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .text PROGBITS 0000000000000000 000000400000000000000015 0000000000000000 AX 0 0 1[ 2] .rela.text RELA 0000000000000000 000001e00000000000000018 0000000000000018 I 9 1 8[ 3] .data PROGBITS 0000000000000000 000000550000000000000000 0000000000000000 WA 0 0 1[ 4] .bss NOBITS 0000000000000000 000000550000000000000000 0000000000000000 WA 0 0 1... ... ... ...[11] .shstrtab STRTAB 0000000000000000 000002100000000000000059 0000000000000000 0 0 1Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),l (large), p (processor specific)readelf -S是显⽰⽂件中的Section信息,sleep.o中共有12个section, 我们省略了其中⼀些Section的信息。
ELF文件格式解析
ELF⽂件格式解析⽬录数据类型⾸先在解析之前,必须对数据类型格式声明⼀下名称⼤⼩说明Elf32_Addr4⽆符号程序地址Elf32_Half2⽆符号中等整数Elf32_Off4⽆符号⽂件偏移Elf32_SWord4有符号⼤整数Elf32_Word4⽆符号⼤整数unsigned char1⽆符号笑整数整体结构概述ELF头部(ELF_Header): 每个ELF⽂件都必须存在⼀个ELF_Header,这⾥存放了很多重要的信息⽤来描述整个⽂件的组织,如: 版本信息,⼊⼝信息,偏移信息等。
程序执⾏也必须依靠其提供的信息。
程序头部表(Program_Header_Table): 可选的⼀个表,⽤于告诉系统如何在内存中创建映像,在图中也可以看出来,有程序头部表才有段,有段就必须有程序头部表。
其中存放各个段的基本信息(包括地址指针)。
节区头部表(Section_Header_Table): 类似与Program_Header_Table,但与其相对应的是节区(Section)。
节区(Section): 将⽂件分成⼀个个节区,每个节区都有其对应的功能,如符号表,哈希表等。
段(Segment): 嗯…就是将⽂件分成⼀段⼀段映射到内存中。
段中通常包括⼀个或多个节区*注:每个节区都应该是前后相连的,且不可有重叠。
即在⼀个地址上的字节只能属于⼀个节区*详解ELF_Header以下是ELF_Header的结构定义typedef struct {Elf32_Half e_type; //Elf⽂件类型Elf32_Half e_machine; //ELF⽂件的CPU平台属性Elf32_Word e_version; //ELF版本信息Elf32_Addr e_entry; //⼊⼝地址Elf32_Off e_phoff; //程序头表的⽂件偏移(以字节为单位)。
如果⽂件没有程序头表,则此成员值为零。
Elf32_Off e_shoff; //节头表的⽂件偏移(以字节为单位)。
ELF文件格式简介
Linux下的ELF文件格式简介1. 概述Executable and linking format(ELF)文件是x86 Linux系统下的一种常用目标文件(object file)格式,有三种主要类型:(1)适于连接的可重定位文件(relocatable file),可与其它目标文件一起创建可执行文件和共享目标文件。
(2)适于执行的可执行文件(executable file),用于提供程序的进程映像,加载的内存执行。
(3)共享目标文件(shared object file),连接器可将它与其它可重定位文件和共享目标文件连接成其它的目标文件,动态连接器又可将它与可执行文件和其它共享目标文件结合起来创建一个进程映像。
ELF文件格式比较复杂,本文只是简要介绍它的结构,希望能给想了解ELF文件结构的读者以帮助。
具体详尽的资料请参阅专门的ELF文档。
2. 文件格式为了方便和高效,ELF文件内容有两个平行的视角:一个是程序连接角度,另一个是程序运行角度,如图1所示。
ELF header在文件开始处描述了整个文件的组织,Section提供了目标文件的各项信息(如指令、数据、符号表、重定位信息等),Program header table指出怎样创建进程映像,含有每个program header的入口,Section header table包含每一个section的入口,给出名字、大小等信息。
图13. 数据表示ELF数据编码顺序与机器相关,数据类型有六种,见表1。
4. ELF文件头象bmp、exe等文件一样,ELF的文件头包含整个文件的控制结构。
它的定义如下:其中E_ident的16个字节标明是个ELF文件(7F+'E'+'L'+'F'+class+data+version+pad)。
E_type表示文件类型,2表示可执行文件。
E_machine说明机器类别,3表示386机器,8表示MIPS机器。
elf文件详解
ARM的可执行文件的格式是ELF格式文件,下文对ELF格式做个详细的介绍。
序言1. OBJECT文件导言ELF头(ELF Header)SectionsString表(String Table)Symbol表(Symbol Table)重定位(Relocation)2. 程序装载与动态连接导言Program头(Program Header)Program装载(Program Loading)Dynamic连接(Dynamic Linking)3. C LIBRARYC Library________________________________________________________________ 导言________________________________________________________________ ELF: 可执行连接格式可执行连接格式是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface(ABI)而开发和发布的。
工具接口标准委员会(TIS)选择了正在发展中的ELF标准作为工作在32位INTEL体系上不同操作系统之间可移植的二进制文件格式。
假定开发者定义了一个二进制接口集合,ELF标准用它来支持流线型的软件发展。
应该减少不同执行接口的数量。
因此可以减少重新编程重新编译的代码。
关于这片文档这篇文档是为那些想创建目标文件或者在不同的操作系统上执行文件的开发着准备的。
它分以下三个部分:* 第一部分, “目标文件O bject Files”描述了ELF目标文件格式三种主要的类型。
* 第二部分, “程序转载和动态连接”描述了目标文件的信息和系统在创建运行时程序的行为。
* 第三部分, “C 语言库”列出了所有包含在libsys中的符号,标准的ANSI C和libc的运行程序,还有libc运行程序所需的全局的数据符号。
ELF文件格式
ELF⽂件格式ELF(executable and linkable format)可执⾏可链接格式,是⼀种⽤于⼆进制⽂件、可执⾏⽂件、⽬标代码、共享库和核⼼转储格式⽂件。
1.2.1ELF⽂件类型ELF主要分为3种⽂件类型:1、可重定位⽂件(relocatable file)后缀“.o” “.rel”:⽬标⽂件编译完成,尚未链接。
⼀般多个⽬标⽂件链接成⼀个可执⾏⽂件或共享⽬标⽂件也,也就是下⾯两种⽂件。
2、可执⾏⽂件(executable file)后缀“.exec”:linux中执⾏的程序。
2、共享⽬标⽂件(shared object file)后缀".dyn":也就是库⽂件。
⽤途1:和其他可重定位⽂件以及共享⽬标⽂件链接⽣成新的可重定位⽂件;⽤途2:动态链接时和可执⾏⽂件链接在⼀起运⾏。
还有⼀种ELF⽂件--核⼼转储⽂件(Core Dump file):程序异常终⽌后对地址空间的转储。
可以使⽤gdb读取⽂件查找异常原因。
1.2.2 ELF⽂件的结构⽬标⽂件既有链接阶段⼜有执⾏阶段,在两个阶段规定的⽂件格式有所不同。
如图1。
图1 在链接视⾓程序头表是可选,通过节(section)来划分;在运⾏视⾓节头表是可选,通过段(segment)来划分(段⼤都来⾃链接阶段的节);注意:除ELF Header位置固定外,其他部分位置、⼤⼩通过ELF Header的内容来确定。
节⼀般包含代码节(.text)、数据节(.data)、BSS节(.bss)。
代码节⽤于保存机器指令,数据节保存以初始化全局变量和局部静态变量,BSS节保存未初始化全局变量和局部静态变量。
将数据和指令分开存放有利于安全,设置代码节对进程只读、数据和BSS节可读写。
ELF ⽂件头(ELF Header) ELF⽂件头固定于程序的最开始,⽤于描述ELF⽂件的基本信息,例如⽂件类型、程序⼊⼝等;注意:⽂件头存在魔术字符(7f 45 4c 46),可通过搜索该字符来确定映射地址的位置。
elf 结构体详解
elf 结构体详解
"elf"是Executable and Linkable Format的缩写,是一种用
于可执行文件、共享库和核心转储文件的标准文件格式。
它是一种
通用的、可移植的二进制文件格式,用于在不同的操作系统和体系
结构之间共享可执行文件和相关的信息。
在Linux系统中,可执行文件和共享库通常使用ELF格式。
ELF
文件由多个部分组成,其中最重要的部分是ELF头部、节头部表和
节区。
ELF头部包含了文件的基本信息,如文件类型、目标体系结构、入口点地址等。
节头部表包含了每个节区的描述信息,如名称、偏移量、大小等。
而节区则包含了实际的数据和代码。
ELF结构体是用来表示ELF文件格式的数据结构。
在C语言中,可以使用结构体来定义ELF头部、节头部表和节区等部分的数据结构,以便于对ELF文件进行解析和操作。
从技术角度来看,ELF结构体包括了多个字段,每个字段对应
了ELF文件中的一个部分,如ELF头部、节头部表、节区等。
通过
对这些结构体的使用,可以方便地对ELF文件进行解析和操作,如
读取ELF头部信息、遍历节区等。
此外,ELF结构体的定义还可以包括一些辅助函数,用于对ELF
文件进行读取、解析和操作。
这些函数可以实现对ELF文件的加载、重定位、符号解析等功能,从而实现对ELF文件的动态链接和执行。
总的来说,ELF结构体是用来表示ELF文件格式的数据结构,
在对ELF文件进行解析和操作时,可以使用这些结构体和相关的辅
助函数,以实现对ELF文件的读取、解析、加载和执行等功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ELF文件结构描述3.4 ELF文件结构描述我们已经通过SimpleSection.o的结构大致了解了ELF文件的轮廓,接着就来看看ELF 文件的结构格式。
图3-4描述的是ELF目标文件的总体结构,我们省去了ELF一些繁琐的结构,把最重要的结构提取出来,形成了如图3-4所示的ELF文件基本结构图,随着我们讨论的展开,ELF文件结构会在这个基本结构之上慢慢变得复杂起来。
ELF目标文件格式的最前部是ELF文件头(ELF Header),它包含了描述整个文件的基本属性,比如ELF文件版本、目标机器型号、程序入口地址等。
紧接着是ELF文件各个段。
其中ELF文件中与段有关的重要结构就是段表(Section Header Table),该表描述了ELF文件包含的所有段的信息,比如每个段的段名、段的长度、在文件中的偏移、读写权限及段的其他属性。
接着将详细分析ELF文件头、段表等ELF关键的结构。
另外还会介绍一些ELF中辅助的结构,比如字符串表、符号表等,这些结构我们在本节只是简单介绍一下,到相关章节中再详细展开。
3.4.1 文件头我们可以用readelf命令来详细查看ELF文件,代码如清单3-2所示。
ELF文件头结构及相关常数被定义在“/usr/include/elf.h”里,因为ELF文件在各种平台下都通用,ELF文件有32位版本和64位版本。
它的文件头结构也有这两种版本,分别叫做“Elf32_Ehdr”和“Elf64_Ehdr”。
32位版本与64位版本的ELF文件的文件头内容是一样的,只不过有些成员的大小不一样。
为了对每个成员的大小做出明确的规定以便于在不同的编译环境下都拥有相同的字段长度,“elf.h”使用typedef定义了一套自己的变量体系,如表3-3所示。
我们这里以32位版本的文件头结构“Elf32_Ehdr”作为例子来描述,它的定义如下:让我们拿ELF文件头结构跟前面readelf输出的ELF文件头信息相比照,可以看到输出的信息与ELF文件头中的结构很多都一一对应。
有点例外的是“Elf32_Ehdr”中的e_ident 这个成员对应了readelf输出结果中的“Class”、“Data”、“Version”、“OS/ABI”和“ABI Version”这5个参数。
剩下的参数与“Elf32_Ehdr”中的成员都一一对应。
我们在表3-4中简单地列举一下,让大家有个初步的印象,详细的定义可以在ELF标准文档里面找到。
表3-4是ELF文件头中各个成员的含义与readelf输出结果的对照表。
这些字段的相关常量都定义在“elf.h”里面,我们在表3-5中会列举一些常见的常量,完整的常量定义请参考“elf.h”。
ELF魔数我们可以从前面readelf的输出看到,最前面的“Magic”的16个字节刚好对应“Elf32_Ehdr”的e_ident这个成员。
这16个字节被ELF标准规定用来标识ELF文件的平台属性,比如这个ELF字长(32位/64位)、字节序、ELF文件版本,如图3-5所示。
最开始的4个字节是所有ELF文件都必须相同的标识码,分别为0x7F、0x45、0x4c、0x46,第一个字节对应ASCII字符里面的DEL控制符,后面3个字节刚好是ELF这3个字母的ASCII码。
这4个字节又被称为ELF文件的魔数,几乎所有的可执行文件格式的最开始的几个字节都是魔数。
比如a.out格式最开始两个字节为 0x01、0x07;PE/COFF文件最开始两个个字节为0x4d、0x5a,即ASCII字符MZ。
这种魔数用来确认文件的类型,操作系统在加载可执行文件的时候会确认魔数是否正确,如果不正确会拒绝加载。
接下来的一个字节是用来标识ELF的文件类的,0x01表示是32位的,0x02表示是64位的;第6个字是字节序,规定该ELF文件是大端的还是小端的(见附录:字节序)。
第7个字节规定ELF文件的主版本号,一般是1,因为ELF标准自1.2版以后就再也没有更新了。
后面的9个字节ELF标准没有定义,一般填0,有些平台会使用这9个字节作为扩展标志。
各种魔数的由来a.out格式的魔数为0x01、0x07,为什么会规定这个魔数呢?UNIX早年是在PDP小型机上诞生的,当时的系统在加载一个可执行文件后直接从文件的第一个字节开始执行,人们一般在文件的最开始放置一条跳转(jump)指令,这条指令负责跳过接下来的7个机器字的文件头到可执行文件的真正入口。
而0x01 0x07这两个字节刚好是当时PDP-11的机器的跳转7个机器字的指令。
为了跟以前的系统保持兼容性,这条跳转指令被当作魔数一直被保留到了几十年后的今天。
计算机系统中有很多怪异的设计背后有着很有趣的历史和传统,了解它们的由来可以让我们了解到很多很有意思的事情。
这让我想起了经济学里面所谓的“路径依赖”,其中一个很有意思的叫“马屁股决定航天飞机”的故事在网上流传很广泛,有兴趣的话你可以在google以“马屁股”和“航天飞机”作为关键字搜索一下。
ELF文件标准历史20世纪90年代,一些厂商联合成立了一个委员会,起草并发布了一个ELF文件格式标准供公开使用,并且希望所有人能够遵循这项标准并且从中获益。
1993年,委员会发布了ELF文件标准。
当时参与该委员会的有来自于编译器的厂商,如Watcom和Borland;来自CPU 的厂商如IBM和Intel;来自操作系统的厂商如IBM和Microsoft。
1995年,委员会发布了ELF 1.2标准,自此委员会完成了自己的使命,不久就解散了。
所以ELF文件格式标准的最新版本为1.2。
文件类型 e_type成员表示ELF文件类型,即前面提到过的3种ELF文件类型,每个文件类型对应一个常量。
系统通过这个常量来判断ELF的真正文件类型,而不是通过文件的扩展名。
相关常量以“ET_”开头,如表3-5所示。
常量值含义机器类型 ELF文件格式被设计成可以在多个平台下使用。
这并不表示同一个ELF文件可以在不同的平台下使用(就像java的字节码文件那样),而是表示不同平台下的ELF文件都遵循同一套ELF标准。
e_machine成员就表示该ELF文件的平台属性,比如3表示该ELF 文件只能在Intel x86机器下使用,这也是我们最常见的情况。
相关的常量以“EM_”开头,如表3-6所示。
3.4.2 段表我们知道ELF文件中有很多各种各样的段,这个段表(Section Header Table)就是保存这些段的基本属性的结构。
段表是ELF文件中除了文件头以外最重要的结构,它描述了ELF 的各个段的信息,比如每个段的段名、段的长度、在文件中的偏移、读写权限及段的其他属性。
也就是说,ELF文件的段结构就是由段表决定的,编译器、链接器和装载器都是依靠段表来定位和访问各个段的属性的。
段表在ELF文件中的位置由ELF文件头的“e_shoff”成员决定,比如SimpleSection.o中,段表位于偏移0x118。
前文中我们使用了“objudmp -h”来查看ELF文件中包含的段,结果是SimpleSection 里面看到了总共有6个段,分别是“.code”、“.data”、“.bss”、“.rodata”、“.comment”和“.note.GNU-stack”。
实际上的情况却有所不同,“objdump -h”命令只是把ELF文件中关键的段显示了出来,而省略了其他的辅助性的段,比如:符号表、字符串表、段名字符串表、重定位表等。
我们可以使用readelf工具来查看ELF文件的段,它显示出来的结果才是真正的段表结构:readelf输出的结果就是ELF文件段表的内容,那么就让我们对照这个输出来看看段表的结构。
段表的结构比较简单,它是一个以“Elf32_Shdr”结构体为元素的数组。
数组元素的个数等于段的个数,每个“Elf32_Shdr”结构体对应一个段。
“Elf32_Shdr”又被称为段描述符(Section Descriptor)。
对于SimpleSection.o来说,段表就是有11个元素的数组。
ELF段表的这个数组的第一个元素是无效的段描述符,它的类型为“NULL”,除此之外每个段描述符都对应一个段。
也就是说SimpleSection.o共有10个有效的段。
数组的存放方式ELF文件里面很多地方采用了这种与段表类似的数组方式保存。
一般定义一个固定长度的结构,然后依次存放。
这样我们就可以使用下标来引用某个结构。
Elf32_Shdr被定义在“/usr/include/elf.h”,代码如清单3-3所示。
Elf32_Shdr的各个成员的含义如表3-7所示。
注1:事实上段的名字对于编译器、链接器来说是有意义的,但是对于操作系统来说并没有实质的意义,对于操作系统来说,一个段该如何处理取决于它的属性和权限,即由段的类型和段的标志位这两个成员决定。
注2:关于这些字段,涉及一些映像文件的加载的概念,我们将在本书的第2部分详细介绍其相关内容,读者也可以先阅读第2部分的最前面一章“可执行文件的装载与进程”,了解一下加载的概念,然后再来阅读关于段的虚拟大小和虚拟地址的内容。
当然,如果读者对映像文件加载过程比较熟悉,应该很容易理解这些内容。
让我们对照Elf32_Shdr和“readelf -S”的输出结果,可以很明显看到,结构体的每一个成员对应于输出结果中从第二列“Name”开始的每一列。
于是SimpleSection的段表的位置如图3-6所示。
到了这一步,我们才彻彻底底把SimpleSection的所有段的位置和长度给分析清楚了。
在图3-6中,SectionTable长度为0x1b8,也就是440个字节,它包含了11个段描述符,每个段描述符为40个字节,这个长度刚好等于sizeof(Elf32_Shdr),符合段描述符的结构体长度;整个文件最后一个段“.rel.text”结束后,长度为0x450,即1104字节,即刚好是SimpleSection.o的文件长度。
中间Section Table和“.rel.text”都因为对齐的原因,与前面的段之间分别有一个字节和两个字节的间隔。
段的类型(sh_type) 正如前面所说的,段的名字只是在链接和编译过程中有意义,但它不能真正地表示段的类型。
我们也可以将一个数据段命名为“.text”,对于编译器和链接器来说,主要决定段的属性的是段的类型(sh_type)和段的标志位(sh_flags)。
段的类型相关常量以SHT_开头,列举如表3-8所示。
段的标志位(sh_flag) 段的标志位表示该段在进程虚拟地址空间中的属性,比如是否可写,是否可执行等。
相关常量以SHF_开头,如表3-9所示。
段的链接信息(sh_link、sh_info) 如果段的类型是与链接相关的(不论是动态链接或静态链接),比如重定位表、符号表等,那么sh_link和sh_info这两个成员所包含的意义如表3-11所示。