Elf Symtab Разбор нулевого указателя - PullRequest
0 голосов
/ 19 мая 2018

Ненавижу просить людей помочь мне отладить мой код, но я застрял на этом.У меня есть простой фрагмент кода для прохождения символов в symtab и последующей печати их на консоли.Очевидно, у меня есть нулевой указатель в вызовах printf и strcmp (что приводит к segfault), но я не могу понять, почему.Вот фрагмент кода:

    #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.

РЕДАКТИРОВАТЬ: Добавлено фрагмент кода, который должен вызватьСигфоСкомпилируйте с флагом "-m32" для gcc.Укажите путь для 32-битного файла Elf в качестве первого параметра запуска.то есть

./symtab_parse test_file

Я уже получил эту работу, как я изначально планировал.Тем не менее, я не уверен в причине segfault, и, как указал EmployedRussian, мой первоначальный ответ не был основной причиной проблемы.Хотел бы по-настоящему докопаться до этой тайны и, надеюсь, чему-то научиться.

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Согласно этому разделу из спецификации ELF:

Секции таблицы строк содержат символьные последовательности с нулевым символом в конце, обычно называемые строками.Объект использует эти строки для представления имен символов и разделов.Один ссылается на строку как индекс в разделе таблицы строк.Первый байт, который является нулевым индексом, определен для хранения нулевого символа.

Это означает, что symtab_str [0] указывает на нулевой символ, который при разыменовании в strcmp приводил к Segfault.Изменение кода для проверки нулевой строки перед выполнением strcmp устранило проблему.

0 голосов
/ 19 мая 2018

Как видите, адрес, сохраненный в eax, указывает на первую строку в .strtab, так почему я получаю нулевой указатель при передаче его в strcmp?

Кодфрагмент, который вы показали, кажется правильным, и если eax равен 0xffd6a030 при вызове strcmp, то по определению это не NULL.

Ваш (не поддерживаетсядоказательством) утверждение, что это NULL - это то, что кажется неправильным (другими словами, вы, вероятно, что-то неправильно понимаете, и вы не показали что-то).

...