【问题标题】:How to print symbol's table, symbol name如何打印符号表、符号名称
【发布时间】:2019-05-31 19:24:48
【问题描述】:

我想在符号表中打印符号的名称。 我正在将 elf 映射到虚拟内存(使用 mmap),我成功访问了符号表,但是当尝试打印符号名称时它失败了(显示一个奇怪的字符串,将其与 elf 文件结果进行比较)。

我的代码:

void printSymboles() {
Elf32_Sym* symtab;
Elf32_Shdr * sh_strtab_p ;
char *sh_strtab;
int symbol_num=-1;
  if(currentFd==-1){
    printf("not legal file set\n");
} else { 

    sectionHeader=(Elf32_Shdr*)(map_start+header->e_shoff);
    int section_num=header->e_shnum;

    int numSectionsFound=0;
    for(int i=0;i<section_num &&numSectionsFound<2;i++){
        if(sectionHeader[i].sh_type==SHT_SYMTAB) {
            symtab=(Elf32_Sym *) (map_start+sectionHeader[i].sh_offset);
            symbol_num= sectionHeader[i].sh_size/sectionHeader[i].sh_entsize; // symobl tbl size/ entrysize 
            numSectionsFound++;
        }
        if(sectionHeader[i].sh_type==SHT_STRTAB) {
            sh_strtab_p=&sectionHeader[i];
            sh_strtab=(char*) map_start+sh_strtab_p->sh_offset;
            numSectionsFound++;

        }
    }

    if(symbol_num==-1) {
        printf("symbol table doesn't exist");
    } else {
        printf("symbol table : \n");
        for(int i=0;i<symbol_num;i++) {
        printf("name : %s\n",sh_strtab+symtab[i].st_name);
        }
    }

【问题讨论】:

    标签: c symbol-table


    【解决方案1】:

    几乎可以肯定,问题在于您正在查找错误的 SHT_STRTAB 部分 - 您扫描标题以查找 SHT_STRTAB 部分,无论最后找到哪个部分,您都记得在 sh_strtab_p 中。如果您的 ELF 文件与大多数 elf 文件一样,那可能是节头字符串表(包含节头名称),而不是带有符号名称的字符串表。

    要查找带有符号名称的字符串表,您需要查看符号表部分标题的sh_link 字段——它告诉您包含的字符串表部分的部分编号(部分标题中的索引)该符号部分中的符号名称。文件中可以有任意多个 SYMTAB 节,每个节都有自己的 STRTAB 节。

    将所有这些放在一起,您想要的更像是:

    Elf32_Shdr *section = (Elf32_Shdr*)(map_start+header->e_shoff);
    char *section_names = (char *)(map_start + section[header->e_shstrndx].sh_offset);
    
    for(int i=0; i<header->e_shnum; i++) {
        if(section[i].sh_type==SHT_SYMTAB) {
            printf("Symobl table %s:\n",  section_names + section[i].sh_name);
            Elf32_Sym *symtab = (Elf32_Sym *)(map_start+section[i].sh_offset);
            int symbol_num = section[i].sh_size/section[i].sh_entsize;
            char *symbol_names = (char *)(map_start + section[section[i].sh_link].sh_offset);
            for (int j=0; j<symbol_num; j++) {
                printf("name : %s\n", symbol_names + symtab[j].st_name);
            }
        }
    }
    

    当然,进行完整性检查以确保没有任何索引超出它们所索引的部分的范围,并且 sh_entsize 和 e_shentsize 与您正在使用的结构的大小相匹配,这也是很好的,以防 ELF 文件损坏。

    【讨论】:

      【解决方案2】:

      正如@chris Dodd 提到的,问题确实是错误的 SHT_STRTAB。 我已经更改了这部分代码:

         if(sectionHeader[i].sh_type==SHT_STRTAB) {
              sh_strtab_p=&sectionHeader[i];
              sh_strtab=(char*) map_start+sh_strtab_p->sh_offset;
              numSectionsFound++;
      
          }
      

      到这里:

          Elf32_Shde * sh_sectionStrTbl_p;
          char * sh_sectionStrTbl;
          sh_sectionStrTbl_p=&sectionHeader[header->e_shoff);
          sh_sectionStrTbl=map_start+sh_sectionStrTbl_p->sh_offset;
      
          if(sectionHeader[i].sh_type==SHT_STRTAB) {
              if(strcmp(sectionHeader[i].sh_name+sh_sectionStrTbl,".strtab")==0) {
              sh_strtab_p=&sectionHeader[i];
              sh_strtab=(char*) map_start+sh_strtab_p->sh_offset;
              numSectionsFound++;
              }
          }
      

      它有效。

      【讨论】:

        猜你喜欢
        • 2013-11-22
        • 1970-01-01
        • 1970-01-01
        • 2012-08-14
        • 1970-01-01
        • 2021-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多