9

在我的 C++ 程序中,如何在运行时以编程方式检测符号是否已通过 Linux 上的“strip”gnu 开发工具被剥离?

我想要一个函数定义,如果剥离则返回 true,否则返回 false。

在“main()”上使用 dlsym() 可以可靠地检测到这一点吗?

4

5 回答 5

10

我知道该file命令可以区分,因此您可以查看其源代码以了解其使用的机制。

于 2011-02-28T16:30:14.960 回答
8

从留下的评论中获得另一个答案

剥离的ELF将缺少.symtab条目。该file命令遍历所有 ELF 节标题,直到找到符号表节。如果找不到,则认为二进制文件已被剥离。


libelf库允许程序操作 ELF 目标文件、归档文件和归档成员。elf(3E)手册页提供了与使用该库相关的文档。.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);
}
于 2011-03-01T20:24:09.530 回答
2

dlsym查看strip未触及的动态符号。静态符号表包含在运行时未加载的节中,因此不会出现在段表中。

一个很好的启发式方法是观察 ELF 标头中是否存在节表,该节表通常映射到您的进程内存,尽管动态链接器接口故意使其难以找出位置。在具有该dl_iterate_phdrs功能的典型系统(这是标准的扩展)上,您可能能够遍历 PHDRS 并在 vaddr 处检查每个是否存在 ELF 幻数,但这绝不是形状或形式便携。

于 2011-02-28T17:28:36.967 回答
1

您可以使用popen()在目标应用程序上执行nm,然后解析输出以确定它是否被剥离。

nm: /bin/ls: no symbols
于 2011-02-28T17:38:10.880 回答
1

readelf --sections 二进制路径 | grep 调试信息

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.

于 2013-09-26T11:09:41.960 回答