2011-02-28 41 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發行版的標準二進制文件中仍有一些與調試相關的部分。

相關問題