3

I am trying to retrieve the symbol name of RELA jump slots found in an ELF executable. Using libElf, I have managed to retrieve the address of the RELA but still trying to figure out how to get the symbol(-name).

According to How can I get the symbol name in struct "Elf64_Rela", the symbol is stored in the DYNSYM section which I tried to query but without satisfying results.

Here is what I've got so far (a little dirty though):

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <libelf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <gelf.h>

#define LIB_PATH "/tmp/a.out"

int main(void)
{
    int fd = open(LIB_PATH, O_RDONLY);
    Elf *elf;
    Elf_Scn *scn;
    Elf_Data *rela_data = NULL;
    Elf_Data *sym_data = NULL;
    GElf_Shdr shdr_rela;
    GElf_Shdr shdr_sym;
    GElf_Rela rela;
    GElf_Sym sym;
    int count = 0;

    elf_version(EV_CURRENT);
    elf = elf_begin(fd, ELF_C_READ, NULL);
    if (!elf)
            fprintf(stderr, "ERROR: %s\n", elf_errmsg(elf_errno()));
    for (scn = elf_getscn(elf, 0); scn; scn = elf_nextscn(elf, scn))
    {
        gelf_getshdr(scn, &shdr_sym);
        if (shdr_sym.sh_type == SHT_DYNSYM)
            break;
    }
    sym_data = elf_getdata(scn, sym_data);
    for (scn = elf_getscn(elf, 0); scn; scn = elf_nextscn(elf, scn))
    {
        gelf_getshdr(scn, &shdr_rela);
        if (shdr_rela.sh_type == SHT_RELA)
            break;
    }
    scn = elf_nextscn(elf, scn);
    gelf_getshdr(scn, &shdr_rela);
    rela_data = elf_getdata(scn, rela_data);
    for (unsigned int it = 0; it < (shdr_rela.sh_size / shdr_rela.sh_entsize); ++it)
    {
        gelf_getrela(rela_data, it, &rela);
        gelf_getsym(sym_data, GELF_R_SYM(rela.r_info), &sym);
        printf("[%-8p]: (%d) %s\n", rela.r_offset, GELF_R_SYM(rela.r_info), elf_strptr(elf, shdr_rela.sh_link, sym.st_shndx));
    }
    elf_end(elf);
    close(fd);
    return 0;
}

How can I retrieve the name of the RELA present in my ELF executable ?

Ra'Jiska
  • 979
  • 2
  • 11
  • 23

1 Answers1

0

There are two incorrect arguments in the call to elf_strptr(). To find the symbol names, use:

elf_strptr(elf, shdr_sym.sh_link, sym.st_name)

Explanation: the names are in the dynsym section (shdr_sym), not the rela section, and the index of the name is identified by the field st_name not st_shndx.

This answer is obviously too late to be useful for the OP, but may be of interest to others trying to do the same.

Byron Hawkins
  • 2,536
  • 2
  • 24
  • 34