2011-02-28 73 views
8

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

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

在“main()”上使用dlsym()是否可以可靠地检测到它?

+0

好奇你为什么要在运行时检测到这一点? – 2011-02-28 18:31:05

+0

我不清楚为什么你需要知道可执行文件是否被删除。但是无论你在运行时如何使用它来处理可执行文件,都应该能够告诉你是否被删除了。 – 2011-02-28 18:27:26

+0

@Martin York在执行应用程序时触发警告消息,以减少无意识地向客户提供未剥离版本的可能性。 – WilliamKF 2011-02-28 19:51:21

回答

7

我知道file命令可以区分不同,所以你可以看看它的来源,看看它使用什么机制。

+5

剥离的[ELF](http://en.wikipedia.org/wiki/Executable_and_Linkable_Format)将缺少'.symtab'条目。 'file'命令遍历所有的ELF节头,直到找到符号表节。如果找不到,则认为该二进制文件被*剥离*。 – jschmier 2011-02-28 17:03:02

2

dlsym着眼于动态符号,这是不通过触摸。静态符号表包含在运行时未加载的部分中,因此不会出现在段表中。

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

1

你可以使用POPEN()到目标应用程序中执行nm然后parse the output如果它剥离或不身影。

nm: /bin/ls: no symbols 
7

从评论留给another answer

一个精简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); 
} 
1

readelf --sections binary_path | grep debug_info

一般说一个二进制文件是否被删除并不是微不足道的,因为有不同的方式来删除一个文件。本质上剥离除去了一些与符号和调试相关的部分。但是,如果将“debug_info”替换为“debug”,则可以看到Ubuntu发行版的标准二进制文件中仍有一些与调试相关的部分。

相关问题