我知道 ELF 文件中的虚拟地址和文件偏移量之间的关系
VirtAddr = Offset + k * Allin
我知道这是由于页面尺寸(x86 架构中的 0x1000)。第一个问题:
- 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......|
- 为什么这两个部分之间有很多零?
我认为它没有链接到页面:如果它的文件偏移量是(例如)0x1f100 而不是 0x1f390,它应该可以正常工作。
在这种情况下,它的虚拟地址应该是 0x21f100,因此尊重同余律
我的解释有什么问题?