0

I'm trying to read the symbols names from an ELF binary using the two functions below, but I don't know if this is the right way to do it.

Elf64_Shdr *get_shdr(void *ptr, char *name) function gives me the address of the section header of the target section with name name.

void elf64(void *ptr) is simply used to print the symbols names, and you can see that I targeted the section .strtab specificly and not .shstrtab.

I understand the difference between .strtab and .shstrtab sections. The first is associated with the section .symtab and it contains the names of the symbols as refered in https://refspecs.linuxbase.org/elf/elf.pdf, and the second is the section that contains the names of all sections in the ELF binary (Please correct me if I was wrong).

Elf64_Shdr  *get_shdr(void *ptr, char *name)
{
    int         idx;
    Elf64_Ehdr  *ehdr;
    Elf64_Shdr  *shdr;
    Elf64_Shdr  *shstrtab;

    if (ptr && name)
    {
        idx = -1;
        ehdr = (Elf64_Ehdr *)ptr;
        shdr = (Elf64_Shdr *)(ptr + ehdr->e_shoff);
        shstrtab = &shdr[ehdr->e_shstrndx];
        while (++idx < ehdr->e_shnum)
        {
            if (!strcmp(ptr + shstrtab->sh_offset + shdr[idx].sh_name, name))
                return (&shdr[idx]);
        }
    }
    return (NULL);
}

void    elf64(void *ptr)
{
    int         i, name;
    Elf64_Shdr  *symtab;
    Elf64_Shdr  *strtab;

    symtab = get_shdr(ptr, ".symtab");
    strtab = get_shdr(ptr, ".strtab");

    i = -1;
    while (++i < symtab->sh_size / sizeof(Elf64_Sym))
    {
        if (name > 0)
            printf("%s\n", (char *)(ptr + strtab->sh_offset + symtab[i].sh_name));
    }
}

If the code in the second function is not the proper way to read the symbols names, how would I do it instead?

Glitch
  • 155
  • 1
  • 9

1 Answers1

-1

ELF is complex enough to justify writting a library just for it. Indeed there's one LGPL library that allows you to access ELF (and many other binary formats), so I recommend you to use it, as it handles all the idiosyncracies of all the binary formats (including COFF, a.out, etc) and you'll operate correctly in a way that's independent on the architecture, word length, endianness, etc.

The BFD library is part of the binutils GNU package. I'd look there before starting to dig into the details of ELF files to implement whatever you need is.

The only need you have is to #include <bfd.h> the proper library files and link with the appropiate -lbfd option, if you have the library installed (which you'll have, if you have installed the binutils-dev package)

Unfortunately I have seen no man pages or textinfo files in the installed packages, so you have to look up here for documentation on it.

Also, if you don't want to deal with the library, there's still an alternative to parsing the file yourself. You can process the output of tne nm(1) command, which shows you that information. You can check for the output format and related things in the online manual page.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31
  • Using `libbfd` for _anything_ is the wrong advice -- it's a horrible library which should ~never be used. – Employed Russian Apr 14 '22 at 03:13
  • that's a point of view.... noticed! But IMHO downvoting an answer because of a taste or preference of use or a personal opinion is bad behaviour... Your comment should be sufficient. Just to say that it is used in `binutils` package that is part of GCC compiler is enough to consider it's use. Of coutse I'm in agreement with you that including a full library for just one thing is not the best approach. But it is a good starting point for someone that has it's first entounter with ELF. – Luis Colorado Apr 14 '22 at 07:02
  • "But it is a good starting point for someone that has it's first entounter with ELF". No, it _definitely_ isn't. There are a lot of libraries which are a _much better_ starting point, `libelf` is one. `libbfd` is the _worst_ starting point you could suggest. – Employed Russian Apr 14 '22 at 15:02
  • Your arguments are too heavy to be even considered. you started saying that libbfd was not appropiate as it was large... now you don't even give a reason. That's good arguing. Thanks for the hint. I'll never recommend this library again. We are learning a lot with your counseil – Luis Colorado Apr 18 '22 at 14:55