代码之家  ›  专栏  ›  技术社区  ›  alexgolec

如何获取二进制文件的文本部分的偏移量和大小?

  •  3
  • alexgolec  · 技术社区  · 11 年前

    我想知道二进制文件文本部分的确切字节位置,最好用算法检查它。我试过使用 size ,但这似乎只给了我部分的大小,而不是它们的位置,我已经尝试使用 readelf ,但坦率地说,这给了我太多的信息。

    1 回复  |  直到 11 年前
        1
  •  14
  •   nneonneo    11 年前

    来自的输出 readelf -S 看起来是这样的:

    There are 21 section headers, starting at offset 0x1fcdc:
    
    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .hash             HASH            000000b4 0000b4 0008e0 04   A  2   0  4
      [ 2] .dynsym           DYNSYM          00000994 000994 0012f0 10   A  3   3  4
      [ 3] .dynstr           STRTAB          00001c84 001c84 0016a4 00   A  0   0  1
      [ 4] .gnu.version      VERSYM          00003328 003328 00025e 02   A  2   0  2
      [ 5] .gnu.version_d    VERDEF          00003588 003588 000118 00   A  3  10  4
      [ 6] .gnu.version_r    VERNEED         000036a0 0036a0 000110 00   A  3   2  4
      [ 7] .rel.dyn          REL             000037b0 0037b0 001428 08   A  2   0  4
      [ 8] .rel.plt          REL             00004bd8 004bd8 0006e0 08   A  2   9  4
      [ 9] .plt              PROGBITS        000052b8 0052b8 000a64 04  AX  0   0  4
      [10] .text             PROGBITS        00005d1c 005d1c 0141d0 00  AX  0   0  4
      [11] .rodata           PROGBITS        00019eec 019eec 004121 00   A  0   0  4
      [12] .data.rel.ro      PROGBITS        0001f010 01e010 00119c 00  WA  0   0  4
      [13] .dynamic          DYNAMIC         000201ac 01f1ac 000110 08  WA  3   0  4
      [14] .got              PROGBITS        000202bc 01f2bc 00045c 04  WA  0   0  4
      [15] .data             PROGBITS        00020718 01f718 0002d0 00  WA  0   0  4
      [16] .bss              NOBITS          000209e8 01f9e8 0005d8 00  WA  0   0  4
      [17] .comment          PROGBITS        00000000 01f9e8 0001f8 00      0   0  1
      [18] .ARM.attributes   ARM_ATTRIBUTES  00000000 01fbe0 00002b 00      0   0  1
      [19] .gnu_debuglink    PROGBITS        00000000 01fc0b 000014 00      0   0  1
      [20] .shstrtab         STRTAB          00000000 01fc1f 0000ba 00      0   0  1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings)
      I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
      O (extra OS processing required) o (OS specific), p (processor specific)
    

    线 [10] .text 部分这个 Addr 列给出加载部分的虚拟地址 Off 列将文件中的偏移量提供给节 Size 列给出了部分的大小。所有数字都用十六进制表示。

    通过编程,您可以使用中定义的结构来获取有关任何部分的信息 elf.h 以解析该文件。下面是一个示例(为了简单起见,省略了错误检查和清理):

    int fd = open(..., O_RDONLY);
    
    /* map ELF file into memory for easier manipulation */
    struct stat statbuf;
    fstat(fd, &statbuf);
    char *fbase = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
    
    Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fbase;
    Elf32_Shdr *sects = (Elf32_Shdr *)(fbase + ehdr->e_shoff);
    int shsize = ehdr->e_shentsize;
    int shnum = ehdr->e_shnum;
    int shstrndx = ehdr->e_shstrndx;
    
    /* get string table index */
    Elf32_Shdr *shstrsect = &sects[shstrndx];
    char *shstrtab = fbase + shstrsect->sh_offset;
    
    int i;
    for(i=0; i<shnum; i++) {
        if(!strcmp(shstrtab+sects[i].sh_name, ".text")) {
            /* found the text section: inspect sects[i].sh_offset, sects[i].sh_size */
        }
    }