C语言 如何获取shstrtab的字符串?

vbkedwbf  于 2023-06-21  发布在  其他
关注(0)|答案(2)|浏览(88)

我正在编写Linux readelf命令的简化版本。
我想打印节信息,所以我需要节的名称。在Elf64_Shdr结构体中,sh_name变量只指向shstrtab中的索引。但这似乎不是shstrtab头中的索引。它是对其相关数据的索引。
我想知道如何到达那里,因为ELF头只指向shstrtab部分头,而不是它的相关数据。从文件的十六进制转储中可以看到,文件的结构如下:

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)

我想错了吗?有没有人能帮我找到这些章节的名字?

rqcrx0a6

rqcrx0a61#

我自己找到了解决办法!
要获取节的相关数据,只需在Elf64_Shdr结构中使用sh_offset。如果将sh_offset添加到文件的起始地址,则直接获得节数据。

oaxa6hgo

oaxa6hgo2#

下面的代码可以列出节标题名称。

int main()
{
    const char *file_name = "a.out";
    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) == 0) {
        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
...

相关问题