Elf Symtab解析空指针

时间:2018-05-19 08:34:08

标签: c assembly elf

讨厌让人们帮我调试我的代码,但真的坚持这个。我有一个简单的代码片段,用于浏览symtab中的符号,然后将它们打印到控制台。显然,我在printfstrcmp的调用中有一个空指针(导致段错误),但我似乎无法找出原因。 以下是代码段:

    #include <stdio.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <elf.h>
    #include <fcntl.h>


    #ifdef DEBUG
    #define PRINTDEBUG(x) printf x //variable number of arguments
    #else
    #define PRINTDEBUG(x) do{} while(0)
    #endif

    uint32_t main(int argc, char** argv){
        char* filename = argv[1];
        char* sym_name = argv[2];
        int fd = open(filename, O_RDONLY);
        struct stat st;
        stat(fd, &st);


    char mem[st.st_size];
        read(fd, mem, st.st_size);

        Elf32_Ehdr* ehdr;
        Elf32_Shdr* shdr; //generic entry for enumerating sections
        Elf32_Shdr strtab; //holds string in symtab
        Elf32_Shdr symtab;
        char* sh_strtab; //hold sections names
        Elf32_Sym* sym;


        ehdr = (Elf32_Ehdr *)mem;
        shdr = (Elf32_Shdr* )(mem + ehdr->e_shoff);
        PRINTDEBUG(("number of section headers: %d\n", ehdr->e_shnum)); //need double brackets for variable #of arguments


        sh_strtab = (char *)(mem + (shdr[ehdr->e_shstrndx].sh_offset)); 

        //find address of symtab and strtab 
        for(int i = 0; i < ehdr->e_shnum; i++){
            if(shdr[i].sh_size){

            printf("%s\n", &sh_strtab[shdr[i].sh_name]);

            if(strcmp(&sh_strtab[shdr[i].sh_name], ".strtab") == 0)
                strtab = shdr[i];
            if(strcmp(&sh_strtab[shdr[i].sh_name], ".symtab") == 0)
                symtab = shdr[i];           

            }
        }
    PRINTDEBUG(("symtab offset %x\n", symtab.sh_offset));
    PRINTDEBUG(("strtab offset %x\n", strtab.sh_offset));

    char* symtab_str = (char *)(mem + strtab.sh_offset);
    sym = (Elf32_Sym* )(mem + symtab.sh_offset);

    printf("Symbol names: \n");
    for(int i = 0;  i < (symtab.sh_size / symtab.sh_entsize); i++, sym++){
        printf("%x\n",&symtab_str[sym->st_name]);
        if(strcmp(&symtab_str[sym->st_name], sym_name) ==0) 
            printf("not crahsed\n");

        //TODO: resolve reloc'd syms
    }
}

空指针出现在&symtab_str[sym->st_name]。奇怪的是,我用调试器查看了程序集,它显示&symtab_str[sym->st_name]指向正确的值,即.strtab中的第一个字符串。

编辑:发布应该触发段错误的代码段。使用&#34; -m32&#34;进行编译gcc的标志。提供32位Elf文件的路径名作为第一个运行参数。即。

./symtab_parse test_file

我已按照我原先的意图完成了这项工作。但是,我不确定segfault的原因,正如EmployedRussian所指出的那样,我原来的答案不是问题的根本原因。想真正深入了解这个谜团,并希望从中学到一些东西。

2 个答案:

答案 0 :(得分:0)

  

正如您所看到的,存储在eax中的地址指向.strtab中的第一个字符串,那么为什么在将其传递给strcmp时会得到一个空指针?

您展示的代码段似乎是正确的,如果eax在调用0xffd6a030strcmpNULL,那么按照定义它不是{ {1}}。

你的(证据不支持)声称它是NULL似乎是错误的(换句话说,你可能会错误地解释某些内容,而你没有显示那东西)。

答案 1 :(得分:-2)

根据ELF规范的这一部分:

  

字符串表部分包含以null结尾的字符序列,   通常称为字符串。该对象使用这些字符串来表示   符号和部分名称。一个引用字符串作为索引   字符串表部分。第一个字节是索引零,是   定义为保留空字符。

这意味着symtab_str [0]指向一个空字符,当在strcmp中取消引用时,会导致Segfault。在执行strcmp之前修改代码以检查空字符串修复了问题。