第二部分主要介绍ELF的格式,ELF是Executable and Linkable Format的缩写,即可执行与可链接的文件格式的总称。ELF是UNIX系统常见的标准文件格式,如可执行文件、目标文件、共享库文件及core dumps文件。
一般来说,ELF文件由三部分组成:可执行文件的头、节和段
链接视图(节视图) |
执行视图(段视图) |
ELF文件的头 |
ELF文件的头 |
程序头部表(可选) |
程序头部表 |
节1 |
段1 |
.... .... |
|
节n |
段2 |
.... .... |
|
.... .... |
|
节头部表 |
节头部表(可选) |
64位ELF二进制文件的格式和内容如下:
在linux系统中,ELF文件定义位置: /usr/include/elf.h 。接下来我们来拆解一下文件。
1、ELF头部
ELF64_Ehdr定义如下:
typedef struct {
unsigned char e_ident[16]; /* 幻数以及其他信息*/
uint16_t e_type; /* 对象文件类型*/
uint16_t e_machine; /* 架构*/
uint32_t e_version; /* 对象文件版本*/
uint64_t e_entry; /* 程序入口的虚拟地址*/
uint64_t e_phoff; /* 程序头表的偏移量(按字节计算)*/
uint64_t e_shoff; /* 节头表的偏移量(按字节计算)*/
uint32_t e_flags; /* 保存与文件相关的、特定于处理器的标 志。标志名称采用EF_machine_flag的格式*/ uint16_t e_ehsize; /* ELF头部的大小(按字节计算) */
uint16_t e_phentsize; /* 程序头表的条目大小(按字节计算) */
uint16_t e_phnum; /* 程序头表的条目数,可以为0 */
uint16_t e_shentsize; /* 节头表的条目大小(按字节计算) */
uint16_t e_shnum; /* 节头表的条目数,可以为0 */
uint16_t e_shstrndx; /* 节头表中与节名称字符串表相关的条目的 索引。如果文件没有节名称字符串表,此参数可以为SHN_UNDEF */
} Elf64_Ehdr;
1.1、e_ident数组
幻数由十六进制数字0x7f组成,后跟字母E、L及F的 ASCII字符代码
字节偏移 |
名称 |
含义 |
0 |
EI_MAG0 |
魔数的第一个字节,通常为 0x7F('0x7F') |
1 |
EI_MAG1 |
魔数的第二个字节,通常为 'E'('0x45') |
2 |
EI_MAG2 |
魔数的第三个字节,通常为 'L'('0x4C') |
3 |
EI_MAG3 |
魔数的第四个字节,通常为 'F'('0x46') |
4 |
EI_CLASS |
文件的位数,标识是 32 位还是 64 位,可能的值为: |
- ELFCLASS32 (1):32 位对象 |
||
- ELFCLASS64 (2):64 位对象 |
||
5 |
EI_DATA |
数据编码方式,标识字节序,可能的值为: |
- ELFDATA2LSB (1):小端字节序(Least Significant Byte first) |
||
- ELFDATA2MSB (2):大端字节序(Most Significant Byte first) |
||
6 |
EI_VERSION |
ELF 版本,通常为 1(EV_CURRENT) |
7 |
EI_OSABI |
操作系统和 ABI 标识,可能的值为: |
- ELFOSABI_SYSV (0):UNIX System V ABI |
||
- ELFOSABI_HPUX (1):HP-UX ABI |
||
- ELFOSABI_NETBSD (2):NetBSD ABI |
||
- ELFOSABI_LINUX (3):Linux ABI |
||
- ELFOSABI_SOLARIS (6):Solaris ABI |
||
- ELFOSABI_AIX (7):AIX ABI |
||
- ELFOSABI_IRIX (8):IRIX ABI |
||
- ELFOSABI_FREEBSD (9):FreeBSD ABI |
||
- ELFOSABI_TRU64 (10):TRU64 UNIX ABI |
||
- ELFOSABI_MODESTO (11):Novell Modesto ABI |
||
- ELFOSABI_OPENBSD (12):OpenBSD ABI |
||
- ELFOSABI_ARM_AEABI (64):ARM EABI |
||
- ELFOSABI_ARM (97):ARM ABI |
||
- ELFOSABI_STANDALONE (255):Standalone (embedded) ABI |
||
8 |
EI_ABIVERSION |
ABI 版本号 |
9 |
EI_PAD |
填充字节,通常为 0,用于对齐和将来扩展 |
10 |
EI_PAD |
填充字节,通常为 0,用于对齐和将来扩展 |
11 |
EI_PAD |
填充字节,通常为 0,用于对齐和将来扩展 |
12 |
EI_PAD |
填充字节,通常为 0,用于对齐和将来扩展 |
13 |
EI_PAD |
填充字节,通常为 0,用于对齐和将来扩展 |
14 |
EI_PAD |
填充字节,通常为 0,用于对齐和将来扩展 |
15 |
EI_PAD |
填充字节,通常为 0,用于对齐和将来扩展 |
如下是在系统中使用readelf查看文件的头信息
root@z:~/bin_learn/chater01# readelf -h a.out
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file) # e_type
Machine: Advanced Micro Devices X86-64 # e_machine
Version: 0x1 # e_version
Entry point address: 0x1060 # e_entry字段表示二进制文件的入口点
Start of program headers: 64 (bytes into file) # e_phoff程序头的偏移量,64字节
Start of section headers: 14712 (bytes into file) # e_shoff节头表的偏移量14712字节Flags: 0x0 # e_flags字段保存了二进制文件在特定处理器的标志,对于x86二进制文件,e_flags通常设置为零
Size of this header: 64 (bytes) # e_ehsize以字节单位指定了ELF头部的大小
Size of program headers: 56 (bytes) # e_phentsize; /* 程序头表的条目大小(按字节计算) */
Number of program headers: 13 # e_phnum; /* 程序头表的条目数,可以为0 */
Size of section headers: 64 (bytes) # e_shentsize; /* 节头表的条目大小(按字节计算) */
Number of section headers: 31 # e_shnum; /* 节头表的条目数,可以为0 */
Section header string table index: 30 # e_shstrndx字段包含一个名为.shstrtab的、与特殊字符串表 节(string table section)相关的头索引(在节头表中)。 .shstrtab的节头在索引30 的位置
查看shstrtab节头:
root@z:~/bin_learn/chater01# readelf -x .shstrtab a.out
Hex dump of section '.shstrtab':
0x00000000 002e7379 6d746162 002e7374 72746162 ..symtab..strtab
0x00000010 002e7368 73747274 6162002e 696e7465 ..shstrtab..inte
0x00000020 7270002e 6e6f7465 2e676e75 2e70726f rp..note.gnu.pro
0x00000030 70657274 79002e6e 6f74652e 676e752e perty..note.gnu.
0x00000040 6275696c 642d6964 002e6e6f 74652e41 build-id..note.A
0x00000050 42492d74 6167002e 676e752e 68617368 BI-tag..gnu.hash
0x00000060 002e6479 6e73796d 002e6479 6e737472 ..dynsym..dynstr
0x00000070 002e676e 752e7665 7273696f 6e002e67 ..gnu.version..g
0x00000080 6e752e76 65727369 6f6e5f72 002e7265 nu.version_r..re
0x00000090 6c612e64 796e002e 72656c61 2e706c74 la.dyn..rela.plt
0x000000a0 002e696e 6974002e 706c742e 676f7400 ..init..plt.got.
0x000000b0 2e706c74 2e736563 002e7465 7874002e .plt.sec..text..
0x000000c0 66696e69 002e726f 64617461 002e6568 fini..rodata..eh
0x000000d0 5f667261 6d655f68 6472002e 65685f66 _frame_hdr..eh_f
0x000000e0 72616d65 002e696e 69745f61 72726179 rame..init_array
0x000000f0 002e6669 6e695f61 72726179 002e6479 ..fini_array..dy
0x00000100 6e616d69 63002e64 61746100 2e627373 namic..data..bss
0x00000110 002e636f 6d6d656e 7400 ..comment.
2、节头
节头的第一个字段称为sh_name,如果该字段 被设置,则在字符串表中包含索引,如果索引为零,则表示
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)