• ELF header


    1. ELF header定义

    ELF header的定义可以在 /usr/include/elf.h 中找到。Elf32_Ehdr是32位 ELF header的结构体。Elf64_Ehdr是64位ELF header的结构体。
    所以,ELF header在ELF文件中的大小与位置是确定的,位置位于文件头部,大小则是Elf_Ehdr结构体的大小。

    typedef struct
    {
      unsigned char	e_ident[EI_NIDENT];	/* Magic number和其它信息 */
      Elf32_Half	e_type;			/* Object file type */
      Elf32_Half	e_machine;		/* Architecture */
      Elf32_Word	e_version;		/* Object file version */
      Elf32_Addr	e_entry;		/* Entry point virtual address */
      Elf32_Off	e_phoff;		/* Program header table file offset */
      Elf32_Off	e_shoff;		/* Section header table file offset */
      Elf32_Word	e_flags;		/* Processor-specific flags */
      Elf32_Half	e_ehsize;		/* ELF header size in bytes */
      Elf32_Half	e_phentsize;		/* Program header table entry size */
      Elf32_Half	e_phnum;		/* Program header table entry count */
      Elf32_Half	e_shentsize;		/* Section header table entry size */
      Elf32_Half	e_shnum;		/* Section header table entry count */
      Elf32_Half	e_shstrndx;		/* Section header string table index */
    } Elf32_Ehdr;
    
    typedef struct
    {
      unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
      Elf64_Half	e_type;			/* Object file type */
      Elf64_Half	e_machine;		/* Architecture */
      Elf64_Word	e_version;		/* Object file version */
      Elf64_Addr	e_entry;		/* Entry point virtual address */
      Elf64_Off	e_phoff;		/* Program header table file offset */
      Elf64_Off	e_shoff;		/* Section header table file offset */
      Elf64_Word	e_flags;		/* Processor-specific flags */
      Elf64_Half	e_ehsize;		/* ELF header size in bytes */
      Elf64_Half	e_phentsize;		/* Program header table entry size */
      Elf64_Half	e_phnum;		/* Program header table entry count */
      Elf64_Half	e_shentsize;		/* Section header table entry size */
      Elf64_Half	e_shnum;		/* Section header table entry count */
      Elf64_Half	e_shstrndx;		/* Section header string table index */
    } Elf64_Ehdr;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    64位和32位只是个别字段长度不同,比如 Elf64_Addr 和 Elf64_Off 都是64位无符号整数。而Elf32_Addr 和 Elf32_Off是32位无符号整数。这导致ELF header的所占的字节数不同。32位的ELF header占52个字节,64位的ELF header占64个字节。

    2. ELF header详解

    在这里插入图片描述
    (1)e_ident占16个字节。前四个字节被称作ELF的Magic Number。后面的字节描述了ELF文件内容如何解码等信息。等一下详细讲。

    (2)e_type,2字节,描述了ELF文件的类型。以下取值有意义:

    ET_NONE, 0, No file type
     ET_REL, 1, Relocatable file(可重定位文件,通常是文件名以.o结尾,目标文件)
     ET_EXEC, 2, Executable file (可执行文件)
     ET_DYN, 3, Shared object file (动态库文件,你用gcc编译出的二进制往往也属于这种类型,惊讶吗?)
     ET_CORE, 4, Core file (core文件,是core dump生成的吧?)
     ET_NUM, 5,表示已经定义了5种文件类型
     ET_LOPROC, 0xff00, Processor-specific
     ET_HIPROC, 0xffff, Processor-specific
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    从ET_LOPROC到 ET_HIPROC 的值,包含特定于处理器的语义。
    (3)e_machine,2字节。描述了文件面向的架构,可取值如下(因为文档较老,现在有更多取值,参见/usr/include/elf.h中的EM_开头的宏定义):

     EM_NONE, 0, No machine
     EM_M32, 1, AT&T WE 32100
     EM_SPARC, 2, SPARC
     EM_386, 3, Intel 80386
     EM_68K, 4, Motorola 68000
     EM_88K, 5, Motorola 88000
     EM_860, 7, Intel 80860
     EM_MIPS, 8, MIPS RS3000
     ... ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (4)e_version,2字节,描述了ELF文件的版本号,合法取值如下:

     EV_NONE, 0, Invalid version
     EV_CURRENT, 1, Current version,通常都是这个取值。
     EV_NUM, 2, 表示已经定义了2种版本号
    
    • 1
    • 2
    • 3

    (5)e_entry,(32位4字节,64位8字节),执行入口点,如果文件没有入口点,这个域保持0。

    (6)e_phoff, (32位4字节,64位8字节),program header table的offset,如果文件没有PH,这个值是0。

    (7)e_shoff, (32位4字节,64位8字节), section header table 的offset,如果文件没有SH,这个值是0。

    (8)e_flags, 4字节,特定于处理器的标志,32位和64位Intel架构都没有定义标志,因此eflags的值是0。

    (9)e_ehsize, 2字节,ELF header的大小,32位ELF是52字节,64位是64字节。

    (10)e_phentsize,2字节。program header table中每个入口的大小。

    (11)e_phnum, 2字节。如果文件没有program header table, e_phnum的值为0。e_phentsize乘以e_phnum就得到了整个program header table的大小。

    (12)e_shentsize, 2字节,section header table中entry的大小,即每个section header占多少字节。

    (13)e_shnum, 2字节,section header table中header的数目。如果文件没有section header table, e_shnum的值为0。e_shentsize乘以e_shnum,就得到了整个section header table的大小。

    (14)e_shstrndx, 2字节。section header string table index. 包含了section header table中section name string table。如果没有section name string table, e_shstrndx的值是SHN_UNDEF.

    **注意:**program header table一般译为程序头表,section header table 一般译为节头表,因为这样的翻译无助于理解,所以我倾向于不翻。

    3. e_ident

    回过头来,我们仔细看看文件前16个字节,也是e_ident。
    在这里插入图片描述
    如图,前4个字节是ELF的Magic Number,固定为7f 45 4c 46。
    第5个字节指明ELF文件是32位还是64位的。
    第6个字节指明了数据的编码方式,即我们通常说的little endian或是big endian。little endian我喜欢称作小头在前,低位字节在前,或者直接说低位字节在低位地址,比如0x7f454c46,存储顺序就是46 4c 45 7f。big endian就是大头在前,高位字节在前,直接说就是高位字节在低位地址,比如0x7f454c46,在文件中的存储顺序是7f 45 4c 46。
    第7个字节指明了ELF header的版本号,目前值都是1。
    第8-16个字节,都填充为0。

    4. readelf读取ELF header

    使用readelf -h 可以读取文件的ELF header信息。
    在这里插入图片描述

  • 相关阅读:
    循环神经网络——中篇【深度学习】【PyTorch】【d2l】
    基于SSM+Vue的订餐系统设计与实现
    flutter 抓包工具charles
    【C++】类和对象(上)
    LRTimelapse 6 for Mac(延时摄影视频制作软件)
    聊聊公众号最让我不爽的两个痛点
    Python操作Excel教程(图文教程,超详细)Python xlwings模块详解,
    机器学习技术(九)——支持向量机算法实操(基于SVM的模型对潜在运营商客户进行分类)
    Java 项目 服务器 日志配置
    Java 多线程案例
  • 原文地址:https://blog.csdn.net/heyangge/article/details/134545761