How to detect at runtime whether symbols are stripped?

回眸只為那壹抹淺笑 提交于 2019-12-03 12:35:22

I know the file command can tell the difference, so you could possibly look at its source to see what mechanism it uses.

jschmier

From a comment left for another answer:

A stripped ELF will lack a .symtab entry. The file command traverses through all the ELF section headers until a symbol table section is found. If one cannot be found, the binary is considered stripped.


The libelf library allows a program to manipulate ELF object files, archive files, and archive members. The elf(3E) man pages provide documentation related to using the library. The following code provides an example on determining if the executable is stripped by looking for the existence of a symbol table section (.symtab).

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

/* Include for ELF processing */
#include <libelf.h>
#include <gelf.h>

int main(int argc, char ** argv)
{
    int fd;
    const char *file = argv[0];

    Elf *elf;       /* ELF pointer for libelf */
    Elf_Scn *scn;   /* section descriptor pointer */
    GElf_Shdr shdr; /* section header */

    /* Open ELF file to obtain file descriptor */
    if((fd = open(file, O_RDONLY)) < 0)
    {
        fprintf(stderr, "Error opening file %s\n", file);
        exit(EXIT_FAILURE);
    }

    /* Protect program from using an older library */
    if(elf_version(EV_CURRENT) == EV_NONE)
    {
        fprintf(stderr, "WARNING - ELF Library is out of date!\n");
        exit(EXIT_FAILURE);
    }

    /* Initialize elf pointer for examining contents of file */
    elf = elf_begin(fd, ELF_C_READ, NULL);

    /* Initialize section descriptor pointer so that elf_nextscn()
     * returns a pointer to the section descriptor at index 1. */
    scn = NULL;

    /* Iterate through ELF sections */
    while((scn = elf_nextscn(elf, scn)) != NULL)
    {
        /* Retrieve section header */
        gelf_getshdr(scn, &shdr);

        /* If a section header holding a symbol table (.symtab)
         * is found, this ELF file has not been stripped. */
        if(shdr.sh_type == SHT_SYMTAB)
        {
            printf("NOT STRIPPED\n");
            break;
        }
    }

    elf_end(elf);
    close(fd);
    exit(EXIT_SUCCESS);
}

dlsym looks at dynamic symbols, which aren't touched by strip. The static symbol table is contained in sections that are not loaded at runtime and thus do not appear in the segment table.

A pretty good heuristic would be to watch for the existence of a section table in the ELF header, which is usually mapped to your process memory, although the dynamic linker interfaces make it deliberately hard to find out where. On a typical system that has the dl_iterate_phdrs function (which is an extension to the standard), you might be able to walk the PHDRS and check at the vaddr for each whether there is an ELF magic number there, but that is in no way, shape or form portable.

karlphillip

You could use popen() to execute nm on the target application and then parse the output to figure if it's stripped or not.

nm: /bin/ls: no symbols

readelf --sections binary_path | grep debug_info

It is not trivial to say in general whether a binary was stripped or not, because there are different ways to strip a file. Essentially stripping removes some sections related to symbols and debugging. However, if you replace "debug_info" with "debug", you can see that there are still some debug-related sections left in standard binaries of Ubuntu distribution.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!