ELF文件格式第三讲,节头(section header)

目录

ELF文件格式第三讲,节头(section header)

一丶节头

1.1 概念简介

​ 段(segment) 和 节(section)是有区别的。 节不是段。 段是程序执行的必要组成部分。 在每个段中会有代码或者数据被划分为不同的节。 而 节头表 则是对这些节的位置和大小的描述,主要是用于链接和调试。

因为节头表没有对程序的内存布局进行描述,对程序内存布局的描述的是 程序头表(第二讲)的任务。 所以

节头表就是对程序头的补充。所以我们将“节头表”都填充为无用的值的话程序还是可以正常启动的。 虽然可以修改,但是随着版本的升级,保不准以后会使用。 就跟window平台上的最小PE一样,在xp下可以是100kb以下。win7下则对各个表的限制更严格了。所以需要100kb以上。 win10同理。 所以节头表以后可能会使用。

readelf -l 显示一个段对应有那些节。 很直观的可以看到节和段的关系。
readelf -S 
......
Section to Segment mapping:
段节...
00
01     .interp
02     .interp .note.gnu.build-id .note.gnu.property .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt
03     .init .plt .text .fini
04     .rodata .eh_frame_hdr .eh_frame
05     .init_array .fini_array .dynamic .got .got.plt .data .bss
06     .dynamic
07     .note.gnu.build-id .note.gnu.property .note.ABI-tag
08     .note.gnu.property
09     .eh_frame_hdr
10
11     .init_array .fini_array .dynamic .got

1.2 节头和节

​ 如果二进制文件中缺少了 节头 ,并不意味着节是不存在的。只是没有办法通过节头来引用节了,对于调试器或者反编译(IDA)程序来说,参考的信息就变少了。

​ 每一个节都保存了某种类型的代码和数据。 数据可以是程序中的全局变量,也可以是连接器所需要的动态链接的信息。 这点跟windows平台的 windowsPE文件格式设计很像。 节头可以被抹除,默认的ELF文件是有节头的。

如果节头被抹除,那么 objcopy objdump gdb IDA 等工具就可能无法使用。

而节头表中的 .dynsym这样的节(记录了函数名和偏移地址,导入导出等符号)就无法分析。进而就增大了逆向的难度。

1.3 节头 结构

  • 结构
/* Section Header */
typedef struct {
    Elf32_Word    sh_name;    /* name - index into section header
                       string table section */
    Elf32_Word    sh_type;    /* type */
    Elf32_Word    sh_flags;    /* flags */
    Elf32_Addr    sh_addr;    /* address */
    Elf32_Off    sh_offset;    /* file offset */
    Elf32_Word    sh_size;    /* section size */
    Elf32_Word    sh_link;    /* section header table index link */
    Elf32_Word    sh_info;    /* extra information */
    Elf32_Word    sh_addralign;    /* address alignment */
    Elf32_Word    sh_entsize;    /* section entry size */
} Elf32_Shdr;

typedef struct {
    Elf64_Half    sh_name;    /* section name */
    Elf64_Half    sh_type;    /* section type */
    Elf64_Xword    sh_flags;    /* section flags */
    Elf64_Addr    sh_addr;    /* virtual address */
    Elf64_Off    sh_offset;    /* file offset */
    Elf64_Xword    sh_size;    /* section size */
    Elf64_Half    sh_link;    /* link to another */
    Elf64_Half    sh_info;    /* misc info */
    Elf64_Xword    sh_addralign;    /* memory alignment */
    Elf64_Xword    sh_entsize;    /* table entry size */
} Elf64_Shdr;
  • 字段含义如下

ELF文件格式第三讲,节头(section header)

索引为0的表是 (SHN_UNDEF) 尽管这个表的意义是未定义的节区应用。

这个节区固定的值为如下:

ELF文件格式第三讲,节头(section header)

010Edit中的取值为如下:

ELF文件格式第三讲,节头(section header)

  • 字段类型

    类型定义结果如下

    ELF文件格式第三讲,节头(section header)

  • sh_flag字段

    此字段定义了一个节区中包含的内容是否可以修改,是否可以执行的信息。 如果一个标志位被设置,则该位取值为1. 定义的各位都设置为0

    ELF文件格式第三讲,节头(section header)

SHF_EXECINSTR: 节区包含可执行的机器指令。

SHF_MASKPROC: 所有包含于刺眼吗中的四位都用于处理器专用的语义

在32 or 64下字段还增加了

typedef enum <Elf32_Xword> {
    SF32_None               = 0x0,     无
    SF32_Exec               = 0x1,     执行
    SF32_Alloc              = 0x2,     此节区执行过程中占用内存。某些控制接续并不会出现于目标文件的内存映像中,对于那些节区此值为0
    SF32_Alloc_Exec         = 0x3,
    SF32_Write              = 0x4,      写
    SF32_Write_Exec         = 0x5,      写执行
    SF32_Write_Alloc        = 0x6,      写内存
    SF32_Write_Alloc_Exec   = 0x7
} s_flags32_e;

typedef enum <Elf64_Xword> {
    SF64_None               = 0x0,
    SF64_Exec               = 0x1,
    SF64_Alloc              = 0x2,
    SF64_Alloc_Exec         = 0x3,
    SF64_Write              = 0x4,
    SF64_Write_Exec         = 0x5,
    SF64_Write_Alloc        = 0x6,
    SF64_Write_Alloc_Exec   = 0x7
} s_flags64_e;
  • 节区类型于字段

    根据节区类型的不同,那么s_link s_info也是不同的。

    如下表

    ELF文件格式第三讲,节头(section header)

1.4特殊节区

下图是系统中使用的节区以及他们的类型和属性。 简单概括图。

ELF文件格式第三讲,节头(section header)

上一篇:震惊!这个操作系统的应用加载只需要“毫秒级”耗时


下一篇:细说ASP.NET Core与OWIN的关系