理解ELF文件中的节头部

6
static inline Elf32_Shdr *elf_sheader(Elf32_Ehdr *hdr) {
    return (Elf32_Shdr *)((int)hdr + hdr->e_shoff);
}

static inline Elf32_Shdr *elf_section(Elf32_Ehdr *hdr, int idx) {
    return &elf_sheader(hdr)[idx];
}

好的,这里的第一个函数使用 hdr_shoff 返回一个指向 ELF 节头的指针,因为那是第一个节头的偏移量。现在第二个函数通过使用数组索引来访问更多的节头(如果有的话)。

static inline char *elf_str_table(Elf32_Ehdr *hdr) {
    if(hdr->e_shstrndx == SHN_UNDEF) return NULL;
    return (char *)hdr + elf_section(hdr, hdr->e_shstrndx)->sh_offset;
}

static inline char *elf_lookup_string(Elf32_Ehdr *hdr, int offset) {
    char *strtab = elf_str_table(hdr);
    if(strtab == NULL) return NULL;
    return strtab + offset;
}

我对访问节名称的上述两个函数遇到了问题。 e->shstrndx 是字符串表的索引。因此,在 elf_str_table 中,我们首先将其与 SHN_UNDEF 进行比较。但是在 return 语句中,我不明白 hdr->e_shstrndx 是一个字符串表的索引,这个索引如何加到 elf_section 头的起始地址上,从而得到另一个 elf 节头(因为我们正在使用它来访问 sh_offset)。 我困惑的是,e->shstrndx 是字符串表的索引,但是这个索引加上 elf_section 如何返回指向 struct Elf32_Shdr 的指针?

参考:http://wiki.osdev.org/ELF_Tutorial#Accessing_Section_Headers

1个回答

6
你自己说过,elf_section根据索引返回一个节头部。 e_shstrndx是包含节头部字符串表偏移量的节头部索引。
因此,你可以使用e_shstrndx作为elf_section的参数来获取该节头部:
Elf32_Shdr* shstr = elf_section(hdr, hdr->e_shstrndx);

然后从该节头获取偏移量:
int strtab_offset = shstr->sh_offset;

使用它来获取实际的字符串表:
char* strtab = (char*) hdr + strtab_offset;

从这个字符串表中,您可以根据它们的偏移量获取各个部分的名称:
char* str = strtab + offset;

哦,我现在明白了,字符串表也是一个具有自己的节头的节,该节头由偏移量 e_shstrndx 给出,我说得对吗? - abkds
@AbKDs:是的,那就是要点。 - Sander De Dycker
感谢 @Sander De Dycker。这是你的点赞和采纳 :) - abkds
@SanderDeDycker,我有点不理解sh_offset字段。如果e_shstrndx指向具有节名称的字符串表,为什么我们还需要使用sh_offset - Trey
1
@Trey:e_shstrndx是特定“节头”(在“节头表”中)的索引。该节头包含文件内“节名称字符串表”的字节偏移量(sh_offset),以及其他信息。换句话说,节头不包含实际的节 - 它们只包含查找节的位置。 - Sander De Dycker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接