4

我知道 ELF 文件中的虚拟地址和文件偏移量之间的关系

VirtAddr = Offset + k * Allin

我知道这是由于页面尺寸(x86 架构中的 0x1000)。第一个问题:

  1. x64 架构中的页面尺寸是多少?它是 0x200000 还是可以更低?

继续前进,如果我尝试readelf -lW /bin/ls,我会获得以下信息:

Elf file type is DYN (Shared object file)
Entry point 0x56d0
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R E 0x8
  INTERP         0x000238 0x0000000000000238 0x0000000000000238 0x00001c 0x00001c R   0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x01e4e8 0x01e4e8 R E 0x200000
  LOAD           0x01f390 0x000000000021f390 0x000000000021f390 0x001278 0x002570 RW  0x200000
  DYNAMIC        0x01fdd8 0x000000000021fdd8 0x000000000021fdd8 0x0001f0 0x0001f0 RW  0x8
  NOTE           0x000254 0x0000000000000254 0x0000000000000254 0x000044 0x000044 R   0x4
  GNU_EH_FRAME   0x01afa0 0x000000000001afa0 0x000000000001afa0 0x000884 0x000884 R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x01f390 0x000000000021f390 0x000000000021f390 0x000c70 0x000c70 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag .note.gnu.build-id 
   06     .eh_frame_hdr 
   07     
   08     .init_array .fini_array .data.rel.ro .dynamic .got 

并使用命令readelf -SW /bin/ls

There are 29 section headers, starting at offset 0x20748:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000238 000238 00001c 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            0000000000000254 000254 000020 00   A  0   0  4
  [ 3] .note.gnu.build-id NOTE            0000000000000274 000274 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        0000000000000298 000298 0000b4 00   A  5   0  8
  [ 5] .dynsym           DYNSYM          0000000000000350 000350 000d20 18   A  6   1  8
  [ 6] .dynstr           STRTAB          0000000000001070 001070 0005f6 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          0000000000001666 001666 000118 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         0000000000001780 001780 000070 00   A  6   1  8
  [ 9] .rela.dyn         RELA            00000000000017f0 0017f0 001350 18   A  5   0  8
  [10] .rela.plt         RELA            0000000000002b40 002b40 000a80 18  AI  5  24  8
  [11] .init             PROGBITS        00000000000035c0 0035c0 000017 00  AX  0   0  4
  [12] .plt              PROGBITS        00000000000035e0 0035e0 000710 10  AX  0   0 16
  [13] .plt.got          PROGBITS        0000000000003cf0 003cf0 000018 08  AX  0   0  8
  [14] .text             PROGBITS        0000000000003d10 003d10 012459 00  AX  0   0 16
  [15] .fini             PROGBITS        000000000001616c 01616c 000009 00  AX  0   0  4
  [16] .rodata           PROGBITS        0000000000016180 016180 004e1d 00   A  0   0 32
  [17] .eh_frame_hdr     PROGBITS        000000000001afa0 01afa0 000884 00   A  0   0  4
  [18] .eh_frame         PROGBITS        000000000001b828 01b828 002cc0 00   A  0   0  8
  [19] .init_array       INIT_ARRAY      000000000021f390 01f390 000008 08  WA  0   0  8
  [20] .fini_array       FINI_ARRAY      000000000021f398 01f398 000008 08  WA  0   0  8
  [21] .data.rel.ro      PROGBITS        000000000021f3a0 01f3a0 000a38 00  WA  0   0 32
  [22] .dynamic          DYNAMIC         000000000021fdd8 01fdd8 0001f0 10  WA  6   0  8
  [23] .got              PROGBITS        000000000021ffc8 01ffc8 000038 08  WA  0   0  8
  [24] .got.plt          PROGBITS        0000000000220000 020000 000398 08  WA  0   0  8
  [25] .data             PROGBITS        00000000002203a0 0203a0 000268 00  WA  0   0 32
  [26] .bss              NOBITS          0000000000220620 020608 0012e0 00  WA  0   0 32
  [27] .gnu_debuglink    PROGBITS        0000000000000000 020608 000034 00      0   0  4
  [28] .shstrtab         STRTAB          0000000000000000 02063c 00010a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

该段中的最后一个部分LOAD (R E).eh_frame; 段中的第一部分LOAD (R W).init_array.

在 ELF 文件中,两个部分之间有很多零hexdump -C /bin/ls

0001e4d0  10 00 00 00 7c 2c 00 00  68 7c ff ff 29 00 00 00  |....|,..h|..)...|
0001e4e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0001f390  d0 57 00 00 00 00 00 00  90 57 00 00 00 00 00 00  |.W.......W......|
0001f3a0  b0 63 00 00 00 00 00 00  f0 6a 00 00 00 00 00 00  |.c.......j......|
  1. 为什么这两个部分之间有很多零?

我认为它没有链接到页面:如果它的文件偏移量是(例如)0x1f100 而不是 0x1f390,它应该可以正常工作。

在这种情况下,它的虚拟地址应该是 0x21f100,因此尊重同余律

我的解释有什么问题?

4

0 回答 0