如何获取shstrtab的字符串?

How to get the strings of shstrtab?

我在写Linux'readelf的简化版。

我想打印栏目信息,所以我需要栏目名称。在 Elf64_Shdr 结构中,sh_name 变量仅将我指向 shstrtab 中的索引。但这似乎不是 shstrtab header 中的索引。它是其关联数据的索引。我想知道如何到达那里,因为 ELF header 只将我指向 shstrtab 部分 header,而不是它的相关数据。从文件的 hexdump 中可以看出,文件的结构如下:

ELF HEADER 
phdr1
phdr2
segment1
segment2
shstrtab strings (i want this address, to make use of the sh_name indices)
shdr1
shdr2
shdr3 (this is the shstrtab section)

我是不是想错了? 任何人都可以指导我获取部分名称吗?

我刚刚自己找到了解决方案!

要获取某个部分的关联数据,只需在其 Elf64_Shdr 结构中使用 sh_offset。如果在文件的起始地址加上sh_offset,则直接得到段数据。

下面的代码可以列出 header 部分的名称。

int main()
{
    const char *file_name;
    char *strtable, *sh_name;
    size_t file_size;
    struct stat st;
    void *data;
    Elf64_Ehdr hdr;
    Elf64_Shdr shdr;
    int i, fd, idx, strndx, stroff, spot;

    if ((fd = open(file_name, O_RDONLY)) < 0) {
        printf("fail to open %s\n", file_name);
        exit(EXIT_FAILURE);
    }

    data = MAP_FAILED;
    if (!fstat(fd, &st)) {
        file_size = st.st_size;
        data = mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
    }
    close(fd);

    if (data == MAP_FAILED) {
        printf("Unable map\n");
        exit(EXIT_FAILURE);
    }

    // read elf header
    memcpy(&hdr, data, sizeof(hdr));

    // read section header string table header
    spot = hdr.e_shoff;     // section header table file offset
    strndx = hdr.e_shstrndx;    // section header string table index
    stroff = spot + strndx * hdr.e_shentsize;
    memcpy(&shdr, (char *)data + stroff, hdr.e_shentsize);

    // read section string table
    strtable = (char *)malloc(shdr.sh_size);
    memcpy(strtable, (char *)data + shdr.sh_offset, shdr.sh_size);

    for (i = 0; i< hdr.e_shnum; ++i) {
        memcpy(&shdr, (char *)data + spot, hdr.e_shentsize);
        spot += hdr.e_shentsize;
        sh_name = &(strtable[shdr.sh_name]);
         printf("[%d] %s\n", i, sh_name);
    }
}

结果如下:

[0] 
[1] .interp
[2] .note.ABI-tag
[3] .gnu.hash
[4] .dynsym
[5] .dynstr
[6] .gnu.version
...