================================================================================
目标文件从结构上讲是已经编译后的可执行文件格式,可执行文件格式涵盖了程序的编译、
链接、装载、执行的各个方面。
================================================================================
目标文件格式:COFF(Common file format)格式的变种
Windows:PE(Portable Executable)
Linux:ELF(Executable Linkable Format)
可执行文件、动态链接库、静态链接库-->按照可执行文件存储
================================================================================
ELF4类文件:
可从定位文件(Relocatable File)
可执行文件(Executable File)
共享目标文件(Shared Object File)
核心转储文件(Core Dump File)
================================================================================
目标文件信息:机器指令代码、数据、符号表、调试信息、字符串
信息按照不同的属性:以“节”(段)的形式存储
--------------------------------------------------------------------------------
段的属性:
段的长度(Size):
段的位置(File Offset):
各段的属性:CONTENTS(该段在文件中存在),ALLOC
--------------------------------------------------------------------------------
文件头:整个文件的属性(是否可执行、是静态链接还是动态连接及入口地址、目标硬件、目标操作系统
段表(Section Table))。
段表:描述文件中各个段的数组,描述文件中各个段在文件中的偏移位置及段的属性,段表里可以得到
每个段的所有信息
代码段(Code Section)(.code .text):程序源代码变异后的机器指令
数据段(Data Section)(.data):全局变量和局部静态变量
(.bss):未初始化的全局变量和局部静态变量
只读数据段(.rodata):const修饰的变量和字符串常量
注释信息段(.comment):
堆栈提示段(.note.GUN-stack):
--------------------------------------------------------------------------------
其他段:
.rodata1
.comment
.debug
.dynamic
.hash
.line
.note
.strtab
.symtab
.shstrtab
.plt.got
.init.fini
自定义段
================================================================================
程序数据分开的好处:待定82 --------------------------------------------
================================================================================
ELF文件结构描述:
头文件:描述整个文件的基本属性(文件版本、目标机器型号、程序入口地址)
段表:所有段的信息(段的名称、段的长度。在文件中的偏移、读取权限、其他属性)
头文件定义:
ELF魔数、文件机器字节长度、数据存储方式、版本、运行平台、ABI版本、ELF重定位类型、
硬件平台、硬件平台版本、入口地址、程序入口和长度、段表的位置和长度及段的数量。
变量体系:
自定义类型 :描述、原始类型、长度
Elf32_Addr : 32位版本程序地址、uint32_t、4
Elf32_Half : 32位版本的无符号短×××、uint16_t、2
Elf32_Off : 32位版本的偏移地址、uint32_t、4
Elf32_Sword : 32位版本有符号×××、uint32_t、4
Elf32_Word : 32位版本无符号×××、uint32_t、4
typedef struct{
usigned char e_ident[16];--Magic、Class、Data、Version、OS/ABI、ABI Version
Elf32_Half e_type; --ELF文件类型
Elf32_Half e_machine; --ELF文件的CPU平台属性,相关常量以EM_开头
Elf32_Word e_version; --ELF版本号,一般为常数1
Elf32_Addr e_entry; --入口地址,规定ELF程序的入口虚拟地址,操作系统在加载完
该程序后,从这个地址开始执行进程的指令,可重定位文件一般
没有入口地址,则这个值为0
Elf32_Off e_phoff; --Unkown
Elf32_Off e_shoff; --段表在文件中的偏移
Elf32_Word e_flags; --ELF标志位,用来标示一些ELF文件平台相关的属性,相关常量的
格式一般为EF_machine_flag,machine为平台,falg为标志
Elf32_Half e_ehsize; --ELF文件头本身的大小
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize; --段表的描述符大小,这个一般等于sizeof(Elf32_Shdr)
Elf32_Half e_shnum; --段表描述符数量,这个值等于ELF文件中拥有的段的数量
Elf32_Half e_shstrndx; --段表字符串表所在的段表中的下标
} Elf32_Ehdr;
例:7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
DEL控制符:0x7f
ELF魔数:0x45、0x4c、0x46
文件结构:0x01->32位、0x02->64位
字节序:0x01
主版本号:0x01
----------------------------------------------------------------------------
文件类型:
ET_REL 1 可重定位文件,一般为.o文件
ET_EXEC 2 可执行文件
ET_DYN 3 共享目标文件,一般为.so文件
机器类型:
EM_M32 1 AT&T WE32100
EM_SPARC 2 SPARC
EM_386 3 intel x86
EM_68K 4 Motorola 68000
EM_88K 5 Mototola 88000
EM_860 6 intel 80860
====================================================================================
段表:
typedef struct {
Elf32_Word sh_name; --段名字符串在”.shstrtab“中的偏移
Elf32_Word sh_type; --段的类型
Elf32_word sh_flags; --段的标志位
Elf32_Addr sh_addr; --如果该段可被加载,则为加载后在进程空间中的虚拟地址
否则为0
Elf32_Off sh_offset; --如果该段存在于文件中,则表示该段在文件中的偏移,否则无意义
Elf32_Word sh_size; --Section Size 段的长度
Elf32_Word sh_link; --段的链接信息
Elf32_Word sh_info; --段的链接信息
Elf32_Word sh_addralign; --Section Address Alignment 段地址对齐(99页)
Elf32_Word sh_entsize; --Section Entry Size 项的长度
} Elf32_Shdr;
-----------------------------------------------------------------------------------
段的类型:
SHT_NULL 0 无效段
SHT_PROGBITS 1 程序段、代码段、数据段
SHT_SYMTAB 2 符号表
SHT_STRTAB 3 字符串
SHT_RELA 4 重定位表(该段包含了重定位信息)
SHT_HASH 5 符号表的哈希表
SHT_DYNAMIC 6 动态链接信息
SHT_NOTE 7 提示性信息
SHT_NOBITS 8 表示该段没有内容
SHT_REL 9 包含了重定位信息
SHT_SHLIB 10 保留
SHT_DNYSYM 11 动态链接的符号表
------------------------------------------------------------------------------------
段的标志位:
SHF_WRITE 1 表示该段在进程空间中可写
SHF_ALLOC 2 表示该段在进程空间中需要分配空间(代码段、数据段、.bss段)
SHF_EXECINSTR 4 表示该段在进程空间中可以被执行
------------------------------------------------------------------------------------
段的链接信息;如果段的类型与链接相关才有意义
sh_type sh_link sh_info
SHT_DYNAMIC 该段所使用的字符串表在段表的下标 0
SHT_HASH 该段所使用的符号表在段表中的下标 0
SHT_REL/RELA 该段所使用的相应的符号表在段表中的下标 该重定位表所作用的段在段表中的下标
SHT_SYMTAB 操作系统相关的 操作系统相关的
SHT_SYNSYM 操作系统相关的 操作系统相关的
other SHN_UNDEF 0
========================================================================================
重定位表:
102