C 如何在 Elf 文件中找到`.strtab`?

问题描述

运行 readelf -S 时我得到:

  [27] .strtab           STRTAB           0000000000000000  00001630
       00000000000001d7  0000000000000000           0     0     1
  [28] .shstrtab         STRTAB           0000000000000000  00001807
       0000000000000103  0000000000000000           0     0     1

如何获取.strtab的索引? 起初,我尝试使用 Type 字段检测它,但正如您所见,这不起作用(27 和 28 具有相同的类型)此外,我无法确定它会是第一个出现的 STRTAB 类型。

我的结构和一些解释:

/*
 * Section header.
 */
typedef struct {
    Elf64_Word sh_name;    /* Section name (index into the
                       section header string table). */
    Elf64_Word sh_type;    /* Section type. */
    Elf64_Xword sh_flags;    /* Section flags. */
    Elf64_Addr sh_addr;    /* Address in memory image. */
    Elf64_Off sh_offset;    /* Offset in file. */
    Elf64_Xword sh_size;    /* Size in bytes. */
    Elf64_Word sh_link;    /* Index of a related section. */
    Elf64_Word sh_info;    /* Depends on section type. */
    Elf64_Xword sh_addralign;    /* Alignment in bytes. */
    Elf64_Xword sh_entsize;    /* Size of each entry in section. */
} Elf64_Shdr;

解决方法

如何获取ts-node app.ts 的索引?

您一一阅读了.strtab。当您阅读第 28 个条目时,您将阅读 Elf64_Shdr,并且您将知道它的索引。

通过将其名称与 .strtab 字符串文字进行比较,您将知道它是 .strtab 部分。

(你可能打算问一个不同的问题,但如果是这样,你就没有表达好。)

更新:

我不能做任何事情而不是比较字符串

也许吧。如果您真正的问题是找到 ".strtab" 部分,那就不是。

(这有点困难)我可以假设它是文件中的第一个 STRTAB 吗?

不能保证一定会如此。

注意:如果您担心 .strtab 的速度,请注意您只能在 strcmp() 时执行 strcmp(),并且因为通常在任何给定文件,对 .sh_type == SHT_STRTAB 速度的关注可能是错误的。您的代码如下所示:

strcmp()

更新 2:

您的解决方案有误,请参阅:http://stackoverflow.com/questions/68074508/

您不能声称我的解决方案是错误的,因为我没有提供完整的解决方案。这也没有错。

这是完整的代码(省略了大部分错误检查):

  if (shdr.sh_type == SHT_STRTAB) {
    const char *sh_name = contents_of_shstrab + shdr.sh_name;
    if (strcmp(sh_name,".strtab") == 0) {
      /* found .strtab; do whatever you need with it */
    }
  }
#include <elf.h>
#include <fcntl.h>
#include <link.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>

int main(int argc,char *argv[])
{
  if (argc < 1) return 1;

  int fd = open(argv[1],O_RDONLY);
  if (fd == -1) return 2;

  struct stat st_buf;
  if (fstat(fd,&st_buf) != 0) return 3;

  char *data = mmap(NULL,st_buf.st_size,PROT_READ,MAP_PRIVATE,fd,0);
  if (data == MAP_FAILED) return 4;

  const ElfW(Ehdr) *ehdr = (const ElfW(Ehdr) *)data;
  const ElfW(Shdr) *shdr = (const ElfW(Shdr) *)(data + ehdr->e_shoff);

  const char *shstrtab = data + shdr[ehdr->e_shstrndx].sh_offset;

  for (int j = 0; j < ehdr->e_shnum; j++) {
    printf("[%2d] %s\n",j,shstrtab + shdr[j].sh_name);
  }

  return 0;
}