Android中ELF文件结构浅析(三)

 一、  节头表(section header table)

        在目标文件中可以包含很多“节”(section),所有这些“节”都登记在一张称为 “节头表”(section header table)的数组里。通过每一个表项可以定位到对应的节。

        每一个表项结构如下:

struct Elf64_Shdr {
  Elf64_Word sh_name;
  Elf64_Word sh_type;
  Elf64_Xword sh_flags;
  Elf64_Addr sh_addr;
  Elf64_Off sh_offset;
  Elf64_Xword sh_size;
  Elf64_Word sh_link;
  Elf64_Word sh_info;
  Elf64_Xword sh_addralign;
  Elf64_Xword sh_entsize;
};

 1.  sh_name

        本节的名字。整个名字的字符串并不存储在这里,它仅是一个索引号,指向 “字符串表”节中的某个位置,那里存储了一个以’\0’结尾的字符串。

        在第一篇文章中的elf header中的 e_shtrndx 可以知道 节头表里面字符串表的索引。

从s_offset的0x40F5偏移 s_name_off 也就是 0x19 开始到第一个 0 结尾取出内容刚好是 .text;

        

2.  sh_type

        本节的类型。

#define SHT_NULL	  0		/* 节头表条目未使用 */
#define SHT_PROGBITS	  1		/* 程序数据 */
#define SHT_SYMTAB	  2		/* 符号表 */
#define SHT_STRTAB	  3		/* 字符串表 */
#define SHT_RELA	  4		/* 带加数的重定向条目 */
#define SHT_HASH	  5		/* 符号哈希表 */
#define SHT_DYNAMIC	  6		/* 动态链接信息 */
#define SHT_NOTE	  7		/* Notes */
#define SHT_NOBITS	  8		/* 没有数据的程序空间(bss) */
#define SHT_REL		  9		/* 重定位条目,无加数 */
#define SHT_SHLIB	  10		/* Reserved */
#define SHT_DYNSYM	  11		/* 动态链接符号表 */
#define SHT_INIT_ARRAY	  14		/* 构造函数数组 */
#define SHT_FINI_ARRAY	  15		/* 析构函数数组 */
#define SHT_PREINIT_ARRAY 16		/* 预构造函数数组 */
#define SHT_GROUP	  17		/* 节组 */
#define SHT_SYMTAB_SHNDX  18		/* 扩展节索引 */
#define	SHT_NUM		  19		/* 已定义类型的数量  */
#define SHT_LOOS	  0x60000000	/* 启动特定于操作系统  */
#define SHT_GNU_ATTRIBUTES 0x6ffffff5	/* 对象属性  */
#define SHT_GNU_HASH	  0x6ffffff6	/* GNU风格的哈希表  */
#define SHT_GNU_LIBLIST	  0x6ffffff7	/* 预链接库列表 */
#define SHT_CHECKSUM	  0x6ffffff8	/* DSO内容的校验和  */
#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
#define SHT_SUNW_move	  0x6ffffffa
#define SHT_SUNW_COMDAT   0x6ffffffb
#define SHT_SUNW_syminfo  0x6ffffffc
#define SHT_GNU_verdef	  0x6ffffffd	/* 版本定义节  */
#define SHT_GNU_verneed	  0x6ffffffe	/* 版本需要节  */
#define SHT_GNU_versym	  0x6fffffff	/* 版本符号表  */
#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */

 3.  sh_flags

        本节的一些属性,由一系列标志比特位组成,各个比特定义了节的不同属性,当某种属性被设置时,相应的标志位被设为 1,反之则设为 0。未定义的标志 位被全部置 0。

 

名称
SHF_WRITE1可写
SHF_ALLOC2在执行过程中占用内存
SHF_ALLOC_WRITE3占用内存,可写
SHF_EXEC4可执行
SHF_WRITE_EXEC5可写,可执行
SHF_ALLOC_EXEC6占用内存,可执行

4.  sh_addr 

        如果本节的内容需要映射到进程空间中去,此成员指定映射的起始地址;如果不需要映射,此值为 0。 

5.  sh_offset

        相对于文件开头的偏移量。单位是字节。如果该节的类型为 SHT_NOBITS 的话,表明这一节的内容是空的,节并不占用实际的空间,这时 sh_offset 只代表一个逻辑上的位置概念,并不代表实际的内容。

6.  sh_size

        指明节的大小,单位是字节。如果该节的类型为 SHT_NOBITS,此值仍然可能为非零,但没有实际的意义。

7.  sh_link

        节头表索引链接,其解释依赖于节类型。

8.  sh_info

        此成员含有此节的附加信息,根据节的类型不同,本成员的意义也有所不同。

9.  sh_addralign

        一些节具有地址对齐约束。例如,如果某节包含双字,则系统必须确保整个节双字对齐。在此情况下,sh_addr 的值在以 sh_addralign 的值为模数进行取模时,同余数必须等于 0。当前,仅允许使用 0 和 2 的正整数幂。值 0 和 1 表示节没有对齐约束。

10.  sh_entsize

        一些节包含固定大小的项的表,如符号表。对于这样的节,此成员会指定每一项的大小(以字节为单位)。如果节不包含固定大小的项的表,则此成员值为零。

二、  特殊节

.note

        供应商或系统工程师可能需要使用特殊信息标记目标文件,以便其他程序可根据此信息检查一致性或兼容性。为此,可使用 SHT_NOTE 类型的节和 PT_NOTE 类型的程序头元素。

.hash

        符号散列表。散列表由用于符号表访问的 Elf32_Word 或 Elf64_Word 目标文件组成。SHT_HASH 节提供了此散列表。与散列关联的符号表在散列表节头的 sh_link 项中指定。

.dynsym

        动态链接符号表。

.dynstr

        进行动态链接所需的字符串,通常是表示与符号表各项关联的名称的字符串。

.rela 

        .重定位是连接符号引用与符号定义的过程。例如,程序调用函数时,关联的调用指令必须在执行时将控制权转移到正确的目标地址。可重定位文件必须包含说明如何修改其节内容的信息。通过此信息,可执行文件和共享目标文件可包含进程的程序映像的正确信息。重定位项即是这些数据。

.plt

        此节包含函数连接表

.relname 和.relaname

        这两个节含有重定位信息。如果此节被包含在某个可装载的段中,那么本节的属性中应置 SHF_ALLOC 标志位,否则不置此标志。注意,这两个节的名字 中”name”是可替换的部分,执照惯例,对哪一节做重定位就把”name”换成哪一节的名字。比如,.plt 节的重定位节的名字将是.rel.plt 或.rela.plt

 .text

        程序的文本或可执行指令。

.rodata

        通常构成进程映像中的非可写段的只读数据。

.eh_frame_hdr 和 .eh_frame

        用于展开栈的调用帧信息。

.init_array

        函数指针数组,用于构成包含此节的可执行文件或共享目标文件的单个初始化数组。

.fini_array

        函数指针数组,用于构成包含此节的可执行文件或共享目标文件的单个终止数组。

.dynamic

        本节包含动态连接信息,并且可能有 SHF_ALLOC 和 SHF_WRITE 等属性。是否具有 SHF_WRITE 属性取决于操作系统和处理器。

.got

        此节包含全局偏移量表。

.data

        构成程序的内存映像的已初始化数据。

.comment

        注释信息,通常由编译系统的组件提供。

.shstrtab

        本节是“节名字表”,含有所有其它节的名字。

.bss

        本节中包含目标文件中未初始化的全局变量。一般情况下,可执行程序在开始运行的时候,系统会把这一段内容清零。但是,在运行期间的 bss 段是由系统初始化而成的,在目标文件中.bss 节并不包含任何内容,其长度为 0,

  • 38
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值