【问题标题】:Print the symbol table of an ELF file打印 ELF 文件的符号表
【发布时间】:2014-07-11 15:00:28
【问题描述】:

我有一个使用 mmap 系统调用的程序:

map_start = mmap(0, fd_stat.st_size, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0)

还有一个头变量:

header = (Elf32_Ehdr *) map_start;

如何访问符号表并使用 header 变量打印其全部内容?

【问题讨论】:

    标签: c elf mmap symbol-table


    【解决方案1】:

    查看elf header的e_shoff字段可以得到section table:

    sections = (Elf32_Shdr *)((char *)map_start + header->e_shoff);
    

    您现在可以在节表中搜索类型为SHT_SYMBTAB 的节,即符号表。

    for (i = 0; i < header->e_shnum; i++)
        if (sections[i].sh_type == SHT_SYMTAB) {
            symtab = (Elf32_Sym *)((char *)map_start + sections[i].sh_offset);
            break; }
    

    当然,如果您的文件不是 ELF 文件或以某种方式损坏,您还应该进行大量的完整性检查。

    linux elf(5) manual page 有很多关于格式的信息。

    【讨论】:

    • 好的,谢谢,但是现在,我怎样才能得到符号表中符号的数量?
    • sh_size 告诉你符号表的大小(以字节为单位);除以sh_entsize(应与sizeof(Elf32_Sym)相同)得到条目数。
    【解决方案2】:

    这里是一个例子:https://docs.oracle.com/cd/E19683-01/817-0679/6mgfb878d/index.html

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <libelf.h>
    #include <gelf.h>
    
    void
    main(int argc, char **argv)
    {
        Elf         *elf;
        Elf_Scn     *scn = NULL;
        GElf_Shdr   shdr;
        Elf_Data    *data;
        int         fd, ii, count;
    
        elf_version(EV_CURRENT);
    
        fd = open(argv[1], O_RDONLY);
        elf = elf_begin(fd, ELF_C_READ, NULL);
    
        while ((scn = elf_nextscn(elf, scn)) != NULL) {
            gelf_getshdr(scn, &shdr);
            if (shdr.sh_type == SHT_SYMTAB) {
                /* found a symbol table, go print it. */
                break;
            }
        }
    
        data = elf_getdata(scn, NULL);
        count = shdr.sh_size / shdr.sh_entsize;
    
        /* print the symbol names */
        for (ii = 0; ii < count; ++ii) {
            GElf_Sym sym;
            gelf_getsym(data, ii, &sym);
            printf("%s\n", elf_strptr(elf, shdr.sh_link, sym.st_name));
        }
        elf_end(elf);
        close(fd);
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 2014-11-15
      • 1970-01-01
      • 2015-12-20
      • 2019-09-06
      • 2015-02-22
      • 2012-05-02
      相关资源
      最近更新 更多