装载器-ELF文件分析【1】
来源:互联网 发布:mac怎么下载qq 编辑:程序博客网 时间:2024/06/05 06:11
ELF 文件格式解析
Linux 系统下的可执行文件、可重定位表和.so文件都是采用ELF格式存储。ELF格式起源于Unix的COFF文件格式。定义了各种段表结构体和存储方式。本文就这几个内容做一些介绍.
ELF 基本结构
ELF的基本结构是由一个ELF文件头部和多个段所组成。文件头部包括了指明该ELF文件的相关信息。比如,头部信息可以表明该文件是可执行文件,还是可重定位表 or .so文件。头部之后就是各个段排列开来,例如.text
段主要是代码段,编译后的代码一般存储在此段。.data
段为数据段,数据段主要是存放初始化的全局静态变量、局部静态变量。实际上还有只读数据段.rodata
,这个段一般存放一些常量,如字符串常量。.bss
段则是那些未初始化的全局变量和局部静态变量存储的区域。当然,实际中,段的类型和数量远不止这几种这么多,甚至用户可以自己定义属于自己的段。后面会详述这些段的组织方式和结构。
ELF整体结构
一个通用的ELF整体结构图如下所示,注意这里的节区头部表指的就是段头部表(这个表相当于一个数组,每一个元素用来描述相应段的属性例如段名、段长、段偏移等)
ELF 头部信息结构
ELF 最前面是ELF文件头(ELF-Header),它包括了描述整个文件的基本属性,如版本号、目标机器型号、程序入口地址等。ELF头中更重要的一部分是包括了对后面所有段描述的数组,该数组中的每一个元素包括了段的名字、长度、在文件中的偏移,读写权限及段的属性。
ELF Header:
Magic: xx xx xx xx xx xx xx xx xx xx //魔数Class: //ELF字长 ELF32,ELF64Data: //数据存储方式Version://版本号OS/ABI://运行平台ABI Version://ABI(application binary Interface)版本号Type://ELF重定位类型Machine://硬件平台 Intel x80386 x86_64 (是指芯片的型号与类型)Version://硬件平台版本号Entry point address://程序入口地址Start of program headers://程序头入口 ??作用Start of section headers://段头入口Flags://Size of this header:Size of program headers:Number of program headers:Size of Section headers://段头长度Number of section headers://段的数量Section header string table index:
注意 这里magic 也就是魔数,ELF文件最前面的16个字节,它是用来代表ELF文件的平台属性、字长、字序、版本等相关信息。最开始的4个字节是所有ELF度必须相同的标识码即:7F 45 4C 46。魔数的作用是用来确认文件的类型,操作系统在加载可执行文件的时候会确认魔数是否正确,如果不正确会拒绝加载。
使用binutils 工具readelf 可以读到ELF文件的头部信息,例如下面的一个例子。这是一个在ARM平台上运行ELF文件
zhr-macox@laptop:/Project/Projects/iotsecurity$ readelf -a iot_appELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2s complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: ARM Version: 0x1 Entry point address: 0x8a84 Start of program headers: 52 (bytes into file) Start of section headers: 12780 (bytes into file) Flags: 0x5000002, has entry point, Version5 EABI Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 10 Size of section headers: 40 (bytes)//段头长度 Number of section headers: 30 //一共30个段 Section header string table index: 27
以上的头部信息对应的ELF头部结构体如下:
typedef struct {unsigned char e_ident[16]; /* ELF魔数,ELF字长,字节序,ELF文件版本等 */Elf32_Half e_type; /*ELF文件类型,REL, 可执行文件,共享目标文件等 */Elf32_Half e_machine; /* ELF的CPU平台属性 */Elf32_Word e_version; /* ELF版本号 */Elf32_Addr e_entry; /* ELF程序的入口虚拟地址,REL一般没有入口地址为0 */Elf32_Off e_phoff; Elf32_Off e_shoff; /* 段表在文件中的偏移 */Elf32_Word e_flags; /* 用于标识ELF文件平台相关的属性 */Elf32_Half e_ehsize; /* 本文件头的长度 */Elf32_Half e_phentsize; Elf32_Half e_phnum;Elf32_Half e_shentsize; /* 段表描述符的大小 */Elf32_Half e_shnum; /* 段表描述符的数量 */Elf32_Half e_shstrndx; /* 段表字符串表所在的段在段表中的下标 */} Elf32_Ehdr;
其中的数据类型定义如下
ELF头部表中对段的描述
在ELF的头部中,有一部分是关于对段的描述,其中e_shoff
代表了段头描述符表(Section Data Table,注意就是段头数组)的偏移位置,e_shentsize
代表一个段头描述符的长度,e_shnum
代表该段头数组中元素的个数,也就是段的个数也就是说,通过这三个参数,可以获知该ELF文件中所有的段信息。在段头描述符表中,每个元素代表一个段的信息,也是一个结构体,这个结构体的描述如下;
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;
由此可以知道,当一个ELF文件被载入的时候,加载器可以先读取ELF的头部信息,然后根据该头部信息可以获取段头部表的偏移,获取到段头部表后,可以接儿获知该ELF文件中的所有段信息。
- 装载器-ELF文件分析【1】
- linux elf文件装载
- elf文件分析
- ELF文件加载分析
- ELF文件实例分析
- uboot2 --elf文件分析
- ELF文件分析
- ELF文件头分析
- ELF文件分析
- 链接、装载与库:Linux下的ELF文件
- ELF文件装载链接过程及hook原理
- 链接、装载与库:ELF文件解析实践
- ELF文件装载链接过程及hook原理
- ELF 文件数据分析: 全局变量
- ELF Linker学习篇(一)关于ELF文件装载进内存
- 一个obj elf文件的分析 1/2
- ELF文件格式以及装载过程
- ELF文件病毒的分析和编写
- Java图形化界面设计——容器(JFrame)
- 不启动图形化界面,不借助response file 安装db software的 10.2.0.5这个patch
- MapReduce的详细过程
- 二---JNI入门 - NDK从入门到精通(2)
- hive实例讲解实现in和not in子句
- 装载器-ELF文件分析【1】
- Oracle Forms之动态List Item Value
- App开发日报 2015-05-13 Swifter:100个Swift开发必备Tip
- 图像边缘检测经典算子及MATLAB实现
- MYSQL表的线性转换
- 超轻量级缓存技术——EhCache
- TJOI2015 Day2解题报告
- 201402 一种新的遥感影像角点提取方法
- jquery动态title和文字缩略显示