【问题标题】:How to get the strings of shstrtab?如何获取 shstrtab 的字符串?
【发布时间】:2022-04-30 12:31:02
【问题描述】:

我正在编写 Linux 的 readelf 的简化版本。

我想打印部分信息,所以我需要部分的名称。在 Elf64_Shdr 结构中,sh_name 变量仅将我指向 shstrtab 中的索引。但这似乎不是 shstrtab 标头中的索引。它是其相关数据的索引。我想知道如何到达那里,因为 ELF 标头仅将我指向 shstrtab 部分标头,而不指向其相关数据。从文件的hexdump中可以看出,文件的结构如下:

ELF HEADER 
phdr1
phdr2
segment1
segment2
shstrtab strings (i want this address, to make use of the sh_name indices)
shdr1
shdr2
shdr3 (this is the shstrtab section)

我想错了吗? 任何人都可以指导我获取部分名称吗?

【问题讨论】:

    标签: c elf readelf


    【解决方案1】:

    我自己找到了解决方案!

    要获取第一个部分的相关数据,只需在其 Elf64_Shdr 结构中使用 sh_offset。如果将 sh_offset 添加到文件的起始地址,则可以直接获取节数据。

    【讨论】:

      【解决方案2】:

      下面的代码可以列出节标题名称。

      int main()
      {
          const char *file_name;
          char *strtable, *sh_name;
          size_t file_size;
          struct stat st;
          void *data;
          Elf64_Ehdr hdr;
          Elf64_Shdr shdr;
          int i, fd, idx, strndx, stroff, spot;
      
          if ((fd = open(file_name, O_RDONLY)) < 0) {
              printf("fail to open %s\n", file_name);
              exit(EXIT_FAILURE);
          }
      
          data = MAP_FAILED;
          if (!fstat(fd, &st)) {
              file_size = st.st_size;
              data = mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
          }
          close(fd);
      
          if (data == MAP_FAILED) {
              printf("Unable map\n");
              exit(EXIT_FAILURE);
          }
      
          // read elf header
          memcpy(&hdr, data, sizeof(hdr));
      
          // read section header string table header
          spot = hdr.e_shoff;     // section header table file offset
          strndx = hdr.e_shstrndx;    // section header string table index
          stroff = spot + strndx * hdr.e_shentsize;
          memcpy(&shdr, (char *)data + stroff, hdr.e_shentsize);
      
          // read section string table
          strtable = (char *)malloc(shdr.sh_size);
          memcpy(strtable, (char *)data + shdr.sh_offset, shdr.sh_size);
      
          for (i = 0; i< hdr.e_shnum; ++i) {
              memcpy(&shdr, (char *)data + spot, hdr.e_shentsize);
              spot += hdr.e_shentsize;
              sh_name = &(strtable[shdr.sh_name]);
               printf("[%d] %s\n", i, sh_name);
          }
      }
      

      结果如下:

      [0] 
      [1] .interp
      [2] .note.ABI-tag
      [3] .gnu.hash
      [4] .dynsym
      [5] .dynstr
      [6] .gnu.version
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-03-21
        • 1970-01-01
        • 1970-01-01
        • 2014-01-03
        • 2013-03-30
        • 2018-01-02
        • 1970-01-01
        相关资源
        最近更新 更多